From 565199a63760e51f2f5421c8df075aeeb7e54a53 Mon Sep 17 00:00:00 2001 From: Viktor Arvidsson Date: Mon, 4 Sep 2023 14:46:33 +0200 Subject: [PATCH 1/3] fix: make tests work on windows --- .../src/server/utils/generate.spec.ts | 46 +++++++++---------- .../src/server/utils/processDocInfos.spec.ts | 32 ++++++------- .../server/utils/processPluginOptions.spec.ts | 12 ++--- jest.config.js | 1 + jestSetup.js | 26 +++++++++++ package.json | 1 + 6 files changed, 73 insertions(+), 45 deletions(-) create mode 100644 jestSetup.js diff --git a/docusaurus-search-local/src/server/utils/generate.spec.ts b/docusaurus-search-local/src/server/utils/generate.spec.ts index 49440583..b0e2971d 100644 --- a/docusaurus-search-local/src/server/utils/generate.spec.ts +++ b/docusaurus-search-local/src/server/utils/generate.spec.ts @@ -18,7 +18,7 @@ describe("generate", () => { [ ["en"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), 'export const language = ["en"];', "export const removeDefaultStopWordFilter = false;", "export const removeDefaultStemmer = false;", @@ -40,9 +40,9 @@ describe("generate", () => { [ ["zh"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.stemmer\.support\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.stemmer\.support\.js"\)\(lunr\);$/ ), 'require("@easyops-cn/docusaurus-search-local/dist/client/shared/lunrLanguageZh").lunrLanguageZh(lunr);', 'export const language = ["zh"];', @@ -66,12 +66,12 @@ describe("generate", () => { [ ["es"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.stemmer\.support\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.stemmer\.support\.js"\)\(lunr\);$/ ), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.es\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.es\.js"\)\(lunr\);$/ ), 'export const language = ["es"];', "export const removeDefaultStopWordFilter = false;", @@ -94,15 +94,15 @@ describe("generate", () => { [ ["ja"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.stemmer\.support\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.stemmer\.support\.js"\)\(lunr\);$/ ), expect.stringMatching( - /^require\(".+\/lunr-languages\/tinyseg\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\tinyseg\.js"\)\(lunr\);$/ ), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.ja\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.ja\.js"\)\(lunr\);$/ ), 'export const language = ["ja"];', "export const removeDefaultStopWordFilter = false;", @@ -125,13 +125,13 @@ describe("generate", () => { [ ["en", "zh"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.stemmer\.support\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.stemmer\.support\.js"\)\(lunr\);$/ ), 'require("@easyops-cn/docusaurus-search-local/dist/client/shared/lunrLanguageZh").lunrLanguageZh(lunr);', expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.multi\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.multi\.js"\)\(lunr\);$/ ), 'export const language = ["en","zh"];', "export const removeDefaultStopWordFilter = false;", @@ -154,16 +154,16 @@ describe("generate", () => { [ ["en", "es", "zh"], [ - expect.stringMatching(/^import lunr from ".+\/lunr\/lunr\.js";$/), + expect.stringMatching(/^import lunr from ".+\/|\\lunr\/|\\lunr\.js";$/), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.stemmer\.support\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.stemmer\.support\.js"\)\(lunr\);$/ ), expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.es\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.es\.js"\)\(lunr\);$/ ), 'require("@easyops-cn/docusaurus-search-local/dist/client/shared/lunrLanguageZh").lunrLanguageZh(lunr);', expect.stringMatching( - /^require\(".+\/lunr-languages\/lunr\.multi\.js"\)\(lunr\);$/ + /^require\(".+\/|\\lunr-languages\/|\\lunr\.multi\.js"\)\(lunr\);$/ ), 'export const language = ["en","es","zh"];', "export const removeDefaultStopWordFilter = false;", @@ -200,7 +200,7 @@ describe("generate", () => { "/tmp" ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.any(String) ); const calledContents = (mockWriteFileSync.mock.calls[0][1] as string).split( @@ -224,7 +224,7 @@ describe("generate", () => { ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.stringContaining("export { default as Mark } from") ); }); @@ -242,7 +242,7 @@ describe("generate", () => { ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.stringContaining("export const searchBarShortcut = false") ); }); @@ -260,7 +260,7 @@ describe("generate", () => { ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.stringContaining("export const searchBarShortcutHint = false") ); }); @@ -278,7 +278,7 @@ describe("generate", () => { ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.stringContaining( 'export const docsPluginIdForPreferredVersion = "product"' ) @@ -298,7 +298,7 @@ describe("generate", () => { ); expect(mockWriteFileSync).toBeCalledWith( - "/tmp/generated.js", + expect.toMatchPath("/tmp/generated.js"), expect.stringContaining( 'export const searchIndexUrl = "search-index{dir}-abc.json"' ) diff --git a/docusaurus-search-local/src/server/utils/processDocInfos.spec.ts b/docusaurus-search-local/src/server/utils/processDocInfos.spec.ts index f13af57f..37d7c87a 100644 --- a/docusaurus-search-local/src/server/utils/processDocInfos.spec.ts +++ b/docusaurus-search-local/src/server/utils/processDocInfos.spec.ts @@ -50,17 +50,17 @@ describe("processDocInfos", () => { outDir: "/build", paths: [ { - filePath: "/build/docs/a/index.html", + filePath: expect.toMatchPath("/build/docs/a/index.html"), type: "docs", url: "/base/docs/a", }, { - filePath: "/build/blog/b/index.html", + filePath: expect.toMatchPath("/build/blog/b/index.html"), type: "blog", url: "/base/blog/b", }, { - filePath: "/build/page/index.html", + filePath: expect.toMatchPath("/build/page/index.html"), type: "page", url: "/base/page", }, @@ -120,17 +120,17 @@ describe("processDocInfos", () => { outDir: "/build", paths: [ { - filePath: "/build/docs/a.html", + filePath: expect.toMatchPath("/build/docs/a.html"), type: "docs", url: "/base/docs/a", }, { - filePath: "/build/blog/b.html", + filePath: expect.toMatchPath("/build/blog/b.html"), type: "blog", url: "/base/blog/b", }, { - filePath: "/build/page.html", + filePath: expect.toMatchPath("/build/page.html"), type: "page", url: "/base/page", }, @@ -190,17 +190,17 @@ describe("processDocInfos", () => { outDir: "/build", paths: [ { - filePath: "/build/docs/a/index.html", + filePath: expect.toMatchPath("/build/docs/a/index.html"), type: "docs", url: "/base/docs/a/", }, { - filePath: "/build/blog/b/index.html", + filePath: expect.toMatchPath("/build/blog/b/index.html"), type: "blog", url: "/base/blog/b/", }, { - filePath: "/build/page/index.html", + filePath: expect.toMatchPath("/build/page/index.html"), type: "page", url: "/base/page/", }, @@ -244,22 +244,22 @@ describe("processDocInfos", () => { outDir: "/build", paths: [ { - filePath: "/build/index.html", + filePath: expect.toMatchPath("/build/index.html"), type: "docs", url: "/base/", }, { - filePath: "/build/docs-a/index.html", + filePath: expect.toMatchPath("/build/docs-a/index.html"), type: "docs", url: "/base/docs-a", }, { - filePath: "/build/docs-b/c/index.html", + filePath: expect.toMatchPath("/build/docs-b/c/index.html"), type: "docs", url: "/base/docs-b/c", }, { - filePath: "/build/page/index.html", + filePath: expect.toMatchPath("/build/page/index.html"), type: "docs", url: "/base/page", }, @@ -303,17 +303,17 @@ describe("processDocInfos", () => { outDir: "/build", paths: [ { - filePath: "/build/blog-a/index.html", + filePath: expect.toMatchPath("/build/blog-a/index.html"), type: "blog", url: "/base/blog-a", }, { - filePath: "/build/blog-b/c/index.html", + filePath: expect.toMatchPath("/build/blog-b/c/index.html"), type: "blog", url: "/base/blog-b/c", }, { - filePath: "/build/page/index.html", + filePath: expect.toMatchPath("/build/page/index.html"), type: "blog", url: "/base/page", }, diff --git a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts index 9a7e0dc5..a8b3aa48 100644 --- a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts +++ b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts @@ -18,8 +18,8 @@ describe("processPluginOptions", () => { { docsRouteBasePath: ["docs"], blogRouteBasePath: ["blog"], - blogDir: ["/tmp/blog"], - docsDir: ["/tmp/docs"], + blogDir: [expect.toMatchPath("/tmp/blog")], + docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], searchBarPosition: "right", @@ -38,8 +38,8 @@ describe("processPluginOptions", () => { { docsRouteBasePath: ["docs"], blogRouteBasePath: ["blog"], - blogDir: ["/tmp/blog"], - docsDir: ["/tmp/docs"], + blogDir: [expect.toMatchPath("/tmp/blog")], + docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en", "zh"], ignoreFiles: [/__meta__$/], searchBarPosition: "left", @@ -91,8 +91,8 @@ describe("processPluginOptions", () => { ).toEqual({ docsRouteBasePath: ["docs"], blogRouteBasePath: ["blog"], - blogDir: ["/tmp/blog"], - docsDir: ["/tmp/docs"], + blogDir: [expect.toMatchPath("/tmp/blog")], + docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], searchBarPosition: "left", diff --git a/jest.config.js b/jest.config.js index 07b78693..59304528 100644 --- a/jest.config.js +++ b/jest.config.js @@ -16,4 +16,5 @@ module.exports = { // Ref https://github.com/facebook/jest/issues/2070#issuecomment-431706685 // Todo(steve): remove next line when issue fixed. modulePathIgnorePatterns: ["/.*/__mocks__"], + setupFilesAfterEnv: ["/jestSetup.js"], }; diff --git a/jestSetup.js b/jestSetup.js new file mode 100644 index 00000000..dc7eb1d8 --- /dev/null +++ b/jestSetup.js @@ -0,0 +1,26 @@ +import { matcherHint, printExpected, printReceived } from "jest-matcher-utils"; + +const passMessage = (actual, expected) => () => + `${matcherHint(".not.toMatchPath")} + +Expected value not to match: + ${printExpected(expected)} +Received: + ${printReceived(actual)}`; + +const failMessage = (actual, expected) => () => + `${matcherHint(".toMatchPath")} + +Expected value to match: + ${printExpected(expected)} +Received: + ${printReceived(actual)}`; + +expect.extend({ + toMatchPath: (actual, expected) => { + const normalised = actual.split(":").pop().replaceAll("\\", "/"); + return expected === normalised + ? { pass: true, message: passMessage(actual, normalised) } + : { pass: false, message: failMessage(actual, normalised) }; + }, +}); diff --git a/package.json b/package.json index 3e1e4b81..843091e4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "identity-obj-proxy": "^3.0.0", "jest": "^28.1.0", "jest-environment-jsdom": "^28.1.0", + "jest-matcher-utils": "^29.6.4", "lint-staged": "^13.0.0", "prettier": "^2.6.2", "typescript": "^4.7.4" From e9f7794f48c7af070c377d56bf3b6dbfccf3b9de Mon Sep 17 00:00:00 2001 From: Viktor Arvidsson Date: Mon, 4 Sep 2023 15:05:34 +0200 Subject: [PATCH 2/3] feat: added ignoreClasses option to be able to exclude specific content from indexing --- README.md | 1 + docusaurus-search-local/src/index.ts | 7 ++ .../src/server/utils/parse.spec.ts | 36 +++++++++- .../src/server/utils/parse.ts | 15 ++++- .../src/server/utils/postBuildFactory.ts | 2 +- .../server/utils/processPluginOptions.spec.ts | 6 ++ .../src/server/utils/processPluginOptions.ts | 1 + .../src/server/utils/scanDocuments.spec.ts | 10 ++- .../src/server/utils/scanDocuments.ts | 16 ++++- .../src/server/utils/validateOptions.spec.ts | 8 +++ .../src/server/utils/validateOptions.ts | 1 + .../src/shared/interfaces.ts | 2 + yarn.lock | 66 +++++++++++++++++++ 13 files changed, 160 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b16b0826..b0f743d0 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ module.exports = { | searchResultContextMaxLength | number | `50` | Set the max length of characters of each search result to show. | | explicitSearchResultPath | boolean | `false` | Whether an explicit path to a heading should be presented on a suggestion template. | | ignoreFiles | string \| RegExp \| (string \| RegExp)[] | `[]` | Set the match rules to ignore some routes. Put a string if you want an exact match, or put a regex if you want a partial match. Note: without the website base url. | +| ignoreClasses | string \| string[] | `[]` | A list of html classes to ignore when indexing each page. | | searchBarShortcut | boolean | `true` | Whether to enable keyboard shortcut to focus in search bar. | | searchBarShortcutHint | boolean | `true` | Whether to show keyboard shortcut hint in search bar. Disable it if you need to hide the hint while shortcut is still enabled. | | searchBarPosition | `"auto"` \| `"left"` \| `"right"` | `"auto"` | The side of the navbar the search bar should appear on. By default, it will try to autodetect based on your docusaurus config according to [the docs](https://docusaurus.io/docs/api/themes/configuration#navbar-search). | diff --git a/docusaurus-search-local/src/index.ts b/docusaurus-search-local/src/index.ts index ef04e55d..b6524bec 100644 --- a/docusaurus-search-local/src/index.ts +++ b/docusaurus-search-local/src/index.ts @@ -120,6 +120,13 @@ export interface PluginOptions { */ ignoreFiles?: string | RegExp | (string | RegExp)[]; + /** + * A list of html classes to ignore when indexing each page. + * + * @default [] + */ + ignoreClasses?: string | string[]; + /** * Whether to enable keyboard shortcut to focus in search bar. * diff --git a/docusaurus-search-local/src/server/utils/parse.spec.ts b/docusaurus-search-local/src/server/utils/parse.spec.ts index 5622607b..138fc63d 100644 --- a/docusaurus-search-local/src/server/utils/parse.spec.ts +++ b/docusaurus-search-local/src/server/utils/parse.spec.ts @@ -1,4 +1,7 @@ -import { ParsedDocument } from "../../shared/interfaces"; +import { + ParsedDocument, + ProcessedPluginOptions, +} from "../../shared/interfaces"; import { parse } from "./parse"; describe("parse", () => { @@ -56,7 +59,36 @@ describe("parse", () => { breadcrumb: [], }, ], + [ + ` +
+
+

Hello World

+
+
+ Test + Peace. +
+
+ `, + "docs", + { + pageTitle: "Hello World", + sections: [ + { + title: "Hello World", + hash: "", + content: "Peace.", + }, + ], + breadcrumb: [], + }, + ], ])("parse(...) should work", (html, type, doc) => { - expect(parse(html, type, "")).toEqual(doc); + expect( + parse(html, type, "", { + ignoreClasses: ["ignore"], + } as ProcessedPluginOptions) + ).toEqual(doc); }); }); diff --git a/docusaurus-search-local/src/server/utils/parse.ts b/docusaurus-search-local/src/server/utils/parse.ts index 4b1561d1..b78f4069 100644 --- a/docusaurus-search-local/src/server/utils/parse.ts +++ b/docusaurus-search-local/src/server/utils/parse.ts @@ -1,18 +1,27 @@ import cheerio from "cheerio"; -import { ParsedDocument } from "../../shared/interfaces"; +import { + ParsedDocument, + ProcessedPluginOptions, +} from "../../shared/interfaces"; import { parseDocument } from "./parseDocument"; import { parsePage } from "./parsePage"; export function parse( html: string, type: "docs" | "blog" | "page", - url: string + url: string, + { ignoreClasses }: ProcessedPluginOptions ): ParsedDocument { const $ = cheerio.load(html); - // Remove copy buttons from code boxes $('div[class^="mdxCodeBlock_"] button').remove(); + if (ignoreClasses) { + for (const ignoreClass of ignoreClasses) { + $("." + ignoreClass).remove(); + } + } + if (type === "docs") { // Remove version badges $("span.badge") diff --git a/docusaurus-search-local/src/server/utils/postBuildFactory.ts b/docusaurus-search-local/src/server/utils/postBuildFactory.ts index 3cf78cbf..0c0fa2c2 100644 --- a/docusaurus-search-local/src/server/utils/postBuildFactory.ts +++ b/docusaurus-search-local/src/server/utils/postBuildFactory.ts @@ -26,7 +26,7 @@ export function postBuildFactory( for (const versionData of data) { // Give every index entry a unique id so that the index does not need to store long URLs. - const allDocuments = await scanDocuments(versionData.paths); + const allDocuments = await scanDocuments(versionData.paths, config); debugInfo("building index"); diff --git a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts index a8b3aa48..a0de932f 100644 --- a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts +++ b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts @@ -13,6 +13,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: "en", ignoreFiles: "test", + ignoreClasses: [], searchBarPosition: "auto", }, { @@ -22,6 +23,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], + ignoreClasses: [], searchBarPosition: "right", }, ], @@ -33,6 +35,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: ["en", "zh"], ignoreFiles: [/__meta__$/], + ignoreClasses: [], searchBarPosition: "left", }, { @@ -42,6 +45,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en", "zh"], ignoreFiles: [/__meta__$/], + ignoreClasses: [], searchBarPosition: "left", }, ], @@ -66,6 +70,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: "en", ignoreFiles: "test", + ignoreClasses: [], searchBarPosition: "auto", }, { @@ -95,6 +100,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], + ignoreClasses: [], searchBarPosition: "left", }); }); diff --git a/docusaurus-search-local/src/server/utils/processPluginOptions.ts b/docusaurus-search-local/src/server/utils/processPluginOptions.ts index 906d528f..ffc2f2d7 100644 --- a/docusaurus-search-local/src/server/utils/processPluginOptions.ts +++ b/docusaurus-search-local/src/server/utils/processPluginOptions.ts @@ -19,6 +19,7 @@ export function processPluginOptions( ensureArray(config, "docsDir"); ensureArray(config, "blogDir"); ensureArray(config, "ignoreFiles"); + ensureArray(config, "ignoreClasses"); config.docsRouteBasePath = config.docsRouteBasePath.map((basePath) => basePath.replace(/^\//, "") ); diff --git a/docusaurus-search-local/src/server/utils/scanDocuments.spec.ts b/docusaurus-search-local/src/server/utils/scanDocuments.spec.ts index 330869b1..d1045a48 100644 --- a/docusaurus-search-local/src/server/utils/scanDocuments.spec.ts +++ b/docusaurus-search-local/src/server/utils/scanDocuments.spec.ts @@ -1,6 +1,9 @@ import fs from "fs"; import { parse } from "./parse"; -import { DocInfoWithFilePath } from "../../shared/interfaces"; +import { + DocInfoWithFilePath, + ProcessedPluginOptions, +} from "../../shared/interfaces"; jest.mock("./parse"); jest.spyOn(fs, "readFile").mockImplementation((( @@ -63,7 +66,10 @@ describe("scanDocuments", () => { }; } }); - const allDocuments = await scanDocuments(DocInfoWithFilePathList); + const allDocuments = await scanDocuments( + DocInfoWithFilePathList, + {} as ProcessedPluginOptions + ); expect(allDocuments).toMatchInlineSnapshot(` Array [ Array [ diff --git a/docusaurus-search-local/src/server/utils/scanDocuments.ts b/docusaurus-search-local/src/server/utils/scanDocuments.ts index bff5de80..c6a25714 100644 --- a/docusaurus-search-local/src/server/utils/scanDocuments.ts +++ b/docusaurus-search-local/src/server/utils/scanDocuments.ts @@ -1,7 +1,11 @@ import fs from "fs"; import path from "path"; import util from "util"; -import { DocInfoWithFilePath, SearchDocument } from "../../shared/interfaces"; +import { + DocInfoWithFilePath, + SearchDocument, + ProcessedPluginOptions, +} from "../../shared/interfaces"; import { parse } from "./parse"; import { debugVerbose } from "./debug"; @@ -13,7 +17,8 @@ const getNextDocId = () => { }; export async function scanDocuments( - DocInfoWithFilePathList: DocInfoWithFilePath[] + DocInfoWithFilePathList: DocInfoWithFilePath[], + config: ProcessedPluginOptions ): Promise { const titleDocuments: SearchDocument[] = []; const headingDocuments: SearchDocument[] = []; @@ -30,7 +35,12 @@ export async function scanDocuments( ); const html = await readFileAsync(filePath, { encoding: "utf8" }); - const { pageTitle, sections, breadcrumb } = parse(html, type, url); + const { pageTitle, sections, breadcrumb } = parse( + html, + type, + url, + config + ); const titleId = getNextDocId(); diff --git a/docusaurus-search-local/src/server/utils/validateOptions.spec.ts b/docusaurus-search-local/src/server/utils/validateOptions.spec.ts index f3281526..1eeb762d 100644 --- a/docusaurus-search-local/src/server/utils/validateOptions.spec.ts +++ b/docusaurus-search-local/src/server/utils/validateOptions.spec.ts @@ -52,6 +52,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -78,6 +79,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: "file1", + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -104,6 +106,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [/__meta__$/, "file1"], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -130,6 +133,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -167,6 +171,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 30, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: false, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -198,6 +203,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: false, searchBarPosition: "auto", @@ -233,6 +239,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "left", @@ -269,6 +276,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], + ignoreClasses: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "left", diff --git a/docusaurus-search-local/src/server/utils/validateOptions.ts b/docusaurus-search-local/src/server/utils/validateOptions.ts index 86733f60..7d65bfbe 100644 --- a/docusaurus-search-local/src/server/utils/validateOptions.ts +++ b/docusaurus-search-local/src/server/utils/validateOptions.ts @@ -36,6 +36,7 @@ const schema = Joi.object({ searchResultContextMaxLength: Joi.number().default(50), explicitSearchResultPath: Joi.boolean().default(false), ignoreFiles: isArrayOfStringsOrRegExpsOrStringOrRegExp.default([]), + ignoreClasses: isStringOrArrayOfStrings.default([]), searchBarShortcut: Joi.boolean().default(true), searchBarShortcutHint: Joi.boolean().default(true), searchBarPosition: Joi.string().default("auto"), diff --git a/docusaurus-search-local/src/shared/interfaces.ts b/docusaurus-search-local/src/shared/interfaces.ts index 80696fe0..5bbc9a64 100644 --- a/docusaurus-search-local/src/shared/interfaces.ts +++ b/docusaurus-search-local/src/shared/interfaces.ts @@ -143,6 +143,7 @@ export type ProcessedPluginOptions = Required< | "docsDir" | "blogDir" | "ignoreFiles" + | "ignoreClasses" > > & { docsRouteBasePath: string[]; @@ -151,6 +152,7 @@ export type ProcessedPluginOptions = Required< docsDir: string[]; blogDir: string[]; ignoreFiles: (string | RegExp)[]; + ignoreClasses: string[]; }; export interface PostBuildData { diff --git a/yarn.lock b/yarn.lock index 43f89de0..b8110e31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2469,6 +2469,15 @@ __metadata: languageName: node linkType: hard +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 + languageName: node + linkType: hard + "@jest/source-map@npm:^28.0.2": version: 28.0.2 resolution: "@jest/source-map@npm:28.0.2" @@ -2866,6 +2875,13 @@ __metadata: languageName: node linkType: hard +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 + languageName: node + linkType: hard + "@sindresorhus/is@npm:^0.14.0": version: 0.14.0 resolution: "@sindresorhus/is@npm:0.14.0" @@ -5891,6 +5907,13 @@ __metadata: languageName: node linkType: hard +"diff-sequences@npm:^29.6.3": + version: 29.6.3 + resolution: "diff-sequences@npm:29.6.3" + checksum: f4914158e1f2276343d98ff5b31fc004e7304f5470bf0f1adb2ac6955d85a531a6458d33e87667f98f6ae52ebd3891bb47d420bb48a5bd8b7a27ee25b20e33aa + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -8533,6 +8556,18 @@ __metadata: languageName: node linkType: hard +"jest-diff@npm:^29.6.4": + version: 29.6.4 + resolution: "jest-diff@npm:29.6.4" + dependencies: + chalk: ^4.0.0 + diff-sequences: ^29.6.3 + jest-get-type: ^29.6.3 + pretty-format: ^29.6.3 + checksum: e205c45ab6dbcc660dc2a682cddb20f6a3cbbbdecd2821cce2050619f96dbd7560ee25f7f51d42c302596aeaddbea54390b78be3ab639340d24d67e4d270a8b0 + languageName: node + linkType: hard + "jest-docblock@npm:^28.0.2": version: 28.0.2 resolution: "jest-docblock@npm:28.0.2" @@ -8592,6 +8627,13 @@ __metadata: languageName: node linkType: hard +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 88ac9102d4679d768accae29f1e75f592b760b44277df288ad76ce5bf038c3f5ce3719dea8aa0f035dac30e9eb034b848ce716b9183ad7cc222d029f03e92205 + languageName: node + linkType: hard + "jest-haste-map@npm:^28.1.0": version: 28.1.0 resolution: "jest-haste-map@npm:28.1.0" @@ -8637,6 +8679,18 @@ __metadata: languageName: node linkType: hard +"jest-matcher-utils@npm:^29.6.4": + version: 29.6.4 + resolution: "jest-matcher-utils@npm:29.6.4" + dependencies: + chalk: ^4.0.0 + jest-diff: ^29.6.4 + jest-get-type: ^29.6.3 + pretty-format: ^29.6.3 + checksum: 9e17bce282e74bdbba2ce5475c490e0bba4f464cd42132bfc5df0337e0853af4dba925c7f4f61cbb0a4818fa121d28d7ff0196ec8829773a22fce59a822976d2 + languageName: node + linkType: hard + "jest-message-util@npm:^28.1.0": version: 28.1.0 resolution: "jest-message-util@npm:28.1.0" @@ -10970,6 +11024,17 @@ __metadata: languageName: node linkType: hard +"pretty-format@npm:^29.6.3": + version: 29.6.3 + resolution: "pretty-format@npm:29.6.3" + dependencies: + "@jest/schemas": ^29.6.3 + ansi-styles: ^5.0.0 + react-is: ^18.0.0 + checksum: 4e1c0db48e65571c22e80ff92123925ff8b3a2a89b71c3a1683cfde711004d492de32fe60c6bc10eea8bf6c678e5cbe544ac6c56cb8096e1eb7caf856928b1c4 + languageName: node + linkType: hard + "pretty-time@npm:^1.1.0": version: 1.1.0 resolution: "pretty-time@npm:1.1.0" @@ -11849,6 +11914,7 @@ __metadata: identity-obj-proxy: ^3.0.0 jest: ^28.1.0 jest-environment-jsdom: ^28.1.0 + jest-matcher-utils: ^29.6.4 lint-staged: ^13.0.0 prettier: ^2.6.2 typescript: ^4.7.4 From 4e2bc60efeba1165681940325610a1468b94e8bf Mon Sep 17 00:00:00 2001 From: Viktor Arvidsson Date: Fri, 8 Sep 2023 17:36:21 +0200 Subject: [PATCH 3/3] refactor: rename ignoreClasses to ignoreCssSelectors and allow any css selector instead of just classes --- README.md | 2 +- docusaurus-search-local/src/index.ts | 4 ++-- .../src/server/utils/parse.spec.ts | 2 +- .../src/server/utils/parse.ts | 8 ++++---- .../server/utils/processPluginOptions.spec.ts | 12 ++++++------ .../src/server/utils/processPluginOptions.ts | 2 +- .../src/server/utils/validateOptions.spec.ts | 16 ++++++++-------- .../src/server/utils/validateOptions.ts | 2 +- docusaurus-search-local/src/shared/interfaces.ts | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index b0f743d0..60c2771e 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ module.exports = { | searchResultContextMaxLength | number | `50` | Set the max length of characters of each search result to show. | | explicitSearchResultPath | boolean | `false` | Whether an explicit path to a heading should be presented on a suggestion template. | | ignoreFiles | string \| RegExp \| (string \| RegExp)[] | `[]` | Set the match rules to ignore some routes. Put a string if you want an exact match, or put a regex if you want a partial match. Note: without the website base url. | -| ignoreClasses | string \| string[] | `[]` | A list of html classes to ignore when indexing each page. | +| ignoreCssSelectors | string \| string[] | `[]` | A list of css selectors to ignore when indexing each page. | | searchBarShortcut | boolean | `true` | Whether to enable keyboard shortcut to focus in search bar. | | searchBarShortcutHint | boolean | `true` | Whether to show keyboard shortcut hint in search bar. Disable it if you need to hide the hint while shortcut is still enabled. | | searchBarPosition | `"auto"` \| `"left"` \| `"right"` | `"auto"` | The side of the navbar the search bar should appear on. By default, it will try to autodetect based on your docusaurus config according to [the docs](https://docusaurus.io/docs/api/themes/configuration#navbar-search). | diff --git a/docusaurus-search-local/src/index.ts b/docusaurus-search-local/src/index.ts index b6524bec..222aba6d 100644 --- a/docusaurus-search-local/src/index.ts +++ b/docusaurus-search-local/src/index.ts @@ -121,11 +121,11 @@ export interface PluginOptions { ignoreFiles?: string | RegExp | (string | RegExp)[]; /** - * A list of html classes to ignore when indexing each page. + * A list of css selectors to ignore when indexing each page. * * @default [] */ - ignoreClasses?: string | string[]; + ignoreCssSelectors?: string | string[]; /** * Whether to enable keyboard shortcut to focus in search bar. diff --git a/docusaurus-search-local/src/server/utils/parse.spec.ts b/docusaurus-search-local/src/server/utils/parse.spec.ts index 138fc63d..4d5d6e15 100644 --- a/docusaurus-search-local/src/server/utils/parse.spec.ts +++ b/docusaurus-search-local/src/server/utils/parse.spec.ts @@ -87,7 +87,7 @@ describe("parse", () => { ])("parse(...) should work", (html, type, doc) => { expect( parse(html, type, "", { - ignoreClasses: ["ignore"], + ignoreCssSelectors: [".ignore"], } as ProcessedPluginOptions) ).toEqual(doc); }); diff --git a/docusaurus-search-local/src/server/utils/parse.ts b/docusaurus-search-local/src/server/utils/parse.ts index b78f4069..f2d740ff 100644 --- a/docusaurus-search-local/src/server/utils/parse.ts +++ b/docusaurus-search-local/src/server/utils/parse.ts @@ -10,15 +10,15 @@ export function parse( html: string, type: "docs" | "blog" | "page", url: string, - { ignoreClasses }: ProcessedPluginOptions + { ignoreCssSelectors }: ProcessedPluginOptions ): ParsedDocument { const $ = cheerio.load(html); // Remove copy buttons from code boxes $('div[class^="mdxCodeBlock_"] button').remove(); - if (ignoreClasses) { - for (const ignoreClass of ignoreClasses) { - $("." + ignoreClass).remove(); + if (ignoreCssSelectors) { + for (const ignoreSelector of ignoreCssSelectors) { + $(ignoreSelector).remove(); } } diff --git a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts index a0de932f..421dcea6 100644 --- a/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts +++ b/docusaurus-search-local/src/server/utils/processPluginOptions.spec.ts @@ -13,7 +13,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: "en", ignoreFiles: "test", - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "auto", }, { @@ -23,7 +23,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "right", }, ], @@ -35,7 +35,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: ["en", "zh"], ignoreFiles: [/__meta__$/], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "left", }, { @@ -45,7 +45,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en", "zh"], ignoreFiles: [/__meta__$/], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "left", }, ], @@ -70,7 +70,7 @@ describe("processPluginOptions", () => { blogDir: "blog", language: "en", ignoreFiles: "test", - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "auto", }, { @@ -100,7 +100,7 @@ describe("processPluginOptions", () => { docsDir: [expect.toMatchPath("/tmp/docs")], language: ["en"], ignoreFiles: ["test"], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarPosition: "left", }); }); diff --git a/docusaurus-search-local/src/server/utils/processPluginOptions.ts b/docusaurus-search-local/src/server/utils/processPluginOptions.ts index ffc2f2d7..a6cb3806 100644 --- a/docusaurus-search-local/src/server/utils/processPluginOptions.ts +++ b/docusaurus-search-local/src/server/utils/processPluginOptions.ts @@ -19,7 +19,7 @@ export function processPluginOptions( ensureArray(config, "docsDir"); ensureArray(config, "blogDir"); ensureArray(config, "ignoreFiles"); - ensureArray(config, "ignoreClasses"); + ensureArray(config, "ignoreCssSelectors"); config.docsRouteBasePath = config.docsRouteBasePath.map((basePath) => basePath.replace(/^\//, "") ); diff --git a/docusaurus-search-local/src/server/utils/validateOptions.spec.ts b/docusaurus-search-local/src/server/utils/validateOptions.spec.ts index 1eeb762d..f44d7f92 100644 --- a/docusaurus-search-local/src/server/utils/validateOptions.spec.ts +++ b/docusaurus-search-local/src/server/utils/validateOptions.spec.ts @@ -52,7 +52,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -79,7 +79,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: "file1", - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -106,7 +106,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [/__meta__$/, "file1"], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -133,7 +133,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -171,7 +171,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 30, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: false, searchBarShortcutHint: true, searchBarPosition: "auto", @@ -203,7 +203,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: false, searchBarPosition: "auto", @@ -239,7 +239,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "left", @@ -276,7 +276,7 @@ describe("validateOptions", () => { explicitSearchResultPath: false, searchResultContextMaxLength: 50, ignoreFiles: [], - ignoreClasses: [], + ignoreCssSelectors: [], searchBarShortcut: true, searchBarShortcutHint: true, searchBarPosition: "left", diff --git a/docusaurus-search-local/src/server/utils/validateOptions.ts b/docusaurus-search-local/src/server/utils/validateOptions.ts index 7d65bfbe..bb2020eb 100644 --- a/docusaurus-search-local/src/server/utils/validateOptions.ts +++ b/docusaurus-search-local/src/server/utils/validateOptions.ts @@ -36,7 +36,7 @@ const schema = Joi.object({ searchResultContextMaxLength: Joi.number().default(50), explicitSearchResultPath: Joi.boolean().default(false), ignoreFiles: isArrayOfStringsOrRegExpsOrStringOrRegExp.default([]), - ignoreClasses: isStringOrArrayOfStrings.default([]), + ignoreCssSelectors: isStringOrArrayOfStrings.default([]), searchBarShortcut: Joi.boolean().default(true), searchBarShortcutHint: Joi.boolean().default(true), searchBarPosition: Joi.string().default("auto"), diff --git a/docusaurus-search-local/src/shared/interfaces.ts b/docusaurus-search-local/src/shared/interfaces.ts index 5bbc9a64..4ab303d0 100644 --- a/docusaurus-search-local/src/shared/interfaces.ts +++ b/docusaurus-search-local/src/shared/interfaces.ts @@ -143,7 +143,7 @@ export type ProcessedPluginOptions = Required< | "docsDir" | "blogDir" | "ignoreFiles" - | "ignoreClasses" + | "ignoreCssSelectors" > > & { docsRouteBasePath: string[]; @@ -152,7 +152,7 @@ export type ProcessedPluginOptions = Required< docsDir: string[]; blogDir: string[]; ignoreFiles: (string | RegExp)[]; - ignoreClasses: string[]; + ignoreCssSelectors: string[]; }; export interface PostBuildData {