enhance(frontend): improve search index
This commit is contained in:
parent
fa52922331
commit
3a8d015194
|
@ -227,10 +227,11 @@ function extractElementText2Inner(node: TemplateChildNode, processingNodeName: s
|
||||||
// region extractUsageInfoFromTemplateAst
|
// region extractUsageInfoFromTemplateAst
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SearchLabelとSearchKeywordを探して抽出する関数
|
* SearchLabel/SearchKeyword/SearchIconを探して抽出する関数
|
||||||
*/
|
*/
|
||||||
function extractLabelsAndKeywords(nodes: TemplateChildNode[]): { label: string | null, keywords: string[] } {
|
function extractSugarTags(nodes: TemplateChildNode[]): { label: string | null, keywords: string[], icon: string | null } {
|
||||||
let label: string | null | undefined = undefined;
|
let label: string | null | undefined = undefined;
|
||||||
|
let icon: string | null | undefined = undefined;
|
||||||
const keywords: string[] = [];
|
const keywords: string[] = [];
|
||||||
|
|
||||||
logger.info(`Extracting labels and keywords from ${nodes.length} nodes`);
|
logger.info(`Extracting labels and keywords from ${nodes.length} nodes`);
|
||||||
|
@ -253,14 +254,32 @@ function extractLabelsAndKeywords(nodes: TemplateChildNode[]): { label: string |
|
||||||
keywords.push(content);
|
keywords.push(content);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case 'SearchIcon':
|
||||||
|
if (icon !== undefined) {
|
||||||
|
logger.warn(`Duplicate SearchIcon found, ignoring the second one at ${node.loc.start.line}`);
|
||||||
|
break; // 2つ目のSearchIconは無視
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.children.length !== 1) {
|
||||||
|
logger.error(`SearchIcon must have exactly one child at ${node.loc.start.line}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconNode = node.children[0];
|
||||||
|
if (iconNode.type !== NodeTypes.ELEMENT) {
|
||||||
|
logger.error(`SearchIcon must have a child element at ${node.loc.start.line}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
icon = getStringProp(findAttribute(iconNode.props, 'class'));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
// デバッグ情報
|
// デバッグ情報
|
||||||
logger.info(`Extraction completed: label=${label}, keywords=[${keywords.join(', ')}]`);
|
logger.info(`Extraction completed: label=${label}, keywords=[${keywords.join(', ')}, icon=${icon}]`);
|
||||||
return { label: label ?? null, keywords };
|
return { label: label ?? null, keywords, icon: icon ?? null };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringProp(attr: AttributeNode | DirectiveNode | null): string | null {
|
function getStringProp(attr: AttributeNode | DirectiveNode | null): string | null {
|
||||||
|
@ -354,10 +373,12 @@ function extractUsageInfoFromTemplateAst(
|
||||||
|
|
||||||
// SearchLabelとSearchKeywordを抽出 (AST全体を探索)
|
// SearchLabelとSearchKeywordを抽出 (AST全体を探索)
|
||||||
{
|
{
|
||||||
const extracted = extractLabelsAndKeywords(node.children);
|
const extracted = extractSugarTags(node.children);
|
||||||
if (extracted.label && markerInfo.label) logger.warn(`Duplicate label found for ${markerId} at ${id}:${node.loc.start.line}`);
|
if (extracted.label && markerInfo.label) logger.warn(`Duplicate label found for ${markerId} at ${id}:${node.loc.start.line}`);
|
||||||
|
if (extracted.icon && markerInfo.icon) logger.warn(`Duplicate icon found for ${markerId} at ${id}:${node.loc.start.line}`);
|
||||||
markerInfo.label = extracted.label ?? markerInfo.label ?? '';
|
markerInfo.label = extracted.label ?? markerInfo.label ?? '';
|
||||||
markerInfo.keywords = [...extracted.keywords, ...markerInfo.keywords];
|
markerInfo.keywords = [...extracted.keywords, ...markerInfo.keywords];
|
||||||
|
markerInfo.icon = extracted.icon ?? markerInfo.icon ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!markerInfo.label) {
|
if (!markerInfo.label) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<slot></slot>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
</style>
|
|
@ -30,6 +30,7 @@ import PageWithAnimBg from './global/PageWithAnimBg.vue';
|
||||||
import SearchMarker from './global/SearchMarker.vue';
|
import SearchMarker from './global/SearchMarker.vue';
|
||||||
import SearchLabel from './global/SearchLabel.vue';
|
import SearchLabel from './global/SearchLabel.vue';
|
||||||
import SearchKeyword from './global/SearchKeyword.vue';
|
import SearchKeyword from './global/SearchKeyword.vue';
|
||||||
|
import SearchIcon from './global/SearchIcon.vue';
|
||||||
|
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
|
|
||||||
|
@ -67,6 +68,7 @@ export const components = {
|
||||||
SearchMarker: SearchMarker,
|
SearchMarker: SearchMarker,
|
||||||
SearchLabel: SearchLabel,
|
SearchLabel: SearchLabel,
|
||||||
SearchKeyword: SearchKeyword,
|
SearchKeyword: SearchKeyword,
|
||||||
|
SearchIcon: SearchIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
|
@ -98,5 +100,6 @@ declare module '@vue/runtime-core' {
|
||||||
SearchMarker: typeof SearchMarker;
|
SearchMarker: typeof SearchMarker;
|
||||||
SearchLabel: typeof SearchLabel;
|
SearchLabel: typeof SearchLabel;
|
||||||
SearchKeyword: typeof SearchKeyword;
|
SearchKeyword: typeof SearchKeyword;
|
||||||
|
SearchIcon: typeof SearchIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<SearchMarker :keywords="['account', 'info']">
|
<SearchMarker :keywords="['account', 'info']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-info-circle"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-info-circle"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.accountInfo }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.accountInfo }}</SearchLabel></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
|
@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<SearchMarker :keywords="['roles']">
|
<SearchMarker :keywords="['roles']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-badges"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-badges"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.rolesAssignedToMe }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.rolesAssignedToMe }}</SearchLabel></template>
|
||||||
|
|
||||||
<MkRolePreview v-for="role in $i.roles" :key="role.id" :role="role" :forModeration="false"/>
|
<MkRolePreview v-for="role in $i.roles" :key="role.id" :role="role" :forModeration="false"/>
|
||||||
|
@ -58,7 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<SearchMarker :keywords="['account', 'move', 'migration']">
|
<SearchMarker :keywords="['account', 'move', 'migration']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-plane"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-plane"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.accountMigration }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.accountMigration }}</SearchLabel></template>
|
||||||
|
|
||||||
<XMigration/>
|
<XMigration/>
|
||||||
|
@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<SearchMarker :keywords="['account', 'close', 'delete']">
|
<SearchMarker :keywords="['account', 'close', 'delete']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-alert-triangle"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-alert-triangle"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.closeAccount }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.closeAccount }}</SearchLabel></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
|
@ -81,7 +81,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<SearchMarker :keywords="['experimental', 'feature', 'flags']">
|
<SearchMarker :keywords="['experimental', 'feature', 'flags']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-flask"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-flask"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.experimentalFeatures }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.experimentalFeatures }}</SearchLabel></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
|
@ -100,7 +100,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<SearchMarker :keywords="['developer', 'mode', 'debug']">
|
<SearchMarker :keywords="['developer', 'mode', 'debug']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ti ti-code"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-code"></i></SearchIcon></template>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.developer }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.developer }}</SearchLabel></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
|
|
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['general']">
|
<SearchMarker :keywords="['general']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.general }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.general }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-settings"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-settings"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<SearchMarker :keywords="['language']">
|
<SearchMarker :keywords="['language']">
|
||||||
|
@ -111,7 +111,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['timeline', 'note']">
|
<SearchMarker :keywords="['timeline', 'note']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts._settings.timelineAndNote }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts._settings.timelineAndNote }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-notes"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-notes"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
|
@ -279,7 +279,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['post', 'form']">
|
<SearchMarker :keywords="['post', 'form']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.postForm }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.postForm }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-edit"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-edit"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
|
@ -341,7 +341,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['notification']">
|
<SearchMarker :keywords="['notification']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.notifications }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.notifications }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-bell"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-bell"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<SearchMarker :keywords="['group']">
|
<SearchMarker :keywords="['group']">
|
||||||
|
@ -382,7 +382,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['chat', 'messaging']">
|
<SearchMarker :keywords="['chat', 'messaging']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.chat }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.chat }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-messages"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-messages"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<SearchMarker :keywords="['show', 'sender', 'name']">
|
<SearchMarker :keywords="['show', 'sender', 'name']">
|
||||||
|
@ -421,7 +421,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['accessibility']">
|
<SearchMarker :keywords="['accessibility']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.accessibility }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.accessibility }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-accessible"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-accessible"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkFeatureBanner icon="/client-assets/mens_room_3d.png" color="#0011ff">
|
<MkFeatureBanner icon="/client-assets/mens_room_3d.png" color="#0011ff">
|
||||||
|
@ -531,7 +531,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['performance']">
|
<SearchMarker :keywords="['performance']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.performance }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.performance }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-battery-vertical-eco"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-battery-vertical-eco"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<SearchMarker :keywords="['blur']">
|
<SearchMarker :keywords="['blur']">
|
||||||
|
@ -567,7 +567,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['datasaver']">
|
<SearchMarker :keywords="['datasaver']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.dataSaver }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.dataSaver }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-antenna-bars-3"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-antenna-bars-3"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<MkInfo>{{ i18n.ts.reloadRequiredToApplySettings }}</MkInfo>
|
<MkInfo>{{ i18n.ts.reloadRequiredToApplySettings }}</MkInfo>
|
||||||
|
@ -601,7 +601,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<SearchMarker :keywords="['other']">
|
<SearchMarker :keywords="['other']">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label><SearchLabel>{{ i18n.ts.other }}</SearchLabel></template>
|
<template #label><SearchLabel>{{ i18n.ts.other }}</SearchLabel></template>
|
||||||
<template #icon><i class="ti ti-settings-cog"></i></template>
|
<template #icon><SearchIcon><i class="ti ti-settings-cog"></i></SearchIcon></template>
|
||||||
|
|
||||||
<div class="_gaps_m">
|
<div class="_gaps_m">
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
|
|
Loading…
Reference in New Issue