Browse Source

fix lunr search

windhamdavid 5 months ago
parent
commit
668eff8df9

+ 3 - 21
package-lock.json

@@ -1,17 +1,18 @@
 {
   "name": "daw-til-2",
-  "version": "0.0.1",
+  "version": "0.0.3",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "daw-til-2",
-      "version": "0.0.1",
+      "version": "0.0.3",
       "dependencies": {
         "@docusaurus/core": "^3.0.0",
         "@docusaurus/plugin-content-blog": "^3.0.0",
         "@docusaurus/preset-classic": "^3.0.0",
         "@docusaurus/theme-mermaid": "^3.0.0",
+        "@mdx-js/mdx": "^3.0.0",
         "@mdx-js/react": "^3.0.0",
         "clsx": "^2.0.0",
         "docusaurus-lunr-search": "^3.3.0",
@@ -16221,12 +16222,6 @@
         "url": "https://opencollective.com/webpack"
       }
     },
-    "node_modules/search-insights": {
-      "version": "2.10.0",
-      "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.10.0.tgz",
-      "integrity": "sha512-pQGrOE56QuTRmq4NzliRZe9rv914hBMBjOviuDliDHoIhmBGoyZRlFsPd4RprGGNC4PKdD2Jz54YN4Cmkb44mA==",
-      "peer": true
-    },
     "node_modules/section-matter": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
@@ -17346,19 +17341,6 @@
         "is-typedarray": "^1.0.0"
       }
     },
-    "node_modules/typescript": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
-      "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
-      "peer": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
     "node_modules/ua-parser-js": {
       "version": "1.0.37",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.37.tgz",

+ 1 - 1
package.json

@@ -18,8 +18,8 @@
     "@docusaurus/plugin-content-blog": "^3.0.0",
     "@docusaurus/preset-classic": "^3.0.0",
     "@docusaurus/theme-mermaid": "^3.0.0",
-    "@mdx-js/react": "^3.0.0",
     "@mdx-js/mdx": "^3.0.0",
+    "@mdx-js/react": "^3.0.0",
     "clsx": "^2.0.0",
     "docusaurus-lunr-search": "^3.3.0",
     "docusaurus-plugin-matomo": "^0.0.6",

+ 6 - 0
src/css/custom.css

@@ -30,6 +30,12 @@ html[data-theme='dark'] {
   --ifm-color-primary-lightest: rgb(146, 224, 208);
   --ifm-code-font-size: 95%;
 }
+[data-theme='dark'] .ds-dropdown-menu {
+  --ifm-background-color: #383a42;
+    border-color: #535763;
+}
+
+
 .toggleTrack_node_modules-\@docusaurus-theme-classic-lib-next-theme-Toggle-styles-module {
   background-color: #e2e2e2 !important;
 }

+ 15 - 2
src/theme/SearchBar/DocSearch.js

@@ -22,7 +22,7 @@ class DocSearch {
         queryHook = false,
         handleSelected = false,
         enhancedSearchInput = false,
-        layout = "collumns"
+        layout = "column"
     }) {
         this.input = DocSearch.getInputFromSelector(inputSelector);
         this.queryDataCallback = queryDataCallback || null;
@@ -85,6 +85,17 @@ class DocSearch {
         if (enhancedSearchInput) {
             DocSearch.bindSearchBoxEvent();
         }
+
+
+        // Ctrl + K should focus the search bar, emulating the Algolia search UI
+        document.addEventListener('keydown',  (e) => {
+            if (e.ctrlKey && e.key == 'k') {
+                this.input.focus();
+
+                // By default, using Ctrl + K in Chrome will open the location bar, so disable this
+                e.preventDefault();
+            }
+        });
     }
 
     static injectSearchBox(input) {
@@ -211,6 +222,7 @@ class DocSearch {
                 !isLvl2 &&
                 (subcategory && subcategory !== "" && subcategory !== category);
             const isLvl0 = !isLvl1 && !isLvl2;
+            const version = hit.version;
 
             return {
                 isLvl0,
@@ -224,7 +236,8 @@ class DocSearch {
                 subcategory,
                 title: displayTitle,
                 text,
-                url
+                url,
+                version
             };
         });
     }

+ 53 - 0
src/theme/SearchBar/HighlightSearchResults.jsx

@@ -0,0 +1,53 @@
+//copied from https://github.com/cmfcmf/docusaurus-search-local
+import Mark from "mark.js";
+import { useEffect, useState } from "react";
+import { useLocation } from "@docusaurus/router";
+import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
+import { useHistory } from "@docusaurus/router";
+
+export function HighlightSearchResults() {
+  const location = useLocation();
+  const history = useHistory();
+  const {
+    siteConfig: { baseUrl },
+  } = useDocusaurusContext();
+
+  const [highlightData, setHighlightData] = useState({ wordToHighlight: '', isTitleSuggestion: false , titleText: '' });
+
+  useEffect(() => {
+    if (
+      !location.state?.highlightState ||
+      location.state.highlightState.wordToHighlight.length === 0
+    ) {
+      return;
+    }
+    setHighlightData(location.state.highlightState);
+
+    const { highlightState, ...state } = location.state;
+    history.replace({
+      ...location,
+      state,
+    });
+  }, [location.state?.highlightState, history, location]);
+
+  useEffect(() => {
+    if (highlightData.wordToHighlight.length === 0) {
+      return;
+    }
+
+    // Make sure to also adjust parse.js if you change the top element here.
+    const root =  document.getElementsByTagName("article")[0] ?? document.getElementsByTagName("main")[0] ;
+    if (!root) {
+      return;
+    }
+
+    const mark = new Mark(root);
+    const options = {
+      ignoreJoiners: true,
+    };
+    mark.mark(highlightData.wordToHighlight , options);
+    return () => mark.unmark(options);
+  }, [highlightData, baseUrl]);
+
+  return null;
+}

+ 27 - 0
src/theme/SearchBar/algolia.css

@@ -450,6 +450,14 @@
   padding-right: 2px;
 }
 
+.algolia-autocomplete .algolia-docsearch-suggestion--version {
+  display: block;
+  font-size: 0.65em;
+  color: #a6aab1;
+  padding-top: 2px;
+  padding-right: 2px;
+}
+
 .algolia-autocomplete .algolia-docsearch-suggestion--no-results {
   width: 100%;
   padding: 8px 0;
@@ -524,3 +532,22 @@
   margin-left: auto;
   margin-right: 5px;
 }
+
+html[data-theme='dark'] .algolia-docsearch-suggestion--category-header,
+html[data-theme='dark'] .algolia-docsearch-suggestion--wrapper,
+html[data-theme='dark'] .algolia-docsearch-footer {
+    background: var(--ifm-background-color) !important;
+    color: var(--ifm-font-color-base) !important;
+}
+
+html[data-theme='dark'] .algolia-docsearch-suggestion--title {
+    color: var(--ifm-font-color-base) !important;
+}
+
+html[data-theme='dark'] .ds-cursor .algolia-docsearch-suggestion--wrapper {
+    background: var(--ifm-background-surface-color) !important;
+}
+
+mark{
+  background-color: lightblue;
+}

+ 137 - 0
src/theme/SearchBar/index.jsx

@@ -0,0 +1,137 @@
+import React, { useRef, useCallback, useState } from "react";
+import clsx from "clsx";
+import { useHistory } from "@docusaurus/router";
+import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
+import { usePluginData } from '@docusaurus/useGlobalData';
+import useIsBrowser from "@docusaurus/useIsBrowser";
+import { HighlightSearchResults } from "./HighlightSearchResults";
+const Search = props => {
+  const initialized = useRef(false);
+  const searchBarRef = useRef(null);
+  const [indexReady, setIndexReady] = useState(false);
+  const history = useHistory();
+  const { siteConfig = {} } = useDocusaurusContext();
+  const pluginConfig = (siteConfig.plugins || []).find(plugin => Array.isArray(plugin) && typeof plugin[0] === "string" && plugin[0].includes("docusaurus-lunr-search"))
+  const isBrowser = useIsBrowser();
+  const { baseUrl } = siteConfig;
+  const assetUrl = pluginConfig && pluginConfig[1]?.assetUrl || baseUrl;
+  const initAlgolia = (searchDocs, searchIndex, DocSearch, options) => {
+    new DocSearch({
+      searchDocs,
+      searchIndex,
+      baseUrl,
+      inputSelector: "#search_input_react",
+      // Override algolia's default selection event, allowing us to do client-side
+      // navigation and avoiding a full page refresh.
+      handleSelected: (_input, _event, suggestion) => {
+        const url = suggestion.url || "/";
+        // Use an anchor tag to parse the absolute url into a relative url
+        // Alternatively, we can use new URL(suggestion.url) but its not supported in IE
+        const a = document.createElement("a");
+        a.href = url;
+        _input.setVal(''); // clear value
+        _event.target.blur(); // remove focus
+
+        // Get the highlight word from the suggestion.
+        let wordToHighlight = '';
+        if (options.highlightResult) {
+          try {
+            const matchedLine = suggestion.text || suggestion.subcategory || suggestion.title;
+            const matchedWordResult = matchedLine.match(new RegExp('<span.+span>\\w*', 'g'));
+            if (matchedWordResult && matchedWordResult.length > 0) {
+              const tempDoc = document.createElement('div');
+              tempDoc.innerHTML = matchedWordResult[0];
+              wordToHighlight = tempDoc.textContent;
+            }
+          } catch (e) {
+            console.log(e);
+          }
+        }
+
+        history.push(url, {
+          highlightState: { wordToHighlight },
+        });
+      }
+    });
+  };
+
+  const pluginData = usePluginData('docusaurus-lunr-search');
+  const getSearchDoc = () =>
+    process.env.NODE_ENV === "production"
+      ? fetch(`${assetUrl}${pluginData.fileNames.searchDoc}`).then((content) => content.json())
+      : Promise.resolve({});
+
+  const getLunrIndex = () =>
+    process.env.NODE_ENV === "production"
+      ? fetch(`${assetUrl}${pluginData.fileNames.lunrIndex}`).then((content) => content.json())
+      : Promise.resolve([]);
+
+  const loadAlgolia = () => {
+    if (!initialized.current) {
+      Promise.all([
+        getSearchDoc(),
+        getLunrIndex(),
+        import("./DocSearch"),
+        import("./algolia.css")
+      ]).then(([searchDocFile, searchIndex, { default: DocSearch }]) => {
+        const { searchDocs, options } = searchDocFile;
+        if (!searchDocs || searchDocs.length === 0) {
+          return;
+        }
+        initAlgolia(searchDocs, searchIndex, DocSearch, options);
+        setIndexReady(true);
+      });
+      initialized.current = true;
+    }
+  };
+
+  const toggleSearchIconClick = useCallback(
+    e => {
+      if (!searchBarRef.current.contains(e.target)) {
+        searchBarRef.current.focus();
+      }
+
+      props.handleSearchBarToggle && props.handleSearchBarToggle(!props.isSearchBarExpanded);
+    },
+    [props.isSearchBarExpanded]
+  );
+
+  if (isBrowser) {
+    loadAlgolia();
+  }
+
+  return (
+    <div className="navbar__search" key="search-box">
+      <span
+        aria-label="expand searchbar"
+        role="button"
+        className={clsx("search-icon", {
+          "search-icon-hidden": props.isSearchBarExpanded
+        })}
+        onClick={toggleSearchIconClick}
+        onKeyDown={toggleSearchIconClick}
+        tabIndex={0}
+      />
+      <input
+        id="search_input_react"
+        type="search"
+        placeholder={indexReady ? 'Search Ctrl+K' : 'Loading...'}
+        aria-label="Search"
+        className={clsx(
+          "navbar__search-input",
+          { "search-bar-expanded": props.isSearchBarExpanded },
+          { "search-bar": !props.isSearchBarExpanded }
+        )}
+        onClick={loadAlgolia}
+        onMouseOver={loadAlgolia}
+        onFocus={toggleSearchIconClick}
+        onBlur={toggleSearchIconClick}
+        ref={searchBarRef}
+        disabled={!indexReady}
+      />
+      <HighlightSearchResults />
+    </div>
+  );
+};
+
+export default Search;

+ 1 - 0
src/theme/SearchBar/lunar-search.js

@@ -27,6 +27,7 @@ class LunrSearchAdapter {
                 lvl1: doc.type === 0 ? null : doc.title
             },
             url: doc.url,
+            version: doc.version,
             _snippetResult: formattedContent ? {
                 content: {
                     value: formattedContent,

+ 1 - 0
src/theme/SearchBar/templates.js

@@ -23,6 +23,7 @@ const templates = {
         <div class="${suggestionPrefix}--subcategory-inline">{{{subcategory}}}</div>
         <div class="${suggestionPrefix}--title">{{{title}}}</div>
         {{#text}}<div class="${suggestionPrefix}--text">{{{text}}}</div>{{/text}}
+        {{#version}}<div class="${suggestionPrefix}--version">{{version}}</div>{{/version}}
       </div>
       {{/isTextOrSubcategoryNonEmpty}}
     </div>

File diff suppressed because it is too large
+ 680 - 699
yarn.lock


Some files were not shown because too many files changed in this diff