From 90408c94d334d35b4e85864a678ce55f25f8bdb1 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 28 Sep 2026 14:33:13 +0800 Subject: [PATCH 1/5] fix(search): preserve literal code block content in index --- src/plugins/search/search.js | 8 +++++--- test/e2e/search.test.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index a30f67b74..baca3c95a 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -257,12 +257,14 @@ export function genIndex(path, content = '', router, depth, indexKey) { indexKey: indexKey, }; } else { + const code = token.type === 'code' ? token.text : null; + if (tokenIndex === 0) { slug = router.toURL(path); index[slug] = { slug, title: path !== '/' ? path.slice(1) : 'Home Page', - body: markdownToTxt(/** @type {any} */ (token).text || ''), + body: code ?? markdownToTxt(/** @type {any} */ (token).text || ''), path: path, indexKey: indexKey, }; @@ -281,7 +283,7 @@ export function genIndex(path, content = '', router, depth, indexKey) { token.text = getListData(token); // @ts-expect-error - index[slug].body += '\n' + markdownToTxt(token.text || ''); + index[slug].body += '\n' + (code ?? markdownToTxt(token.text || '')); } else { // @ts-expect-error token.text = getTableData(token); @@ -289,7 +291,7 @@ export function genIndex(path, content = '', router, depth, indexKey) { token.text = getListData(token); // @ts-expect-error - index[slug].body = markdownToTxt(token.text || ''); + index[slug].body = code ?? markdownToTxt(token.text || ''); } index[slug].path = path; diff --git a/test/e2e/search.test.js b/test/e2e/search.test.js index cfcfdf99c..9d80e22b3 100644 --- a/test/e2e/search.test.js +++ b/test/e2e/search.test.js @@ -524,6 +524,39 @@ console.log('Hello World'); ); }); + for (const [name, markdown, title] of [ + [ + 'after a heading', + '# Code examples\n\n```html\n\n```', + 'Code examples', + ], + [ + 'after a paragraph', + '# Code examples\n\nAn example:\n\n```html\n\n```', + 'Code examples', + ], + ['without a heading', '```html\n\n```', 'Home Page'], + [ + 'in an indented code block', + '# Code examples\n\n ', + 'Code examples', + ], + ]) { + test(`searches HTML examples ${name}`, async ({ page }) => { + await docsifyInit({ + markdown: { homepage: markdown }, + scriptURLs: ['/dist/plugins/search.js'], + }); + + await page.locator('input[type=search]').fill('customwidget'); + await expect(page.locator('.results-panel .title')).toHaveText(title); + await expect(page.locator('.results-panel .content')).toContainText( + '', + ); + await expect(page.locator('.results-panel customwidget')).toHaveCount(0); + }); + } + test('search result should remove file markdown and keep href attribution for files', async ({ page, }) => { From 8e58868541dd5f2871869b7866618f16846663bb Mon Sep 17 00:00:00 2001 From: Luffy Date: Wed, 14 Oct 2026 16:08:09 +0800 Subject: [PATCH 2/5] fix(search): clear body content in search index --- src/plugins/search/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index baca3c95a..d739a4fd3 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -264,7 +264,7 @@ export function genIndex(path, content = '', router, depth, indexKey) { index[slug] = { slug, title: path !== '/' ? path.slice(1) : 'Home Page', - body: code ?? markdownToTxt(/** @type {any} */ (token).text || ''), + body: '', path: path, indexKey: indexKey, }; From 32bb358999234d8e70c5ead9284d5a9af52a2884 Mon Sep 17 00:00:00 2001 From: Luffy Date: Wed, 14 Oct 2026 16:12:47 +0800 Subject: [PATCH 3/5] fix(search): improve handling of post title and content escaping --- src/plugins/search/search.js | 12 +++++------- test/e2e/search.test.js | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index d739a4fd3..578bf0c40 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -339,6 +339,11 @@ export function search(query) { const postUrl = post.slug || ''; if (postTitle) { + handlePostTitle = escapeHtml(ignoreDiacriticalMarks(postTitle)); + handlePostContent = postContent + ? escapeHtml(ignoreDiacriticalMarks(postContent)) + : postContent; + keywords.forEach(keyword => { // From https://github.com/sindresorhus/escape-string-regexp const regEx = new RegExp( @@ -348,13 +353,6 @@ export function search(query) { ), 'gi', ); - handlePostTitle = postTitle - ? escapeHtml(ignoreDiacriticalMarks(postTitle)) - : postTitle; - handlePostContent = postContent - ? escapeHtml(ignoreDiacriticalMarks(postContent)) - : postContent; - const indexTitle = postTitle ? handlePostTitle.search(regEx) : -1; let indexContent = postContent ? handlePostContent.search(regEx) : -1; diff --git a/test/e2e/search.test.js b/test/e2e/search.test.js index 9d80e22b3..0d02f0e79 100644 --- a/test/e2e/search.test.js +++ b/test/e2e/search.test.js @@ -553,6 +553,12 @@ console.log('Hello World'); await expect(page.locator('.results-panel .content')).toContainText( '', ); + if (name === 'without a heading') { + const resultText = await page + .locator('.results-panel .content') + .textContent(); + expect(resultText?.match(//g)).toHaveLength(1); + } await expect(page.locator('.results-panel customwidget')).toHaveCount(0); }); } From 54c95e875b0d65a0671ead386e761c31c226c2f5 Mon Sep 17 00:00:00 2001 From: Luffy Date: Wed, 14 Oct 2026 16:16:37 +0800 Subject: [PATCH 4/5] test(search): simplify result text validation for custom widget --- test/e2e/search.test.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/e2e/search.test.js b/test/e2e/search.test.js index 0d02f0e79..803a92869 100644 --- a/test/e2e/search.test.js +++ b/test/e2e/search.test.js @@ -553,12 +553,10 @@ console.log('Hello World'); await expect(page.locator('.results-panel .content')).toContainText( '', ); - if (name === 'without a heading') { - const resultText = await page - .locator('.results-panel .content') - .textContent(); - expect(resultText?.match(//g)).toHaveLength(1); - } + const resultText = await page + .locator('.results-panel .content') + .textContent(); + expect(resultText?.match(//g)).toHaveLength(1); await expect(page.locator('.results-panel customwidget')).toHaveCount(0); }); } From 7a7184152c1c6f3b2554f4259e3c8fba007aa92e Mon Sep 17 00:00:00 2001 From: Luffy Date: Wed, 14 Oct 2026 16:19:07 +0800 Subject: [PATCH 5/5] fix(search): rename variable for clarity in search index processing --- src/plugins/search/search.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index 578bf0c40..8f2acbf1d 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -257,7 +257,7 @@ export function genIndex(path, content = '', router, depth, indexKey) { indexKey: indexKey, }; } else { - const code = token.type === 'code' ? token.text : null; + const codeText = token.type === 'code' ? token.text : null; if (tokenIndex === 0) { slug = router.toURL(path); @@ -282,16 +282,17 @@ export function genIndex(path, content = '', router, depth, indexKey) { // @ts-expect-error token.text = getListData(token); - // @ts-expect-error - index[slug].body += '\n' + (code ?? markdownToTxt(token.text || '')); + index[slug].body += + '\n' + + (codeText ?? markdownToTxt(/** @type {any} */ (token).text || '')); } else { // @ts-expect-error token.text = getTableData(token); // @ts-expect-error token.text = getListData(token); - // @ts-expect-error - index[slug].body = code ?? markdownToTxt(token.text || ''); + index[slug].body = + codeText ?? markdownToTxt(/** @type {any} */ (token).text || ''); } index[slug].path = path;