chore: simplify processing SearchLabel and SearchKeyword element
This commit is contained in:
parent
0367545183
commit
bbe852da94
|
@ -9,9 +9,9 @@ import { parse as vueSfcParse } from 'vue/compiler-sfc';
|
||||||
import {
|
import {
|
||||||
createLogger,
|
createLogger,
|
||||||
EnvironmentModuleGraph,
|
EnvironmentModuleGraph,
|
||||||
normalizePath,
|
|
||||||
type LogErrorOptions,
|
type LogErrorOptions,
|
||||||
type LogOptions,
|
type LogOptions,
|
||||||
|
normalizePath,
|
||||||
type Plugin,
|
type Plugin,
|
||||||
type PluginOption
|
type PluginOption
|
||||||
} from 'vite';
|
} from 'vite';
|
||||||
|
@ -22,13 +22,17 @@ import MagicString, { SourceMap } from 'magic-string';
|
||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
import { hash, toBase62 } from '../vite.config';
|
import { hash, toBase62 } from '../vite.config';
|
||||||
import { minimatch } from 'minimatch';
|
import { minimatch } from 'minimatch';
|
||||||
import type {
|
import {
|
||||||
AttributeNode, CompoundExpressionNode, DirectiveNode,
|
type AttributeNode,
|
||||||
ElementNode,
|
type CompoundExpressionNode,
|
||||||
RootNode, SimpleExpressionNode,
|
type DirectiveNode,
|
||||||
TemplateChildNode,
|
type ElementNode,
|
||||||
|
ElementTypes,
|
||||||
|
NodeTypes,
|
||||||
|
type RootNode,
|
||||||
|
type SimpleExpressionNode,
|
||||||
|
type TemplateChildNode,
|
||||||
} from '@vue/compiler-core';
|
} from '@vue/compiler-core';
|
||||||
import { NodeTypes } from '@vue/compiler-core';
|
|
||||||
|
|
||||||
export interface SearchIndexItem {
|
export interface SearchIndexItem {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -60,7 +64,7 @@ interface MarkerRelation {
|
||||||
let logger = {
|
let logger = {
|
||||||
info: (msg: string, options?: LogOptions) => { },
|
info: (msg: string, options?: LogOptions) => { },
|
||||||
warn: (msg: string, options?: LogOptions) => { },
|
warn: (msg: string, options?: LogOptions) => { },
|
||||||
error: (msg: string, options?: LogErrorOptions) => { },
|
error: (msg: string, options?: LogErrorOptions | unknown) => { },
|
||||||
};
|
};
|
||||||
let loggerInitialized = false;
|
let loggerInitialized = false;
|
||||||
|
|
||||||
|
@ -107,157 +111,55 @@ function customStringify(obj: unknown): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 要素ノードからテキスト内容を抽出する
|
* 要素のノードの中身のテキストを抽出する
|
||||||
* 各抽出方法を分離して可読性を向上
|
|
||||||
*/
|
*/
|
||||||
function extractElementText(node: TemplateChildNode): string | null {
|
function extractElementText(node: ElementNode): string | null {
|
||||||
if (!node) return null;
|
return extractElementTextChecked(node, node.tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractElementTextChecked(node: ElementNode, processingNodeName: string): string | null {
|
||||||
|
const result: string[] = [];
|
||||||
|
for (const child of node.children) {
|
||||||
|
const text = extractElementText2Inner(child, processingNodeName);
|
||||||
|
if (text == null) return null;
|
||||||
|
result.push(text);
|
||||||
|
}
|
||||||
|
return result.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractElementText2Inner(node: TemplateChildNode, processingNodeName: string): string | null {
|
||||||
if (node.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
if (node.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
||||||
|
|
||||||
logger.info(`Extracting text from node type=${node.type}, tag=${'tag' in node ? node.tag : 'unknown'}`);
|
switch (node.type) {
|
||||||
|
case NodeTypes.INTERPOLATION: {
|
||||||
// 1. 直接コンテンツの抽出を試行
|
const expr = node.content;
|
||||||
const directContent = extractDirectContent(node);
|
if (expr.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error(`Unexpected COMPOUND_EXPRESSION`);
|
||||||
if (directContent) return directContent;
|
const exprResult = evalExpression(expr.content);
|
||||||
|
if (typeof exprResult !== 'string') {
|
||||||
// 子要素がない場合は終了
|
logger.error(`Result of interpolation node is not string at line ${node.loc.start.line}`);
|
||||||
if (!('children' in node) || !Array.isArray(node.children)) {
|
return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. インターポレーションノードを検索
|
|
||||||
const interpolationContent = extractInterpolationContent(node.children);
|
|
||||||
if (interpolationContent) return interpolationContent;
|
|
||||||
|
|
||||||
// 3. 式ノードを検索
|
|
||||||
const expressionContent = extractExpressionContent(node.children);
|
|
||||||
if (expressionContent) return expressionContent;
|
|
||||||
|
|
||||||
// 5. 再帰的に子ノードを探索
|
|
||||||
return extractNestedContent(node.children);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* ノードから直接コンテンツを抽出
|
|
||||||
*/
|
|
||||||
function extractDirectContent(node: TemplateChildNode): string | null {
|
|
||||||
if (!('content' in node)) return null;
|
|
||||||
if (typeof node.content == 'object' && node.content.type === NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
|
||||||
|
|
||||||
const content = typeof node.content === 'string' ? node.content.trim()
|
|
||||||
: node.content.type !== NodeTypes.INTERPOLATION ? node.content.content.trim()
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (!content) return null;
|
|
||||||
|
|
||||||
logger.info(`Direct node content found: ${content}`);
|
|
||||||
|
|
||||||
// Mustache構文のチェック
|
|
||||||
const mustachePattern = /^\s*{{\s*(.*?)\s*}}\s*$/;
|
|
||||||
const mustacheMatch = content.match(mustachePattern);
|
|
||||||
|
|
||||||
if (mustacheMatch && mustacheMatch[1] && isI18nReference(mustacheMatch[1])) {
|
|
||||||
const extractedContent = mustacheMatch[1].trim();
|
|
||||||
logger.info(`Extracted i18n reference from mustache: ${extractedContent}`);
|
|
||||||
return extractedContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 直接i18n参照を含む場合
|
|
||||||
if (isI18nReference(content)) {
|
|
||||||
logger.info(`Direct i18n reference found: ${content}`);
|
|
||||||
return '$\{' + content + '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
// その他のコンテンツ
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* インターポレーションノード(Mustache)からコンテンツを抽出
|
|
||||||
*/
|
|
||||||
function extractInterpolationContent(children: TemplateChildNode[]): string | null {
|
|
||||||
for (const child of children) {
|
|
||||||
if (child.type === NodeTypes.INTERPOLATION) {
|
|
||||||
logger.info(`Found interpolation node (Mustache): ${JSON.stringify(child.content).substring(0, 100)}...`);
|
|
||||||
|
|
||||||
if (child.content && child.content.type === 4 && child.content.content) {
|
|
||||||
const content = child.content.content.trim();
|
|
||||||
logger.info(`Interpolation content: ${content}`);
|
|
||||||
|
|
||||||
if (isI18nReference(content)) {
|
|
||||||
return '$\{' + content + '}';
|
|
||||||
}
|
|
||||||
} else if (child.content && typeof child.content === 'object') {
|
|
||||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("Unexpected COMPOUND_EXPRESSION");
|
|
||||||
// オブジェクト形式のcontentを探索
|
|
||||||
logger.info(`Complex interpolation node: ${JSON.stringify(child.content).substring(0, 100)}...`);
|
|
||||||
|
|
||||||
if (child.content.content) {
|
|
||||||
const content = child.content.content.trim();
|
|
||||||
|
|
||||||
if (isI18nReference(content)) {
|
|
||||||
logger.info(`Found i18n reference in complex interpolation: ${content}`);
|
|
||||||
return '$\{' + content + '}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return exprResult;
|
||||||
}
|
}
|
||||||
}
|
case NodeTypes.ELEMENT:
|
||||||
|
if (node.tagType === ElementTypes.ELEMENT) {
|
||||||
return null;
|
return extractElementTextChecked(node, processingNodeName);
|
||||||
}
|
} else {
|
||||||
|
logger.error(`Unexpected ${node.tag} extracting text of ${processingNodeName} ${node.loc.start.line}`);
|
||||||
/**
|
return null;
|
||||||
* 式ノードからコンテンツを抽出
|
|
||||||
*/
|
|
||||||
function extractExpressionContent(children: TemplateChildNode[]): string | null {
|
|
||||||
// i18n.ts. 参照パターンを持つものを優先
|
|
||||||
for (const child of children) {
|
|
||||||
if (child.type === NodeTypes.TEXT && child.content) {
|
|
||||||
const expr = child.content.trim();
|
|
||||||
|
|
||||||
if (isI18nReference(expr)) {
|
|
||||||
logger.info(`Found i18n reference in expression node: ${expr}`);
|
|
||||||
return '$\{' + expr + '}';
|
|
||||||
}
|
}
|
||||||
}
|
case NodeTypes.TEXT:
|
||||||
|
return node.content;
|
||||||
|
case NodeTypes.COMMENT:
|
||||||
|
// We skip comments
|
||||||
|
return '';
|
||||||
|
case NodeTypes.IF:
|
||||||
|
case NodeTypes.IF_BRANCH:
|
||||||
|
case NodeTypes.FOR:
|
||||||
|
case NodeTypes.TEXT_CALL:
|
||||||
|
logger.error(`Unexpected controlflow element extracting text of ${processingNodeName} ${node.loc.start.line}`);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// その他の式
|
|
||||||
for (const child of children) {
|
|
||||||
if (child.type === NodeTypes.TEXT && child.content) {
|
|
||||||
const expr = child.content.trim();
|
|
||||||
logger.info(`Found expression: ${expr}`);
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 子ノードを再帰的に探索してコンテンツを抽出
|
|
||||||
*/
|
|
||||||
function extractNestedContent(children: TemplateChildNode[]): string | null {
|
|
||||||
for (const child of children) {
|
|
||||||
if ('children' in child && Array.isArray(child.children) && child.children.length > 0) {
|
|
||||||
const nestedContent = extractElementText(child);
|
|
||||||
|
|
||||||
if (nestedContent) {
|
|
||||||
logger.info(`Found nested content: ${nestedContent}`);
|
|
||||||
return nestedContent;
|
|
||||||
}
|
|
||||||
} else if (child.type === NodeTypes.ELEMENT) {
|
|
||||||
// childrenがなくても内部を調査
|
|
||||||
const nestedContent = extractElementText(child);
|
|
||||||
|
|
||||||
if (nestedContent) {
|
|
||||||
logger.info(`Found content in childless element: ${nestedContent}`);
|
|
||||||
return nestedContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,89 +188,25 @@ function extractLabelsAndKeywords(nodes: TemplateChildNode[]): { label: string |
|
||||||
if (node.tag === 'SearchLabel') {
|
if (node.tag === 'SearchLabel') {
|
||||||
logger.info(`Found SearchLabel node, structure: ${JSON.stringify(node).substring(0, 200)}...`);
|
logger.info(`Found SearchLabel node, structure: ${JSON.stringify(node).substring(0, 200)}...`);
|
||||||
|
|
||||||
// まず完全なノード内容の抽出を試みる
|
|
||||||
const content = extractElementText(node);
|
const content = extractElementText(node);
|
||||||
if (content) {
|
if (content) {
|
||||||
label = content;
|
label = content;
|
||||||
logger.info(`SearchLabel content extracted: ${content}`);
|
logger.info(`SearchLabel content extracted: ${content}`);
|
||||||
} else {
|
|
||||||
logger.info(`SearchLabel found but extraction failed, trying direct children inspection`);
|
|
||||||
|
|
||||||
// バックアップ: 子直接確認 - type=5のMustacheインターポレーションを重点的に確認
|
|
||||||
{
|
|
||||||
for (const child of node.children) {
|
|
||||||
// Mustacheインターポレーション
|
|
||||||
if (child.type === NodeTypes.INTERPOLATION && child.content) {
|
|
||||||
// content内の式を取り出す
|
|
||||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("unexpected COMPOUND_EXPRESSION");
|
|
||||||
const expression = child.content.content ||
|
|
||||||
(child.content.type === 4 ? child.content.content : null) ||
|
|
||||||
JSON.stringify(child.content);
|
|
||||||
|
|
||||||
logger.info(`Interpolation expression: ${expression}`);
|
|
||||||
if (typeof expression === 'string' && isI18nReference(expression)) {
|
|
||||||
label = expression.trim();
|
|
||||||
logger.info(`Found i18n in interpolation: ${label}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 式ノード
|
|
||||||
else if (child.type === NodeTypes.TEXT && child.content && isI18nReference(child.content)) {
|
|
||||||
label = child.content.trim();
|
|
||||||
logger.info(`Found i18n in expression: ${label}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SearchKeywordの処理
|
// SearchKeywordの処理
|
||||||
else if (node.tag === 'SearchKeyword') {
|
else if (node.tag === 'SearchKeyword') {
|
||||||
logger.info(`Found SearchKeyword node`);
|
logger.info(`Found SearchKeyword node`);
|
||||||
|
|
||||||
// まず完全なノード内容の抽出を試みる
|
|
||||||
const content = extractElementText(node);
|
const content = extractElementText(node);
|
||||||
if (content) {
|
if (content) {
|
||||||
keywords.push(content);
|
keywords.push(content);
|
||||||
logger.info(`SearchKeyword content extracted: ${content}`);
|
logger.info(`SearchKeyword content extracted: ${content}`);
|
||||||
} else {
|
|
||||||
logger.info(`SearchKeyword found but extraction failed, trying direct children inspection`);
|
|
||||||
|
|
||||||
// バックアップ: 子直接確認 - type=5のMustacheインターポレーションを重点的に確認
|
|
||||||
{
|
|
||||||
for (const child of node.children) {
|
|
||||||
// Mustacheインターポレーション
|
|
||||||
if (child.type === NodeTypes.INTERPOLATION && child.content) {
|
|
||||||
// content内の式を取り出す
|
|
||||||
if (child.content.type == NodeTypes.COMPOUND_EXPRESSION) throw new Error("unexpected COMPOUND_EXPRESSION");
|
|
||||||
const expression = child.content.content ||
|
|
||||||
(child.content.type === 4 ? child.content.content : null) ||
|
|
||||||
JSON.stringify(child.content);
|
|
||||||
|
|
||||||
logger.info(`Keyword interpolation: ${expression}`);
|
|
||||||
if (typeof expression === 'string' && isI18nReference(expression)) {
|
|
||||||
const keyword = expression.trim();
|
|
||||||
keywords.push(keyword);
|
|
||||||
logger.info(`Found i18n keyword in interpolation: ${keyword}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 式ノード
|
|
||||||
else if (child.type === NodeTypes.TEXT && child.content && isI18nReference(child.content)) {
|
|
||||||
const keyword = child.content.trim();
|
|
||||||
keywords.push(keyword);
|
|
||||||
logger.info(`Found i18n keyword in expression: ${keyword}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 子要素を再帰的に調査(ただしSearchMarkerは除外)
|
// 子要素を再帰的に調査(ただしSearchMarkerは除外)
|
||||||
if (node.children && Array.isArray(node.children)) {
|
findComponents(node.children);
|
||||||
findComponents(node.children);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue