hashをパスと行数から決定
This commit is contained in:
parent
dc9472771b
commit
1e80ee5bd0
|
@ -64,7 +64,6 @@ temp
|
||||||
/packages/frontend/src/**/*.stories.ts
|
/packages/frontend/src/**/*.stories.ts
|
||||||
tsdoc-metadata.json
|
tsdoc-metadata.json
|
||||||
misskey-assets
|
misskey-assets
|
||||||
/packages/frontend/src/scripts/autogen/settings-search-index.ts
|
|
||||||
|
|
||||||
# Vite temporary files
|
# Vite temporary files
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
|
|
|
@ -11,6 +11,7 @@ import JSON5 from 'json5';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import MagicString from 'magic-string';
|
import MagicString from 'magic-string';
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
|
import { hash, toBase62 } from '../vite.config';
|
||||||
|
|
||||||
export interface AnalysisResult {
|
export interface AnalysisResult {
|
||||||
filePath: string;
|
filePath: string;
|
||||||
|
@ -201,20 +202,26 @@ async function processVueFile(
|
||||||
transformedCodeCache: Record<string, string>
|
transformedCodeCache: Record<string, string>
|
||||||
) {
|
) {
|
||||||
const s = new MagicString(code); // magic-string のインスタンスを作成
|
const s = new MagicString(code); // magic-string のインスタンスを作成
|
||||||
const ast = vueSfcParse(code, { filename: id }).descriptor.template?.ast; // テンプレート AST を取得
|
const parsed = vueSfcParse(code, { filename: id });
|
||||||
|
if (!parsed.descriptor.template) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ast = parsed.descriptor.template.ast; // テンプレート AST を取得
|
||||||
const markerRelations: MarkerRelation[] = []; // MarkerRelation 配列を初期化
|
const markerRelations: MarkerRelation[] = []; // MarkerRelation 配列を初期化
|
||||||
|
|
||||||
if (ast) {
|
if (ast) {
|
||||||
function traverse(node: any, currentParent?: any) {
|
function traverse(node: any, currentParent?: any) {
|
||||||
// ノードが MkSearchMarker なら、markerId を生成しノードにセット(すでに存在する場合はその値を使用)
|
|
||||||
let nodeMarkerId: string | undefined;
|
|
||||||
if (node.type === 1 && node.tag === 'MkSearchMarker') {
|
if (node.type === 1 && node.tag === 'MkSearchMarker') {
|
||||||
const markerId = String(randomUUID());
|
// 行番号はコード先頭からの改行数で取得
|
||||||
|
const lineNumber = code.slice(0, node.loc.start.offset).split('\n').length;
|
||||||
|
// ファイルパスと行番号からハッシュ値を生成
|
||||||
|
const generatedMarkerId = toBase62(hash(`${id}:${lineNumber}`));
|
||||||
|
|
||||||
const props = node.props || [];
|
const props = node.props || [];
|
||||||
const hasMarkerIdProp = props.some((prop: any) => prop.type === 6 && prop.name === 'markerId');
|
const hasMarkerIdProp = props.some((prop: any) => prop.type === 6 && prop.name === 'markerId');
|
||||||
nodeMarkerId = hasMarkerIdProp
|
const nodeMarkerId = hasMarkerIdProp
|
||||||
? props.find((prop: any) => prop.type === 6 && prop.name === 'markerId')?.value?.content as string
|
? props.find((prop: any) => prop.type === 6 && prop.name === 'markerId')?.value?.content as string
|
||||||
: markerId;
|
: generatedMarkerId;
|
||||||
node.__markerId = nodeMarkerId;
|
node.__markerId = nodeMarkerId;
|
||||||
|
|
||||||
// 子マーカーの場合、親ノードに __children を設定しておく
|
// 子マーカーの場合、親ノードに __children を設定しておく
|
||||||
|
@ -223,7 +230,6 @@ async function processVueFile(
|
||||||
currentParent.__children.push(nodeMarkerId);
|
currentParent.__children.push(nodeMarkerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// markerRelations の処理はそのまま
|
|
||||||
const parentMarkerId = currentParent && currentParent.__markerId;
|
const parentMarkerId = currentParent && currentParent.__markerId;
|
||||||
markerRelations.push({
|
markerRelations.push({
|
||||||
parentId: parentMarkerId,
|
parentId: parentMarkerId,
|
||||||
|
@ -234,7 +240,7 @@ async function processVueFile(
|
||||||
if (!hasMarkerIdProp) {
|
if (!hasMarkerIdProp) {
|
||||||
const startTagEnd = code.indexOf('>', node.loc.start.offset);
|
const startTagEnd = code.indexOf('>', node.loc.start.offset);
|
||||||
if (startTagEnd !== -1) {
|
if (startTagEnd !== -1) {
|
||||||
s.appendRight(startTagEnd, ` markerId="${markerId}"`);
|
s.appendRight(startTagEnd, ` markerId="${generatedMarkerId}"`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template>
|
<template>
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkSearchMarker
|
<MkSearchMarker
|
||||||
markerId="test"
|
|
||||||
:locationLabel="[i18n.ts.muteAndBlock]"
|
:locationLabel="[i18n.ts.muteAndBlock]"
|
||||||
icon="ti ti-ban"
|
icon="ti ti-ban"
|
||||||
:keywords="['mute', i18n.ts.wordMute]"
|
:keywords="['mute', i18n.ts.wordMute]"
|
||||||
:children="['test2']"
|
|
||||||
>
|
>
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-message-off"></i></template>
|
<template #icon><i class="ti ti-message-off"></i></template>
|
||||||
|
@ -20,7 +18,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkInfo>{{ i18n.ts.wordMuteDescription }}</MkInfo>
|
<MkInfo>{{ i18n.ts.wordMuteDescription }}</MkInfo>
|
||||||
|
|
||||||
<MkSearchMarker
|
<MkSearchMarker
|
||||||
markerId="test2"
|
|
||||||
:locationLabel="[i18n.ts.muteAndBlock, i18n.ts.wordMute]"
|
:locationLabel="[i18n.ts.muteAndBlock, i18n.ts.wordMute]"
|
||||||
icon="ti ti-ban"
|
icon="ti ti-ban"
|
||||||
:keywords="['showMutedWord', i18n.ts.showMutedWord]"
|
:keywords="['showMutedWord', i18n.ts.showMutedWord]"
|
||||||
|
|
|
@ -18,13 +18,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MkSearchMarker markerId="727cc9e8-ad67-474a-9241-b5a9a6475e47">
|
<MkSearchMarker>
|
||||||
<MkInput v-model="profile.name" :max="30" manualSave :mfmAutocomplete="['emoji']">
|
<MkInput v-model="profile.name" :max="30" manualSave :mfmAutocomplete="['emoji']">
|
||||||
<template #label>{{ i18n.ts._profile.name }}</template>
|
<template #label>{{ i18n.ts._profile.name }}</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
</MkSearchMarker>
|
</MkSearchMarker>
|
||||||
|
|
||||||
<MkSearchMarker markerId="1a06c7f9-e85e-46cb-bf5f-b3efa8e71b93">
|
<MkSearchMarker>
|
||||||
<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true">
|
<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true">
|
||||||
<template #label>{{ i18n.ts._profile.description }}</template>
|
<template #label>{{ i18n.ts._profile.description }}</template>
|
||||||
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
|
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file was automatically generated by create-search-index.
|
||||||
|
// Do not edit this file.
|
||||||
|
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
|
export const searchIndexes = [
|
||||||
|
{
|
||||||
|
filePath: 'src/pages/settings/profile.vue',
|
||||||
|
usage: [
|
||||||
|
{
|
||||||
|
staticProps: {
|
||||||
|
markerId: '4mWPWOqkN',
|
||||||
|
},
|
||||||
|
bindProps: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
staticProps: {
|
||||||
|
markerId: 'gw1zundQ3',
|
||||||
|
},
|
||||||
|
bindProps: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filePath: 'src/pages/settings/privacy.vue',
|
||||||
|
usage: [
|
||||||
|
{
|
||||||
|
staticProps: {
|
||||||
|
icon: 'ti ti-lock-open',
|
||||||
|
markerId: 'ssTCH2oBL',
|
||||||
|
},
|
||||||
|
bindProps: {
|
||||||
|
locationLabel: [i18n.ts.privacy, i18n.ts.makeFollowManuallyApprove],
|
||||||
|
keywords: ['follow', 'lock', i18n.ts.lockedAccountInfo],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filePath: 'src/pages/settings/mute-block.vue',
|
||||||
|
usage: [
|
||||||
|
{
|
||||||
|
staticProps: {
|
||||||
|
icon: 'ti ti-ban',
|
||||||
|
markerId: 'CVhDOYgMv',
|
||||||
|
},
|
||||||
|
bindProps: {
|
||||||
|
locationLabel: [i18n.ts.muteAndBlock],
|
||||||
|
keywords: ['mute', i18n.ts.wordMute],
|
||||||
|
children: [
|
||||||
|
'kcHPXo5ZV',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
staticProps: {
|
||||||
|
icon: 'ti ti-ban',
|
||||||
|
markerId: 'kcHPXo5ZV',
|
||||||
|
},
|
||||||
|
bindProps: {
|
||||||
|
locationLabel: [i18n.ts.muteAndBlock, i18n.ts.wordMute],
|
||||||
|
keywords: ['showMutedWord', i18n.ts.showMutedWord],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type AnalysisResults = typeof searchIndexes;
|
||||||
|
export type ComponentUsageInfo = AnalysisResults[number]['usage'][number];
|
|
@ -35,7 +35,7 @@ const externalPackages = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const hash = (str: string, seed = 0): number => {
|
export const hash = (str: string, seed = 0): number => {
|
||||||
let h1 = 0xdeadbeef ^ seed,
|
let h1 = 0xdeadbeef ^ seed,
|
||||||
h2 = 0x41c6ce57 ^ seed;
|
h2 = 0x41c6ce57 ^ seed;
|
||||||
for (let i = 0, ch; i < str.length; i++) {
|
for (let i = 0, ch; i < str.length; i++) {
|
||||||
|
@ -50,9 +50,9 @@ const hash = (str: string, seed = 0): number => {
|
||||||
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const BASE62_DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
export const BASE62_DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
|
||||||
function toBase62(n: number): string {
|
export function toBase62(n: number): string {
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
return '0';
|
return '0';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue