Skip to content

Commit

Permalink
Merge branch 'master' into fix221017
Browse files Browse the repository at this point in the history
  • Loading branch information
weareoutman authored Oct 17, 2022
2 parents c9b8603 + cef9b73 commit 9ec0197
Show file tree
Hide file tree
Showing 33 changed files with 1,160 additions and 640 deletions.
532 changes: 266 additions & 266 deletions .yarn/releases/yarn-3.2.2.cjs → .yarn/releases/yarn-3.2.3.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"

yarnPath: .yarn/releases/yarn-3.2.2.cjs
yarnPath: .yarn/releases/yarn-3.2.3.cjs

npmPublishAccess: public
52 changes: 29 additions & 23 deletions README.md

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions docusaurus-search-local/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,41 @@

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.

## [0.33.1](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.33.0...v0.33.1) (2022-10-17)


### Bug Fixes

* refine search context, support `hideSearchBarWithNoSearchContext` ([38908ed](https://github.com/easyops-cn/docusaurus-search-local/commit/38908edd8dea6bbf5a38f2ea225f9a9530b406ed))

## [0.33.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.32.1...v0.33.0) (2022-10-16)


### Features

* support search context by paths ([aa6de9a](https://github.com/easyops-cn/docusaurus-search-local/commit/aa6de9a2890cad2570bd40f41cccb0626a5163d6))

## [0.32.1](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.32.0...v0.32.1) (2022-10-08)


### Bug Fixes

* fix indexing when trailingSlash is explicitly set ([cfc603d](https://github.com/easyops-cn/docusaurus-search-local/commit/cfc603db8f0b2467dca064ec2f2f00b3449f4574))

## [0.32.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.31.0...v0.32.0) (2022-09-05)


### Features

* support setting searchBarPosition ([60b27d4](https://github.com/easyops-cn/docusaurus-search-local/commit/60b27d4a6e1f3342ac7afda586202fc5d7b8a3bc)), closes [#263](https://github.com/easyops-cn/docusaurus-search-local/issues/263)

## [0.31.0](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.30.2...v0.31.0) (2022-08-08)


### Features

* support `zhUserDict` and `zhUserDictPath` ([33f1ea4](https://github.com/easyops-cn/docusaurus-search-local/commit/33f1ea4765b0e134689fd65aa655c2bc1b4e6f0b)), closes [#246](https://github.com/easyops-cn/docusaurus-search-local/issues/246)

## [0.30.2](https://github.com/easyops-cn/docusaurus-search-local/compare/v0.30.1...v0.30.2) (2022-07-23)


Expand Down
1 change: 1 addition & 0 deletions docusaurus-search-local/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
See https://github.com/easyops-cn/docusaurus-search-local#readme

9 changes: 6 additions & 3 deletions docusaurus-search-local/package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
{
"name": "@easyops-cn/docusaurus-search-local",
"version": "0.30.2",
"version": "0.33.1",
"description": "An offline/local search plugin for Docusaurus v2",
"repository": "https://github.com/easyops-cn/docusaurus-search-local",
"homepage": "https://github.com/easyops-cn/docusaurus-search-local",
"scripts": {
"start": "concurrently -k -n client,server \"yarn run start:client\" \"yarn run start:server\"",
"start": "concurrently -k -n client,server,types \"yarn run start:client\" \"yarn run start:server\" \"yarn run start:types\"",
"start:client": "tsc --watch --project tsconfig.client.json",
"start:server": "tsc --watch --project tsconfig.server.json",
"build": "rimraf dist && yarn run build:client && yarn run build:server && yarn run copy-static-files",
"start:types": "tsc --project tsconfig.types.json --watch",
"build": "rimraf dist && yarn run build:client && yarn run build:server && yarn run build:types && yarn run copy-static-files",
"build:client": "tsc --project tsconfig.client.json",
"build:server": "tsc --project tsconfig.server.json",
"build:types": "tsc --project tsconfig.types.json",
"copy-static-files": "copyfiles -u 3 \"src/client/theme/**/*.css\" dist/client/client/theme && copyfiles -u 1 \"locales/*.json\" dist/locales"
},
"main": "dist/server/server/index.js",
"typings": "dist/types/index.d.ts",
"files": [
"/dist",
"!/dist/generated.js"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
padding: var(--search-local-spacing, 12px);
}

@media not (max-width: 996px) {
.searchBar.searchBarLeft .dropdownMenu {
left: 0 !important;
right: auto !important;
}
}

@media (max-width: 576px) {
:global(.navbar__search-input):not(:focus) {
width: 2rem;
Expand Down
60 changes: 50 additions & 10 deletions docusaurus-search-local/src/client/theme/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ import {
Mark,
searchBarShortcut,
searchBarShortcutHint,
searchBarPosition,
docsPluginIdForPreferredVersion,
indexDocs,
searchContextByPaths,
hideSearchBarWithNoSearchContext,
} from "../../utils/proxiedGenerated";
import LoadingRing from "../LoadingRing/LoadingRing";

Expand Down Expand Up @@ -91,24 +94,54 @@ export default function SearchBar({
const history = useHistory();
const location = useLocation();
const searchBarRef = useRef<HTMLInputElement>(null);
const indexState = useRef("empty"); // empty, loaded, done
const indexStateMap = useRef(new Map<string, "loading" | "done">());
// Should the input be focused after the index is loaded?
const focusAfterIndexLoaded = useRef(false);
const [loading, setLoading] = useState(false);
const [inputChanged, setInputChanged] = useState(false);
const [inputValue, setInputValue] = useState("");
const search = useRef<any>(null);

const prevSearchContext = useRef<string>("");
const [searchContext, setSearchContext] = useState<string>("");
useEffect(() => {
if (!Array.isArray(searchContextByPaths)) {
return;
}
let nextSearchContext = "";
if (location.pathname.startsWith(versionUrl)) {
const uri = location.pathname.substring(versionUrl.length);
const matchedPath = searchContextByPaths.find(
(path) => uri === path || uri.startsWith(`${path}/`)
);
if (matchedPath) {
nextSearchContext = matchedPath;
}
}
if (prevSearchContext.current !== nextSearchContext) {
// Reset index state map once search context is changed.
indexStateMap.current.delete(nextSearchContext);
prevSearchContext.current = nextSearchContext;
}
setSearchContext(nextSearchContext);
}, [location.pathname, versionUrl]);

const hidden =
!!hideSearchBarWithNoSearchContext &&
Array.isArray(searchContextByPaths) &&
searchContext === "";

const loadIndex = useCallback(async () => {
if (indexState.current !== "empty") {
if (hidden || indexStateMap.current.get(searchContext)) {
// Do not load the index (again) if its already loaded or in the process of being loaded.
return;
}
indexState.current = "loading";
indexStateMap.current.set(searchContext, "loading");
search.current?.autocomplete.destroy();
setLoading(true);

const [{ wrappedIndexes, zhDictionary }, autoComplete] = await Promise.all([
fetchIndexes(versionUrl),
fetchIndexes(versionUrl, searchContext),
fetchAutoCompleteJS(),
]);

Expand All @@ -119,7 +152,9 @@ export default function SearchBar({
autoselect: true,
openOnFocus: true,
cssClasses: {
root: styles.searchBar,
root: clsx(styles.searchBar, {
[styles.searchBarLeft]: searchBarPosition === "left",
}),
noPrefix: true,
dropdownMenu: styles.dropdownMenu,
input: styles.input,
Expand All @@ -146,7 +181,11 @@ export default function SearchBar({
return;
}
const a = document.createElement("a");
const url = `${baseUrl}search?q=${encodeURIComponent(query)}`;
const url = `${baseUrl}search?q=${encodeURIComponent(query)}${
Array.isArray(searchContextByPaths)
? `&ctx=${encodeURIComponent(searchContext)}`
: ""
}`;
a.href = url;
a.textContent = translate({
id: "theme.SearchBar.seeAll",
Expand All @@ -155,7 +194,7 @@ export default function SearchBar({
a.addEventListener("click", (e) => {
if (!e.ctrlKey && !e.metaKey) {
e.preventDefault();
search.current.autocomplete.close();
search.current?.autocomplete.close();
history.push(url);
}
});
Expand Down Expand Up @@ -191,17 +230,17 @@ export default function SearchBar({
searchBarRef.current?.blur();
});

indexState.current = "done";
indexStateMap.current.set(searchContext, "done");
setLoading(false);

if (focusAfterIndexLoaded.current) {
const input = searchBarRef.current as HTMLInputElement;
if (input.value) {
search.current.autocomplete.open();
search.current?.autocomplete.open();
}
input.focus();
}
}, [baseUrl, versionUrl, history]);
}, [hidden, searchContext, versionUrl, baseUrl, history]);

useEffect(() => {
if (!Mark) {
Expand Down Expand Up @@ -308,6 +347,7 @@ export default function SearchBar({
[styles.searchIndexLoading]: loading && inputChanged,
[styles.focused]: focused,
})}
hidden={hidden}
>
<input
placeholder={translate({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import lunr from "lunr";
import { fetchIndexes } from "./fetchIndexes";
import { legacyFetchIndexes as fetchIndexes } from "./fetchIndexes";

jest.mock("lunr");
jest.mock("../../utils/proxiedGenerated");
Expand Down Expand Up @@ -29,7 +29,7 @@ describe("fetchIndexes", () => {
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve([]),
});
const result = await fetchIndexes(baseUrl);
const result = await fetchIndexes(baseUrl, "");
expect(mockFetch).toBeCalledWith("/search-index.json?_=abc");
expect(result).toEqual({
wrappedIndexes: [],
Expand Down Expand Up @@ -58,8 +58,8 @@ describe("fetchIndexes", () => {
},
]),
});
const result = await fetchIndexes(baseUrl);
expect(mockFetch).toBeCalledWith("/search-index.json?_=abc");
const result = await fetchIndexes(baseUrl, "community");
expect(mockFetch).toBeCalledWith("/search-index-community.json?_=abc");
expect(result).toEqual({
wrappedIndexes: [
{
Expand All @@ -74,7 +74,7 @@ describe("fetchIndexes", () => {

test("development", async () => {
process.env.NODE_ENV = "development";
const result = await fetchIndexes(baseUrl);
const result = await fetchIndexes(baseUrl, "");
expect(mockFetch).not.toBeCalled();
expect(result).toEqual({
wrappedIndexes: [],
Expand Down
31 changes: 28 additions & 3 deletions docusaurus-search-local/src/client/theme/SearchBar/fetchIndexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,38 @@ interface SerializedIndex {
};
}

export async function fetchIndexes(baseUrl: string): Promise<{
export interface IndexesData {
wrappedIndexes: WrappedIndex[];
zhDictionary: string[];
}> {
}

const cache = new Map<string, Promise<IndexesData>>();

export function fetchIndexes(
baseUrl: string,
searchContext: string
): Promise<IndexesData> {
const cacheKey = `${baseUrl}${searchContext}`;
let promise = cache.get(cacheKey);
if (!promise) {
promise = legacyFetchIndexes(baseUrl, searchContext);
cache.set(cacheKey, promise);
}
return promise;
}

export async function legacyFetchIndexes(
baseUrl: string,
searchContext: string
): Promise<IndexesData> {
if (process.env.NODE_ENV === "production") {
const json = (await (
await fetch(`${baseUrl}${searchIndexUrl}`)
await fetch(
`${baseUrl}${searchIndexUrl.replace(
"{dir}",
searchContext ? `-${searchContext.replace(/\//g, "-")}` : ""
)}`
)
).json()) as SerializedIndex[];

const wrappedIndexes: WrappedIndex[] = json.map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { concatDocumentPath } from "../../utils/concatDocumentPath";
import {
docsPluginIdForPreferredVersion,
indexDocs,
searchContextByPaths,
} from "../../utils/proxiedGenerated";

import styles from "./SearchPage.module.css";
Expand Down Expand Up @@ -66,7 +67,7 @@ function SearchPageContent(): React.ReactElement {
}
}
const { selectMessage } = usePluralForm();
const { searchValue, updateSearchPath } = useSearchQuery();
const { searchValue, searchContext, updateSearchPath } = useSearchQuery();
const [searchQuery, setSearchQuery] = useState(searchValue);
const [searchSource, setSearchSource] =
useState<
Expand Down Expand Up @@ -127,13 +128,16 @@ function SearchPageContent(): React.ReactElement {

useEffect(() => {
async function doFetchIndexes() {
const { wrappedIndexes, zhDictionary } = await fetchIndexes(versionUrl);
const { wrappedIndexes, zhDictionary } = await fetchIndexes(
versionUrl,
searchContext
);
setSearchSource(() =>
SearchSourceFactory(wrappedIndexes, zhDictionary, 100)
);
}
doFetchIndexes();
}, [versionUrl]);
}, [searchContext, versionUrl]);

return (
<React.Fragment>
Expand Down
20 changes: 15 additions & 5 deletions docusaurus-search-local/src/client/theme/hooks/useSearchQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
import { useHistory, useLocation } from "@docusaurus/router";
import ExecutionEnvironment from "@docusaurus/ExecutionEnvironment";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import {
searchContextByPaths,
} from "../../utils/proxiedGenerated";

const SEARCH_PARAM_QUERY = "q";
const SEARCH_PARAM_CONTEXT = "ctx";

function useSearchQuery(): any {
const history = useHistory();
Expand All @@ -18,11 +22,13 @@ function useSearchQuery(): any {
siteConfig: { baseUrl },
} = useDocusaurusContext();

const params = ExecutionEnvironment.canUseDOM ? new URLSearchParams(location.search) : null;
const searchValue = params?.get(SEARCH_PARAM_QUERY) || "";
const searchContext = params?.get(SEARCH_PARAM_CONTEXT) || "";

return {
searchValue:
(ExecutionEnvironment.canUseDOM &&
new URLSearchParams(location.search).get(SEARCH_PARAM_QUERY)) ||
"",
searchValue,
searchContext,
updateSearchPath: (searchValue: string) => {
const searchParams = new URLSearchParams(location.search);

Expand All @@ -37,8 +43,12 @@ function useSearchQuery(): any {
});
},
generateSearchPageLink: (searchValue: string) => {
const searchParams = new URLSearchParams(location.search);
const searchContext = searchParams.get(SEARCH_PARAM_CONTEXT) || "";
// Refer to https://github.com/facebook/docusaurus/pull/2838
return `${baseUrl}search?q=${encodeURIComponent(searchValue)}`;
return `${baseUrl}search?q=${encodeURIComponent(searchValue)}${
Array.isArray(searchContextByPaths) ? `&ctx=${encodeURIComponent(searchContext)}` : ""
}`;
},
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export let language = ["en", "zh"];
export let removeDefaultStopWordFilter = false;
export let removeDefaultStemmer = false;
export const searchIndexUrl = "search-index.json?_=abc";
export const searchIndexUrl = "search-index{dir}.json?_=abc";
export const searchResultLimits = 8;
export const searchResultContextMaxLength = 50;
export const explicitSearchResultPath = false;
Expand Down
Loading

0 comments on commit 9ec0197

Please sign in to comment.