diff --git a/plugins/plugin-search/src/client/composables/index.ts b/plugins/plugin-search/src/client/composables/index.ts index f8f26ed7..fade3ddb 100644 --- a/plugins/plugin-search/src/client/composables/index.ts +++ b/plugins/plugin-search/src/client/composables/index.ts @@ -1,2 +1,9 @@ +/** + * Composables Entry Point + * + * 组合式函数入口 + * + * @module plugin-search/client/composables + */ export * from './locale.js' export * from './searchIndex.js' diff --git a/plugins/plugin-search/src/client/composables/locale.ts b/plugins/plugin-search/src/client/composables/locale.ts index 7e13589b..8c273cd6 100644 --- a/plugins/plugin-search/src/client/composables/locale.ts +++ b/plugins/plugin-search/src/client/composables/locale.ts @@ -1,8 +1,20 @@ +/** + * Locale Composable for Search Plugin + * + * 搜索插件的语言组合式函数 + * + * @module plugin-search/client/composables/locale + */ import type { ComputedRef, MaybeRef } from 'vue' import type { SearchBoxLocales, SearchLocaleOptions } from '../../shared/index.js' import { computed, toRef } from 'vue' import { useRouteLocale } from 'vuepress/client' +/** + * Default locale configuration for search. + * + * 搜索的默认语言配置。 + */ const defaultLocales: SearchBoxLocales = { '/': { placeholder: 'Search', @@ -21,6 +33,17 @@ const defaultLocales: SearchBoxLocales = { }, } +/** + * Get locale configuration for the current route. + * + * 获取当前路由的语言配置。 + * + * @param locales - Locale configuration object / 语言配置对象 + * @returns Computed ref to the current locale settings / 当前语言设置的计算引用 + * @example + * const locale = useLocale(locales) + * console.log(locale.value.placeholder) // 'Search' or localized value + */ export function useLocale(locales: MaybeRef): ComputedRef> { const localesRef = toRef(locales) const routeLocale = useRouteLocale() diff --git a/plugins/plugin-search/src/client/composables/searchIndex.ts b/plugins/plugin-search/src/client/composables/searchIndex.ts index 0155e92e..e2595aea 100644 --- a/plugins/plugin-search/src/client/composables/searchIndex.ts +++ b/plugins/plugin-search/src/client/composables/searchIndex.ts @@ -1,13 +1,44 @@ +/** + * Search Index Composable for Search Plugin + * + * 搜索插件的搜索索引组合式函数 + * + * @module plugin-search/client/composables/searchIndex + */ import type { ShallowRef } from 'vue' import { searchIndex } from '@internal/minisearchIndex' import { shallowRef } from 'vue' declare const __VUE_HMR_RUNTIME__: Record +/** + * Type definition for search index data. + * + * 搜索索引数据的类型定义。 + * + * Maps locale paths to functions that load the corresponding search index. + * + * 将语言路径映射到加载相应搜索索引的函数。 + */ type SearchIndexData = Record Promise<{ default: string }>> +/** + * Reactive reference to the search index data. + * + * 搜索索引数据的响应式引用。 + */ const searchIndexData = shallowRef(searchIndex) +/** + * Get the search index data for all locales. + * + * 获取所有语言的搜索索引数据。 + * + * @returns Shallow ref to the search index data / 搜索索引数据的浅层引用 + * @example + * const indexData = useSearchIndex() + * const localeIndex = await indexData.value['/zh/']() + */ export function useSearchIndex(): ShallowRef { return searchIndexData } diff --git a/plugins/plugin-search/src/client/config.ts b/plugins/plugin-search/src/client/config.ts index 7aa69306..2a279fad 100644 --- a/plugins/plugin-search/src/client/config.ts +++ b/plugins/plugin-search/src/client/config.ts @@ -1,3 +1,15 @@ +/** + * VuePress Client Configuration for Search Plugin + * + * 搜索插件的 VuePress 客户端配置 + * + * Registers the SearchBox component globally and provides locale and option + * configuration to the search component. + * + * 全局注册 SearchBox 组件,并向搜索组件提供语言和选项配置。 + * + * @module plugin-search/client/config + */ import type { ClientConfig } from 'vuepress/client' import type { SearchBoxLocales, SearchOptions } from '../shared/index.js' import { h } from 'vue' diff --git a/plugins/plugin-search/src/client/index.ts b/plugins/plugin-search/src/client/index.ts index e56355ad..2a4f9704 100644 --- a/plugins/plugin-search/src/client/index.ts +++ b/plugins/plugin-search/src/client/index.ts @@ -1,3 +1,15 @@ +/** + * VuePress Search Plugin - Client Side Entry + * + * VuePress 搜索插件 - 客户端入口 + * + * Exports the SearchBox component and search index composable for use in + * VuePress theme components. + * + * 导出 SearchBox 组件和搜索索引组合式函数,供 VuePress 主题组件使用。 + * + * @module plugin-search/client + */ import SearchBox from './components/Search.vue' import { useSearchIndex } from './composables/index.js' diff --git a/plugins/plugin-search/src/client/utils/index.ts b/plugins/plugin-search/src/client/utils/index.ts index 60cb7c08..3832b15b 100644 --- a/plugins/plugin-search/src/client/utils/index.ts +++ b/plugins/plugin-search/src/client/utils/index.ts @@ -1 +1,8 @@ +/** + * Utilities Entry Point + * + * 工具函数入口 + * + * @module plugin-search/client/utils + */ export * from './lru.js' diff --git a/plugins/plugin-search/src/client/utils/lru.ts b/plugins/plugin-search/src/client/utils/lru.ts index 191a6f0c..992d0a7a 100644 --- a/plugins/plugin-search/src/client/utils/lru.ts +++ b/plugins/plugin-search/src/client/utils/lru.ts @@ -1,14 +1,63 @@ -// adapted from https://stackoverflow.com/a/46432113/11613622 +/** + * LRU (Least Recently Used) Cache Implementation + * + * LRU(最近最少使用)缓存实现 + * + * Adapted from https://stackoverflow.com/a/46432113/11613622 + * + * @module plugin-search/client/utils/lru + */ +/** + * Generic LRU Cache implementation using Map. + * + * 使用 Map 实现的通用 LRU 缓存。 + * + * Automatically evicts the least recently used item when the cache reaches + * its maximum size. + * + * 当缓存达到最大容量时,自动淘汰最近最少使用的项。 + * + * @template K - Key type / 键类型 + * @template V - Value type / 值类型 + * @example + * const cache = new LRUCache(3) + * cache.set('a', 1) + * cache.set('b', 2) + * cache.set('c', 3) + * cache.set('d', 4) // 'a' is evicted + * cache.get('b') // returns 2, 'b' becomes most recent + */ export class LRUCache { + /** Maximum number of items in the cache / 缓存中的最大项数 */ private max: number + /** Internal Map storage / 内部 Map 存储 */ private cache: Map + /** + * Create a new LRU Cache instance. + * + * 创建新的 LRU 缓存实例。 + * + * @param max - Maximum cache size (default: 10) / 最大缓存大小(默认:10) + */ constructor(max: number = 10) { this.max = max this.cache = new Map() } + /** + * Get a value from the cache. + * + * 从缓存中获取值。 + * + * Accessing an item moves it to the end (most recently used position). + * + * 访问项会将其移动到末尾(最近使用的位置)。 + * + * @param key - Cache key / 缓存键 + * @returns Cached value or undefined if not found / 缓存值,未找到则返回 undefined + */ get(key: K): V | undefined { const item = this.cache.get(key) if (item !== undefined) { @@ -19,6 +68,19 @@ export class LRUCache { return item } + /** + * Set a value in the cache. + * + * 在缓存中设置值。 + * + * If the key already exists, it is moved to the end. If the cache is full, + * the oldest item is evicted. + * + * 如果键已存在,则将其移动到末尾。如果缓存已满,则淘汰最旧的项。 + * + * @param key - Cache key / 缓存键 + * @param val - Value to cache / 要缓存的值 + */ set(key: K, val: V): void { // refresh key if (this.cache.has(key)) @@ -29,10 +91,22 @@ export class LRUCache { this.cache.set(key, val) } + /** + * Get the first (oldest) key in the cache. + * + * 获取缓存中的第一个(最旧的)键。 + * + * @returns The oldest key or undefined if cache is empty / 最旧的键,缓存为空则返回 undefined + */ first(): K | undefined { return this.cache.keys().next().value } + /** + * Clear all items from the cache. + * + * 清空缓存中的所有项。 + */ clear(): void { this.cache.clear() } diff --git a/plugins/plugin-search/src/node/index.ts b/plugins/plugin-search/src/node/index.ts index c9a3fdc3..5ef3469b 100644 --- a/plugins/plugin-search/src/node/index.ts +++ b/plugins/plugin-search/src/node/index.ts @@ -1,3 +1,14 @@ +/** + * VuePress Search Plugin - Node Side Entry + * + * VuePress 搜索插件 - Node 端入口 + * + * Exports the search plugin and search index preparation utilities. + * + * 导出搜索插件和搜索索引准备工具。 + * + * @module plugin-search/node + */ export * from '../shared/index.js' export { prepareSearchIndex } from './prepareSearchIndex.js' export { searchPlugin } from './searchPlugin.js' diff --git a/plugins/plugin-search/src/node/locales/de.ts b/plugins/plugin-search/src/node/locales/de.ts index 26a5c718..4037834d 100644 --- a/plugins/plugin-search/src/node/locales/de.ts +++ b/plugins/plugin-search/src/node/locales/de.ts @@ -1,6 +1,17 @@ -/** 德语 */ +/** + * German locale configuration for search plugin. + * + * 搜索插件的德语本地化配置。 + * + * @module plugin-search/node/locales/de + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * German search locale strings. + * + * 德语搜索本地化字符串。 + */ export const deSearchLocale: Partial = { placeholder: 'Dokumente durchsuchen', resetButtonTitle: 'Suche zurücksetzen', diff --git a/plugins/plugin-search/src/node/locales/en.ts b/plugins/plugin-search/src/node/locales/en.ts index 5db1c546..0c50da1e 100644 --- a/plugins/plugin-search/src/node/locales/en.ts +++ b/plugins/plugin-search/src/node/locales/en.ts @@ -1,5 +1,17 @@ +/** + * English locale configuration for search plugin. + * + * 搜索插件的英语本地化配置。 + * + * @module plugin-search/node/locales/en + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * English search locale strings. + * + * 英语搜索本地化字符串。 + */ export const enSearchLocale: Partial = { placeholder: 'Search', resetButtonTitle: 'Reset search', diff --git a/plugins/plugin-search/src/node/locales/fr.ts b/plugins/plugin-search/src/node/locales/fr.ts index 2a935743..0475a997 100644 --- a/plugins/plugin-search/src/node/locales/fr.ts +++ b/plugins/plugin-search/src/node/locales/fr.ts @@ -1,6 +1,17 @@ -/** 法语 */ +/** + * French locale configuration for search plugin. + * + * 搜索插件的法语本地化配置。 + * + * @module plugin-search/node/locales/fr + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * French search locale strings. + * + * 法语搜索本地化字符串。 + */ export const frSearchLocale: Partial = { placeholder: 'Rechercher dans la documentation', resetButtonTitle: 'Réinitialiser la recherche', diff --git a/plugins/plugin-search/src/node/locales/index.ts b/plugins/plugin-search/src/node/locales/index.ts index e7f2353d..d030937b 100644 --- a/plugins/plugin-search/src/node/locales/index.ts +++ b/plugins/plugin-search/src/node/locales/index.ts @@ -1,7 +1,14 @@ /** - * 多语言预设 - * 除 /zh/ 、 /en/ 外,其它语言预设通过 AI 生成,不保证准确 - * 如有错误,欢迎提 issue + * Multi-language presets for search plugin. + * + * 搜索插件的多语言预设。 + * + * Language presets other than /zh/ and /en/ are generated by AI and may not be accurate. + * If you find any errors, please submit an issue. + * + * 除 /zh/ 和 /en/ 外,其他语言预设通过 AI 生成,不保证准确。如有错误,欢迎提 issue。 + * + * @module plugin-search/node/locales */ import type { DefaultLocaleInfo } from '@vuepress/helper' import type { SearchLocaleOptions } from '../../shared/index.js' @@ -13,6 +20,15 @@ import { ruSearchLocale } from './ru.js' import { zhTwSearchLocale } from './zh-tw.js' import { zhSearchLocale } from './zh.js' +/** + * Default locale configurations for search plugin. + * + * 搜索插件的默认语言配置。 + * + * Maps language codes to their respective locale strings. + * + * 将语言代码映射到相应的本地化字符串。 + */ export const SEARCH_LOCALES: DefaultLocaleInfo> = [ [['en', 'en-US'], enSearchLocale], [['zh', 'zh-CN', 'zh-Hans', 'zh-Hant'], zhSearchLocale], diff --git a/plugins/plugin-search/src/node/locales/ja.ts b/plugins/plugin-search/src/node/locales/ja.ts index 946c0f2a..de96529b 100644 --- a/plugins/plugin-search/src/node/locales/ja.ts +++ b/plugins/plugin-search/src/node/locales/ja.ts @@ -1,6 +1,17 @@ -/** 日语 */ +/** + * Japanese locale configuration for search plugin. + * + * 搜索插件的日语本地化配置。 + * + * @module plugin-search/node/locales/ja + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * Japanese search locale strings. + * + * 日语搜索本地化字符串。 + */ export const jaSearchLocale: Partial = { placeholder: 'ドキュメントを検索', resetButtonTitle: '検索をリセット', diff --git a/plugins/plugin-search/src/node/locales/ru.ts b/plugins/plugin-search/src/node/locales/ru.ts index 5c06700c..5cf1ce29 100644 --- a/plugins/plugin-search/src/node/locales/ru.ts +++ b/plugins/plugin-search/src/node/locales/ru.ts @@ -1,6 +1,17 @@ -/** 俄语 */ +/** + * Russian locale configuration for search plugin. + * + * 搜索插件的俄语本地化配置。 + * + * @module plugin-search/node/locales/ru + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * Russian search locale strings. + * + * 俄语搜索本地化字符串。 + */ export const ruSearchLocale: Partial = { placeholder: 'Поиск по документации', resetButtonTitle: 'Сбросить поиск', diff --git a/plugins/plugin-search/src/node/locales/zh-tw.ts b/plugins/plugin-search/src/node/locales/zh-tw.ts index 4973f911..448f6a5e 100644 --- a/plugins/plugin-search/src/node/locales/zh-tw.ts +++ b/plugins/plugin-search/src/node/locales/zh-tw.ts @@ -1,6 +1,17 @@ -/** 繁体中文 */ +/** + * Traditional Chinese (Taiwan) locale configuration for search plugin. + * + * 搜索插件的繁体中文(台湾)本地化配置。 + * + * @module plugin-search/node/locales/zh-tw + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * Traditional Chinese (Taiwan) search locale strings. + * + * 繁体中文(台湾)搜索本地化字符串。 + */ export const zhTwSearchLocale: Partial = { placeholder: '搜尋文件', resetButtonTitle: '重設搜尋', diff --git a/plugins/plugin-search/src/node/locales/zh.ts b/plugins/plugin-search/src/node/locales/zh.ts index 4e3fb81c..a6a0f9e1 100644 --- a/plugins/plugin-search/src/node/locales/zh.ts +++ b/plugins/plugin-search/src/node/locales/zh.ts @@ -1,5 +1,17 @@ +/** + * Simplified Chinese locale configuration for search plugin. + * + * 搜索插件的简体中文本地化配置。 + * + * @module plugin-search/node/locales/zh + */ import type { SearchLocaleOptions } from '../../shared/index.js' +/** + * Simplified Chinese search locale strings. + * + * 简体中文搜索本地化字符串。 + */ export const zhSearchLocale: Partial = { placeholder: '搜索文档', resetButtonTitle: '重置搜索', diff --git a/plugins/plugin-search/src/node/prepareSearchIndex.ts b/plugins/plugin-search/src/node/prepareSearchIndex.ts index 0760cbe1..a3ef91ac 100644 --- a/plugins/plugin-search/src/node/prepareSearchIndex.ts +++ b/plugins/plugin-search/src/node/prepareSearchIndex.ts @@ -1,26 +1,71 @@ +/** + * Search Index Preparation Module + * + * 搜索索引准备模块 + * + * This module handles the creation, update, and management of MiniSearch indexes + * for VuePress pages, supporting multiple locales and hot module replacement. + * + * 本模块处理 VuePress 页面的 MiniSearch 索引的创建、更新和管理, + * 支持多语言和热模块替换。 + * + * @module plugin-search/node/prepareSearchIndex + */ import type { App, Page } from 'vuepress/core' import type { SearchOptions, SearchPluginOptions } from '../shared/index.js' import MiniSearch from 'minisearch' import pMap from 'p-map' import { colors, logger } from 'vuepress/utils' +/** + * Options for search index preparation. + * + * 搜索索引准备的配置选项。 + */ export interface SearchIndexOptions { + /** VuePress application instance / VuePress 应用实例 */ app: App + /** MiniSearch configuration options / MiniSearch 配置选项 */ searchOptions: SearchOptions + /** Function to filter searchable pages / 过滤可搜索页面的函数 */ isSearchable: SearchPluginOptions['isSearchable'] } +/** + * Internal index object structure for MiniSearch. + * + * MiniSearch 的内部索引对象结构。 + */ interface IndexObject { + /** Unique identifier for the indexed item / 索引项的唯一标识符 */ id: string + /** Text content for searching / 用于搜索的文本内容 */ text: string + /** Title of the section / 章节标题 */ title: string + /** Parent titles hierarchy / 父级标题层级 */ titles: string[] } +/** Directory path for storing search index files / 存储搜索索引文件的目录路径 */ const SEARCH_INDEX_DIR = 'internal/minisearchIndex/' + +/** Map of locale paths to their MiniSearch instances / 语言路径到 MiniSearch 实例的映射 */ const indexByLocales = new Map>() + +/** Cache for index objects by file path / 按文件路径缓存索引对象 */ const indexCache = new Map() +/** + * Get or create a MiniSearch index for a specific locale. + * + * 获取或创建特定语言的 MiniSearch 索引。 + * + * @param locale - Locale path (e.g., '/', '/zh/') / 语言路径 + * @param lang - Language code for tokenization / 用于分词的语言代码 + * @param options - Search index options / 搜索索引选项 + * @returns MiniSearch instance for the locale / 该语言的 MiniSearch 实例 + */ function getIndexByLocale(locale: string, lang: string, options: SearchIndexOptions['searchOptions']) { let index = indexByLocales.get(locale) if (!index) { @@ -38,6 +83,14 @@ function getIndexByLocale(locale: string, lang: string, options: SearchIndexOpti return index } +/** + * Get or create an index cache for a specific file path. + * + * 获取或创建特定文件路径的索引缓存。 + * + * @param filepath - File path to get cache for / 要获取缓存的文件路径 + * @returns Array of index objects for the file / 该文件的索引对象数组 + */ function getIndexCache(filepath: string) { let index = indexCache.get(filepath) if (!index) { @@ -47,10 +100,39 @@ function getIndexCache(filepath: string) { return index } +/** + * Write a placeholder search index file for development mode. + * + * 为开发模式写入占位符搜索索引文件。 + * + * This is used to provide an empty index before the actual index is prepared, + * preventing errors when the search component loads before indexing completes. + * + * 用于在实际索引准备完成之前提供空索引, + * 防止搜索组件在索引完成之前加载时出错。 + * + * @param app - VuePress application instance / VuePress 应用实例 + */ export async function prepareSearchIndexPlaceholder(app: App) { await app.writeTemp(`${SEARCH_INDEX_DIR}index.js`, 'export const searchIndex = {}') } +/** + * Prepare search indexes for all pages in the VuePress application. + * + * 为 VuePress 应用中的所有页面准备搜索索引。 + * + * This function indexes all pages concurrently, creating separate MiniSearch + * instances for each locale, and writes the indexes to temporary files. + * + * 此函数并发索引所有页面,为每个语言创建独立的 MiniSearch 实例, + * 并将索引写入临时文件。 + * + * @param options - Search index preparation options / 搜索索引准备选项 + * @param options.app - VuePress application instance / VuePress 应用实例 + * @param options.isSearchable - Function to filter searchable pages / 过滤可搜索页面的函数 + * @param options.searchOptions - MiniSearch configuration / MiniSearch 配置 + */ export async function prepareSearchIndex({ app, isSearchable, @@ -78,6 +160,17 @@ export async function prepareSearchIndex({ } } +/** + * Handle search index update when a page is modified. + * + * 当页面被修改时处理搜索索引更新。 + * + * @param filepath - Path of the modified file relative to project root / 相对于项目根目录的修改文件路径 + * @param options - Search index preparation options / 搜索索引准备选项 + * @param options.app - VuePress application instance / VuePress 应用实例 + * @param options.isSearchable - Function to filter searchable pages / 过滤可搜索页面的函数 + * @param options.searchOptions - MiniSearch configuration / MiniSearch 配置 + */ export async function onSearchIndexUpdated( filepath: string, { @@ -97,6 +190,17 @@ export async function onSearchIndexUpdated( } } +/** + * Handle search index update when a page is removed. + * + * 当页面被删除时处理搜索索引更新。 + * + * @param filepath - Path of the removed file relative to project root / 相对于项目根目录的删除文件路径 + * @param options - Search index preparation options / 搜索索引准备选项 + * @param options.app - VuePress application instance / VuePress 应用实例 + * @param options.isSearchable - Function to filter searchable pages / 过滤可搜索页面的函数 + * @param options.searchOptions - MiniSearch configuration / MiniSearch 配置 + */ export async function onSearchIndexRemoved( filepath: string, { @@ -119,6 +223,19 @@ export async function onSearchIndexRemoved( } } +/** + * Write all search indexes to temporary files. + * + * 将所有搜索索引写入临时文件。 + * + * Creates separate JavaScript files for each locale's search index, + * enabling lazy loading of indexes in the client. + * + * 为每个语言的搜索索引创建独立的 JavaScript 文件, + * 支持客户端延迟加载索引。 + * + * @param app - VuePress application instance / VuePress 应用实例 + */ async function writeTemp(app: App) { const records: string[] = [] const promises: Promise[] = [] @@ -145,6 +262,21 @@ async function writeTemp(app: App) { await Promise.all(promises) } +/** + * Index a single page for search. + * + * 为单个页面建立搜索索引。 + * + * Extracts content from the page, splits it into sections based on headings, + * and adds each section to the appropriate locale's MiniSearch index. + * + * 从页面提取内容,根据标题将其分割为章节, + * 并将每个章节添加到相应语言的 MiniSearch 索引中。 + * + * @param page - VuePress page object / VuePress 页面对象 + * @param options - MiniSearch options / MiniSearch 选项 + * @param isSearchable - Function to check if page should be indexed / 检查页面是否应被索引的函数 + */ async function indexFile(page: Page, options: SearchIndexOptions['searchOptions'], isSearchable: SearchPluginOptions['isSearchable']) { if (!page.filePath || page.frontmatter?.search === false) return @@ -194,13 +326,27 @@ ${page.contentRendered}` } } +/** Regex pattern for matching heading tags / 匹配标题标签的正则表达式 */ // eslint-disable-next-line regexp/no-super-linear-backtracking const headingRegex = /([\s\S]*?<\/a>)<\/h\1>/gi +/** Regex pattern for extracting heading content / 提取标题内容的正则表达式 */ // eslint-disable-next-line regexp/no-super-linear-backtracking const headingContentRegex = /([\s\S]*?)<\/span><\/a>/i +/** Regex pattern for ignoring template content / 忽略模板内容的正则表达式 */ const ignoreHeadingRegex = /]*>[\s\S]*<\/template>/gi + /** - * Splits HTML into sections based on headings + * Split HTML content into sections based on heading elements. + * + * 根据标题元素将 HTML 内容分割为章节。 + * + * This generator function parses HTML content and yields section objects + * containing anchor, titles hierarchy, and searchable text. + * + * 此生成器函数解析 HTML 内容并生成包含锚点、标题层级和可搜索文本的章节对象。 + * + * @param html - HTML content to split / 要分割的 HTML 内容 + * @yields Section objects with anchor, titles, and text / 包含锚点、标题和文本的章节对象 */ function* splitPageIntoSections(html: string) { const result = html.split(headingRegex) @@ -228,17 +374,41 @@ function* splitPageIntoSections(html: string) { } } +/** + * Extract searchable text from HTML content by removing tags. + * + * 通过移除标签从 HTML 内容中提取可搜索文本。 + * + * @param content - HTML content / HTML 内容 + * @returns Plain text content / 纯文本内容 + */ function getSearchableText(content: string) { content = clearHtmlTags(content) return content } +/** + * Remove all HTML tags from a string. + * + * 移除字符串中的所有 HTML 标签。 + * + * @param str - String containing HTML / 包含 HTML 的字符串 + * @returns String with HTML tags removed / 移除 HTML 标签后的字符串 + */ function clearHtmlTags(str: string) { str = str.replace(ignoreHeadingRegex, '') // 移除其他所有HTML标签 return str.replace(/<[^>]*>/g, '') } +/** + * Generate HMR (Hot Module Replacement) code for the search index. + * + * 为搜索索引生成 HMR(热模块替换)代码。 + * + * @param m - Module name / 模块名称 + * @returns HMR code string / HMR 代码字符串 + */ function genHmrCode(m: string) { const func = `update${m[0].toUpperCase()}${m.slice(1)}` return ` diff --git a/plugins/plugin-search/src/node/searchPlugin.ts b/plugins/plugin-search/src/node/searchPlugin.ts index d37b258f..24684796 100644 --- a/plugins/plugin-search/src/node/searchPlugin.ts +++ b/plugins/plugin-search/src/node/searchPlugin.ts @@ -8,6 +8,36 @@ import { onSearchIndexRemoved, onSearchIndexUpdated, prepareSearchIndex, prepare const __dirname = getDirname(import.meta.url) +/** + * Create a VuePress search plugin instance. + * + * 创建 VuePress 搜索插件实例。 + * + * @param options - Plugin configuration options / 插件配置选项 + * @param options.locales - Locale-specific search configurations / 特定语言的搜索配置 + * @param options.isSearchable - Function to determine if a page should be indexed / 判断页面是否应被索引的函数 + * @param options.searchOptions - MiniSearch options / MiniSearch 配置选项 + * @returns VuePress plugin object / VuePress 插件对象 + * @example + * // Basic usage + * export default { + * plugins: [ + * searchPlugin() + * ] + * } + * + * // With custom options + * export default { + * plugins: [ + * searchPlugin({ + * locales: { + * '/zh/': { placeholder: '搜索文档' } + * }, + * isSearchable: (page) => page.path !== '/secret/' + * }) + * ] + * } + */ export function searchPlugin({ locales = {}, isSearchable, diff --git a/plugins/plugin-search/src/shared/index.ts b/plugins/plugin-search/src/shared/index.ts index a772af98..21faccca 100644 --- a/plugins/plugin-search/src/shared/index.ts +++ b/plugins/plugin-search/src/shared/index.ts @@ -1,40 +1,107 @@ +/** + * Shared Types for VuePress Search Plugin + * + * VuePress 搜索插件的共享类型 + * + * This module contains type definitions shared between the node and client + * sides of the search plugin. + * + * 本模块包含搜索插件在 Node 端和客户端之间共享的类型定义。 + * + * @module plugin-search/shared + */ import type { Options as MiniSearchOptions } from 'minisearch' import type { LocaleConfig, Page } from 'vuepress/core' +/** + * Locale options for search UI strings. + * + * 搜索 UI 字符串的语言选项。 + */ export interface SearchLocaleOptions { + /** Placeholder text for search input / 搜索输入框的占位文本 */ placeholder: string + /** Text for search button / 搜索按钮的文本 */ buttonText: string + /** Title for reset button / 重置按钮的标题 */ resetButtonTitle: string + /** Title for back/close button / 返回/关闭按钮的标题 */ backButtonTitle: string + /** Text shown when no results found / 无搜索结果时显示的文本 */ noResultsText: string + /** Footer keyboard shortcut hints / 底部键盘快捷键提示 */ footer: { + /** Text for select action / 选择操作的文本 */ selectText: string + /** ARIA label for select key / 选择键的 ARIA 标签 */ selectKeyAriaLabel: string + /** Text for navigate action / 导航操作的文本 */ navigateText: string + /** ARIA label for navigate up key / 向上导航键的 ARIA 标签 */ navigateUpKeyAriaLabel: string + /** ARIA label for navigate down key / 向下导航键的 ARIA 标签 */ navigateDownKeyAriaLabel: string + /** Text for close action / 关闭操作的文本 */ closeText: string + /** ARIA label for close key / 关闭键的 ARIA 标签 */ closeKeyAriaLabel: string } } +/** + * Locale configuration type for search box. + * + * 搜索框的语言配置类型。 + */ export type SearchBoxLocales = LocaleConfig +/** + * Options for the search plugin. + * + * 搜索插件的选项。 + */ export interface SearchPluginOptions extends SearchOptions { + /** Locale-specific search configurations / 特定语言的搜索配置 */ locales?: SearchBoxLocales + /** + * Function to determine if a page should be indexed. + * + * 判断页面是否应被索引的函数。 + * + * @param page - VuePress page object / VuePress 页面对象 + * @returns Whether the page should be searchable / 页面是否可搜索 + */ isSearchable?: (page: Page) => boolean } +/** + * Search configuration options. + * + * 搜索配置选项。 + */ export interface SearchOptions { /** + * Whether to disable query persistence in session storage. + * + * 是否禁用会话存储中的查询持久化。 + * * @default false */ disableQueryPersistence?: boolean + /** + * MiniSearch configuration options. + * + * MiniSearch 配置选项。 + */ miniSearch?: { /** + * MiniSearch instance options. + * + * MiniSearch 实例选项。 + * * @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#options */ options?: Pick< @@ -42,6 +109,10 @@ export interface SearchOptions { 'extractField' | 'tokenize' | 'processTerm' > /** + * MiniSearch search options. + * + * MiniSearch 搜索选项。 + * * @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchoptions-1 */ searchOptions?: MiniSearchOptions['searchOptions']