@easyops-cn/docusaurus-search-local 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [0.36.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.35.0...v0.36.0) (2023-09-09)
6
+
7
+
8
+ ### Features
9
+
10
+ * added ignoreClasses option to be able to exclude specific content from indexing ([e9f7794](https://github.com/easyops-cn/docusaurus-search-local/commit/e9f7794f48c7af070c377d56bf3b6dbfccf3b9de))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * make tests work on windows ([565199a](https://github.com/easyops-cn/docusaurus-search-local/commit/565199a63760e51f2f5421c8df075aeeb7e54a53))
16
+
17
+ ## [0.35.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.34.0...v0.35.0) (2023-03-04)
18
+
19
+
20
+ ### Features
21
+
22
+ * improve no results UI when searching in context ([#323](https://github.com/easyops-cn/docusaurus-search-local/issues/323)) ([1a70835](https://github.com/easyops-cn/docusaurus-search-local/commit/1a708353d5fc6edae0f6e7d16bbd6e32381a9ea1))
23
+
5
24
  ## [0.34.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.33.6...v0.34.0) (2023-02-16)
6
25
 
7
26
 
@@ -102,6 +102,53 @@ export default function SearchBar({ handleSearchBarToggle, }) {
102
102
  fetchIndexes(versionUrl, searchContext),
103
103
  fetchAutoCompleteJS(),
104
104
  ]);
105
+ const searchFooterLinkElement = ({ query, isEmpty, }) => {
106
+ const a = document.createElement("a");
107
+ const params = new URLSearchParams();
108
+ const seeAllResultsText = translate({
109
+ id: "theme.SearchBar.seeAll",
110
+ message: "See all results",
111
+ });
112
+ const seeAllResultsOutsideContextText = translate({
113
+ id: "theme.SearchBar.seeAllOutsideContext",
114
+ message: "See results outside {context}",
115
+ }, { context: searchContext });
116
+ const seeAllResultsInContextText = translate({
117
+ id: "theme.SearchBar.searchInContext",
118
+ message: "See all results in {context}",
119
+ }, { context: searchContext });
120
+ params.set("q", query);
121
+ let linkText;
122
+ if (searchContext && isEmpty) {
123
+ linkText = seeAllResultsOutsideContextText;
124
+ }
125
+ else if (searchContext) {
126
+ linkText = seeAllResultsInContextText;
127
+ }
128
+ else {
129
+ linkText = seeAllResultsText;
130
+ }
131
+ if (Array.isArray(searchContextByPaths) && !isEmpty) {
132
+ params.set("ctx", searchContext);
133
+ }
134
+ if (versionUrl !== baseUrl) {
135
+ if (!versionUrl.startsWith(baseUrl)) {
136
+ throw new Error(`Version url '${versionUrl}' does not start with base url '${baseUrl}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);
137
+ }
138
+ params.set("version", versionUrl.substring(baseUrl.length));
139
+ }
140
+ const url = `${baseUrl}search?${params.toString()}`;
141
+ a.href = url;
142
+ a.textContent = linkText;
143
+ a.addEventListener("click", (e) => {
144
+ if (!e.ctrlKey && !e.metaKey) {
145
+ e.preventDefault();
146
+ search.current?.autocomplete.close();
147
+ history.push(url);
148
+ }
149
+ });
150
+ return a;
151
+ };
105
152
  search.current = autoComplete(searchBarRef.current, {
106
153
  hint: false,
107
154
  autoselect: true,
@@ -127,39 +174,10 @@ export default function SearchBar({ handleSearchBarToggle, }) {
127
174
  suggestion: SuggestionTemplate,
128
175
  empty: EmptyTemplate,
129
176
  footer: ({ query, isEmpty }) => {
130
- if (isEmpty) {
177
+ if (isEmpty && !searchContext) {
131
178
  return;
132
179
  }
133
- const a = document.createElement("a");
134
- const params = new URLSearchParams();
135
- params.set("q", query);
136
- if (Array.isArray(searchContextByPaths)) {
137
- params.set("ctx", searchContext);
138
- }
139
- if (versionUrl !== baseUrl) {
140
- if (!versionUrl.startsWith(baseUrl)) {
141
- throw new Error(`Version url '${versionUrl}' does not start with base url '${baseUrl}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);
142
- }
143
- params.set("version", versionUrl.substring(baseUrl.length));
144
- }
145
- const url = `${baseUrl}search?${params.toString()}`;
146
- a.href = url;
147
- a.textContent = searchContext
148
- ? translate({
149
- id: "theme.SearchBar.searchInContext",
150
- message: "See all results in {context}",
151
- }, { context: searchContext })
152
- : translate({
153
- id: "theme.SearchBar.seeAll",
154
- message: "See all results",
155
- });
156
- a.addEventListener("click", (e) => {
157
- if (!e.ctrlKey && !e.metaKey) {
158
- e.preventDefault();
159
- search.current?.autocomplete.close();
160
- history.push(url);
161
- }
162
- });
180
+ const a = searchFooterLinkElement({ query, isEmpty });
163
181
  const div = document.createElement("div");
164
182
  div.className = styles.hitFooter;
165
183
  div.appendChild(a);
@@ -86,14 +86,15 @@ function SearchPageContent() {
86
86
  <h1>{pageTitle}</h1>
87
87
 
88
88
  <div className="row">
89
- <div className={clsx("col", styles.searchQueryColumn, {
89
+ <div className={clsx("col", {
90
+ [styles.searchQueryColumn]: Array.isArray(searchContextByPaths),
90
91
  "col--9": Array.isArray(searchContextByPaths),
91
92
  "col--12": !Array.isArray(searchContextByPaths),
92
93
  })}>
93
94
  <input type="search" name="q" className={styles.searchQueryInput} aria-label="Search" onChange={handleSearchInputChange} value={searchQuery} autoComplete="off" autoFocus/>
94
95
  </div>
95
- {Array.isArray(searchContextByPaths) ? (<div className={clsx("col", "col--3", "padding-left--none", styles.searchVersionColumn)}>
96
- <select name="search-context" className={styles.searchVersionInput} id="context-selector" value={searchContext} onChange={(e) => updateSearchContext(e.target.value)}>
96
+ {Array.isArray(searchContextByPaths) ? (<div className={clsx("col", "col--3", "padding-left--none", styles.searchContextColumn)}>
97
+ <select name="search-context" className={styles.searchContextInput} id="context-selector" value={searchContext} onChange={(e) => updateSearchContext(e.target.value)}>
97
98
  <option value="">
98
99
  {useAllContextsWithNoSearchContext
99
100
  ? translate({
@@ -1,4 +1,4 @@
1
- .searchVersionInput,
1
+ .searchContextInput,
2
2
  .searchQueryInput {
3
3
  border-radius: var(--ifm-global-radius);
4
4
  border: var(--ifm-global-border-width) solid
@@ -30,3 +30,24 @@
30
30
  font-style: italic;
31
31
  margin: 0.5rem 0px 0px;
32
32
  }
33
+
34
+ @media only screen and (max-width: 996px) {
35
+ .searchQueryColumn {
36
+ max-width: 60% !important;
37
+ }
38
+
39
+ .searchContextColumn {
40
+ max-width: 40% !important;
41
+ }
42
+ }
43
+
44
+ @media screen and (max-width: 576px) {
45
+ .searchQueryColumn {
46
+ max-width: 100% !important;
47
+ }
48
+
49
+ .searchContextColumn {
50
+ max-width: 100% !important;
51
+ padding-left: var(--ifm-spacing-horizontal) !important;
52
+ }
53
+ }
@@ -5,10 +5,15 @@ const tslib_1 = require("tslib");
5
5
  const cheerio_1 = tslib_1.__importDefault(require("cheerio"));
6
6
  const parseDocument_1 = require("./parseDocument");
7
7
  const parsePage_1 = require("./parsePage");
8
- function parse(html, type, url) {
8
+ function parse(html, type, url, { ignoreCssSelectors }) {
9
9
  const $ = cheerio_1.default.load(html);
10
10
  // Remove copy buttons from code boxes
11
11
  $('div[class^="mdxCodeBlock_"] button').remove();
12
+ if (ignoreCssSelectors) {
13
+ for (const ignoreSelector of ignoreCssSelectors) {
14
+ $(ignoreSelector).remove();
15
+ }
16
+ }
12
17
  if (type === "docs") {
13
18
  // Remove version badges
14
19
  $("span.badge")
@@ -18,7 +18,7 @@ function postBuildFactory(config, searchIndexFilename) {
18
18
  (0, debug_1.debugInfo)("parsing documents");
19
19
  for (const versionData of data) {
20
20
  // Give every index entry a unique id so that the index does not need to store long URLs.
21
- const allDocuments = yield (0, scanDocuments_1.scanDocuments)(versionData.paths);
21
+ const allDocuments = yield (0, scanDocuments_1.scanDocuments)(versionData.paths, config);
22
22
  (0, debug_1.debugInfo)("building index");
23
23
  const docsByDirMap = new Map();
24
24
  const { searchContextByPaths, hideSearchBarWithNoSearchContext, useAllContextsWithNoSearchContext, } = config;
@@ -12,6 +12,7 @@ function processPluginOptions(options, { siteDir, siteConfig: { themeConfig }, }
12
12
  ensureArray(config, "docsDir");
13
13
  ensureArray(config, "blogDir");
14
14
  ensureArray(config, "ignoreFiles");
15
+ ensureArray(config, "ignoreCssSelectors");
15
16
  config.docsRouteBasePath = config.docsRouteBasePath.map((basePath) => basePath.replace(/^\//, ""));
16
17
  config.blogRouteBasePath = config.blogRouteBasePath.map((basePath) => basePath.replace(/^\//, ""));
17
18
  config.docsDir = config.docsDir.map((dir) => path_1.default.resolve(siteDir, dir));
@@ -12,7 +12,7 @@ let nextDocId = 0;
12
12
  const getNextDocId = () => {
13
13
  return (nextDocId += 1);
14
14
  };
15
- function scanDocuments(DocInfoWithFilePathList) {
15
+ function scanDocuments(DocInfoWithFilePathList, config) {
16
16
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
17
17
  const titleDocuments = [];
18
18
  const headingDocuments = [];
@@ -21,7 +21,7 @@ function scanDocuments(DocInfoWithFilePathList) {
21
21
  yield Promise.all(DocInfoWithFilePathList.map(({ filePath, url, type }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
22
22
  (0, debug_1.debugVerbose)(`parsing %s file %o of %o`, type, path_1.default.relative(process.cwd(), filePath), url);
23
23
  const html = yield readFileAsync(filePath, { encoding: "utf8" });
24
- const { pageTitle, sections, breadcrumb } = (0, parse_1.parse)(html, type, url);
24
+ const { pageTitle, sections, breadcrumb } = (0, parse_1.parse)(html, type, url, config);
25
25
  const titleId = getNextDocId();
26
26
  titleDocuments.push({
27
27
  i: titleId,
@@ -22,6 +22,7 @@ const schema = utils_validation_1.Joi.object({
22
22
  searchResultContextMaxLength: utils_validation_1.Joi.number().default(50),
23
23
  explicitSearchResultPath: utils_validation_1.Joi.boolean().default(false),
24
24
  ignoreFiles: isArrayOfStringsOrRegExpsOrStringOrRegExp.default([]),
25
+ ignoreCssSelectors: isStringOrArrayOfStrings.default([]),
25
26
  searchBarShortcut: utils_validation_1.Joi.boolean().default(true),
26
27
  searchBarShortcutHint: utils_validation_1.Joi.boolean().default(true),
27
28
  searchBarPosition: utils_validation_1.Joi.string().default("auto"),
@@ -103,6 +103,12 @@ export interface PluginOptions {
103
103
  * @default []
104
104
  */
105
105
  ignoreFiles?: string | RegExp | (string | RegExp)[];
106
+ /**
107
+ * A list of css selectors to ignore when indexing each page.
108
+ *
109
+ * @default []
110
+ */
111
+ ignoreCssSelectors?: string | string[];
106
112
  /**
107
113
  * Whether to enable keyboard shortcut to focus in search bar.
108
114
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easyops-cn/docusaurus-search-local",
3
- "version": "0.34.0",
3
+ "version": "0.36.0",
4
4
  "description": "An offline/local search plugin for Docusaurus v2",
5
5
  "repository": "https://github.com/easyops-cn/docusaurus-search-local",
6
6
  "homepage": "https://github.com/easyops-cn/docusaurus-search-local",