Fixed search for use_directory_urls: false

This commit is contained in:
squidfunk
2020-02-29 10:47:01 +01:00
parent ff9ef6a4a7
commit 68c9cb6dac
9 changed files with 49 additions and 45 deletions

View File

@@ -52,7 +52,8 @@ import {
debounceTime,
distinctUntilKeyChanged,
distinctUntilChanged,
bufferCount
bufferCount,
startWith
} from "rxjs/operators"
import {
@@ -68,7 +69,8 @@ import {
useToggle,
getElement,
setViewportOffset,
ViewportOffset
ViewportOffset,
getLocation
} from "./observables"
import { setupSearchWorker } from "./workers"
@@ -158,7 +160,7 @@ export function initialize(config: unknown) {
/* ----------------------------------------------------------------------- */
const worker = setupSearchWorker(config.worker.search, {
base: config.base
base: config.base, location$
})
/* ----------------------------------------------------------------------- */

View File

@@ -28,11 +28,10 @@ import {
pluck,
share,
skip,
startWith,
switchMap
} from "rxjs/operators"
import { getLocation, setLocation } from "../../location"
import { setLocation } from "../../location"
/* ----------------------------------------------------------------------------
* Helper types
@@ -52,7 +51,7 @@ interface WatchOptions {
/**
* Watch document switch
*
* This function returns an observables that fetches a document if the provided // TODO: update docs
* This function returns an observables that fetches a document if the provided
* location observable emits a new value (i.e. URL). If the emitted URL points
* to the same page, the request is effectively ignored (i.e. when only the
* fragment identifier changes).
@@ -68,7 +67,6 @@ export function watchDocumentSwitch(
): Observable<Document> {
return location$
.pipe(
startWith(getLocation()),
distinctUntilKeyChanged("pathname"),
skip(1),

View File

@@ -20,7 +20,7 @@
* IN THE SOFTWARE.
*/
import { Subject } from "rxjs"
import { BehaviorSubject } from "rxjs"
/* ----------------------------------------------------------------------------
* Functions
@@ -56,6 +56,6 @@ export function setLocation(url: URL): void {
*
* @return Location subject
*/
export function watchLocation(): Subject<URL> {
return new Subject<URL>()
export function watchLocation(): BehaviorSubject<URL> {
return new BehaviorSubject<URL>(getLocation())
}

View File

@@ -20,14 +20,19 @@
* IN THE SOFTWARE.
*/
import { Subject, Subscriber, from, fromEvent } from "rxjs"
import { Observable, Subject, from } from "rxjs"
import { ajax } from "rxjs/ajax"
import { map, pluck, shareReplay } from "rxjs/operators"
import {
map,
pluck,
shareReplay,
take,
withLatestFrom
} from "rxjs/operators"
import { SearchIndexOptions } from "integrations/search"
import {
WorkerHandler,
getLocation,
watchWorker
} from "observables"
@@ -48,26 +53,7 @@ import {
interface SetupOptions {
base: string /* Base url */
index?: Promise<SearchIndexOptions> /* Promise resolving with index */
}
/* ----------------------------------------------------------------------------
* Helper functions
* ------------------------------------------------------------------------- */
/**
* Resolve URL
* * TODO: document what's going on here + cache results
*
* @param origin - Base URL
* @param paths - Further URL paths
*
* @return Relative URL
*/
function resolve(origin: URL, ...paths: string[]) {
const path = location.pathname
.replace(origin.pathname, "")
.replace(/[^\/]+/g, "..")
return [path, ...paths].join("")
location$: Observable<URL> /* Location observable */
}
/* ----------------------------------------------------------------------------
@@ -88,21 +74,39 @@ function resolve(origin: URL, ...paths: string[]) {
* @return Worker handler
*/
export function setupSearchWorker(
url: string, { base, index }: SetupOptions
url: string, { base, index, location$ }: SetupOptions
): WorkerHandler<SearchMessage> {
const worker = new Worker(url)
const origin = new URL(base, getLocation())
/* Compute new base URL when location changes */
const origin$ = location$
.pipe(
withLatestFrom(location$
.pipe(
take(1),
map(({ href }) => new URL(base, href))
)
),
map(([location, origin]) => location.href
.replace(origin.href, "")
.split("/")
.slice(1)
.map(() => "..")
.join("/")
)
)
/* Create communication channels and resolve relative links */
const tx$ = new Subject<SearchMessage>()
const rx$ = watchWorker(worker, { tx$ })
.pipe(
map(message => {
withLatestFrom(origin$),
map(([message, origin]) => {
if (isSearchResultMessage(message)) {
for (const { article, sections } of message.data) {
article.location = resolve(origin, article.location)
article.location = `${origin}/${article.location}`
for (const section of sections)
section.location = resolve(origin, section.location)
section.location = `${origin}/${section.location}`
}
}
return message
@@ -114,7 +118,7 @@ export function setupSearchWorker(
const index$ = typeof index !== "undefined"
? from(index)
: ajax({
url: resolve(origin, "search/search_index.json"),
url: `${base}/search/search_index.json`,
responseType: "json",
withCredentials: true
})