mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Refactored location observables
This commit is contained in:
parent
74b02ad382
commit
ae05805124
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
material/assets/javascripts/bundle.4120b2e2.min.js.map
Normal file
1
material/assets/javascripts/bundle.4120b2e2.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"assets/javascripts/bundle.js": "assets/javascripts/bundle.0e463231.min.js",
|
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4120b2e2.min.js",
|
||||||
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.0e463231.min.js.map",
|
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4120b2e2.min.js.map",
|
||||||
"assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js",
|
"assets/javascripts/worker/packer.js": "assets/javascripts/worker/packer.c14659e8.min.js",
|
||||||
"assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map",
|
"assets/javascripts/worker/packer.js.map": "assets/javascripts/worker/packer.c14659e8.min.js.map",
|
||||||
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.0a5433f7.min.js",
|
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.0a5433f7.min.js",
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ 'assets/javascripts/bundle.0e463231.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/bundle.4120b2e2.min.js' | url }}"></script>
|
||||||
<script id="__lang" type="application/json">
|
<script id="__lang" type="application/json">
|
||||||
{%- set translations = {} -%}
|
{%- set translations = {} -%}
|
||||||
{%- for key in [
|
{%- for key in [
|
||||||
|
@ -148,10 +148,10 @@ export function useComponent<T extends HTMLElement>(
|
|||||||
): Observable<T> {
|
): Observable<T> {
|
||||||
return components$
|
return components$
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap(components => {
|
switchMap(components => (
|
||||||
return typeof components[name] !== "undefined"
|
typeof components[name] !== "undefined"
|
||||||
? of(components[name] as T)
|
? of(components[name] as T)
|
||||||
: NEVER
|
: NEVER
|
||||||
})
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ export function mountSearch(
|
|||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
|
|
||||||
/* Mount search reset */
|
/* Mount search reset */
|
||||||
const reset$ = useComponent<HTMLInputElement>("search-reset")
|
const reset$ = useComponent("search-reset")
|
||||||
.pipe(
|
.pipe(
|
||||||
mountSearchReset()
|
mountSearchReset()
|
||||||
)
|
)
|
||||||
|
56
src/assets/javascripts/observables/agent/location/_/index.ts
Normal file
56
src/assets/javascripts/observables/agent/location/_/index.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Subject, fromEvent } from "rxjs"
|
||||||
|
import { map } from "rxjs/operators"
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Functions
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve location
|
||||||
|
*
|
||||||
|
* @return Location
|
||||||
|
*/
|
||||||
|
export function getLocation(): string {
|
||||||
|
return location.href
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch location
|
||||||
|
*
|
||||||
|
* @return Location subject
|
||||||
|
*/
|
||||||
|
export function watchLocation(): Subject<string> {
|
||||||
|
const location$ = new Subject<string>()
|
||||||
|
fromEvent<PopStateEvent>(window, "popstate")
|
||||||
|
.pipe(
|
||||||
|
map(getLocation)
|
||||||
|
)
|
||||||
|
.subscribe(location$)
|
||||||
|
|
||||||
|
/* Return subject */
|
||||||
|
return location$
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Observable, fromEvent } from "rxjs"
|
||||||
|
import { filter, map, share } from "rxjs/operators"
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Functions
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve location hash
|
||||||
|
*
|
||||||
|
* @return Location hash
|
||||||
|
*/
|
||||||
|
export function getLocationHash(): string {
|
||||||
|
return location.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set location hash
|
||||||
|
*
|
||||||
|
* This will force a reset of the location hash, inducing an anchor jump if
|
||||||
|
* the hash matches the `id` of an element. It is implemented outside of the
|
||||||
|
* whole RxJS architecture using `setTimeout` to keep it plain and simple.
|
||||||
|
*
|
||||||
|
* @param value - Location hash
|
||||||
|
*/
|
||||||
|
export function setLocationHash(value: string): void {
|
||||||
|
location.hash = ""
|
||||||
|
setTimeout(() => {
|
||||||
|
location.hash = value
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch location hash
|
||||||
|
*
|
||||||
|
* @return Location hash observable
|
||||||
|
*/
|
||||||
|
export function watchLocationHash(): Observable<string> {
|
||||||
|
return fromEvent<HashChangeEvent>(window, "hashchange")
|
||||||
|
.pipe(
|
||||||
|
map(getLocationHash),
|
||||||
|
filter(hash => hash.length > 0),
|
||||||
|
share()
|
||||||
|
)
|
||||||
|
}
|
@ -20,40 +20,5 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Observable, Subject, fromEvent } from "rxjs"
|
export * from "./_"
|
||||||
import { filter, map, share } from "rxjs/operators"
|
export * from "./hash"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* Functions
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Watch location
|
|
||||||
*
|
|
||||||
* @return Location subject
|
|
||||||
*/
|
|
||||||
export function watchLocation(): Subject<string> {
|
|
||||||
const location$ = new Subject<string>()
|
|
||||||
fromEvent<PopStateEvent>(window, "popstate")
|
|
||||||
.pipe(
|
|
||||||
map(() => location.href)
|
|
||||||
)
|
|
||||||
.subscribe(location$)
|
|
||||||
|
|
||||||
/* Return subject */
|
|
||||||
return location$
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Watch location hash
|
|
||||||
*
|
|
||||||
* @return Location hash observable
|
|
||||||
*/
|
|
||||||
export function watchLocationHash(): Observable<string> {
|
|
||||||
return fromEvent<HashChangeEvent>(window, "hashchange")
|
|
||||||
.pipe(
|
|
||||||
map(() => location.hash),
|
|
||||||
filter(hash => hash.length > 0),
|
|
||||||
share()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
@ -52,7 +52,7 @@ export function getViewportOffset(): ViewportOffset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve viewport offset
|
* Set viewport offset
|
||||||
*
|
*
|
||||||
* @param offset - Viewport offset
|
* @param offset - Viewport offset
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Observable, Subject, fromEvent, fromEventPattern } from "rxjs"
|
import { Observable, Subject, fromEventPattern } from "rxjs"
|
||||||
import {
|
import {
|
||||||
pluck,
|
pluck,
|
||||||
share,
|
share,
|
||||||
|
@ -26,8 +26,7 @@ import {
|
|||||||
distinctUntilChanged,
|
distinctUntilChanged,
|
||||||
map,
|
map,
|
||||||
shareReplay,
|
shareReplay,
|
||||||
startWith,
|
startWith
|
||||||
tap
|
|
||||||
} from "rxjs/operators"
|
} from "rxjs/operators"
|
||||||
|
|
||||||
import { watchElementFocus } from "../../agent"
|
import { watchElementFocus } from "../../agent"
|
||||||
@ -92,8 +91,9 @@ function defaultTransform(value: string): string {
|
|||||||
* @return Search query observable
|
* @return Search query observable
|
||||||
*/
|
*/
|
||||||
export function watchSearchQuery(
|
export function watchSearchQuery(
|
||||||
el: HTMLInputElement, { transform = defaultTransform }: WatchOptions = {}
|
el: HTMLInputElement, { transform }: WatchOptions = {}
|
||||||
): Observable<SearchQuery> {
|
): Observable<SearchQuery> {
|
||||||
|
const fn = transform || defaultTransform
|
||||||
|
|
||||||
/* Intercept keyboard events */
|
/* Intercept keyboard events */
|
||||||
const value$ = merge(
|
const value$ = merge(
|
||||||
@ -101,8 +101,8 @@ export function watchSearchQuery(
|
|||||||
fromEvent(el, "focus").pipe(delay(1))
|
fromEvent(el, "focus").pipe(delay(1))
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
map(() => transform(el.value)),
|
map(() => fn(el.value)),
|
||||||
startWith(transform(el.value)),
|
startWith(fn(el.value)),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -121,11 +121,11 @@ export function useToggle(
|
|||||||
): Observable<HTMLInputElement> {
|
): Observable<HTMLInputElement> {
|
||||||
return toggles$
|
return toggles$
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap(toggles => {
|
switchMap(toggles => (
|
||||||
return typeof toggles[name] !== "undefined"
|
typeof toggles[name] !== "undefined"
|
||||||
? of(toggles[name]!)
|
? of(toggles[name]!)
|
||||||
: NEVER
|
: NEVER
|
||||||
})
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,24 +21,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { identity } from "ramda"
|
import { identity } from "ramda"
|
||||||
|
import { NEVER, Observable, fromEvent, merge, of } from "rxjs"
|
||||||
import {
|
import {
|
||||||
Observable,
|
catchError,
|
||||||
animationFrameScheduler,
|
|
||||||
fromEvent,
|
|
||||||
merge,
|
|
||||||
of
|
|
||||||
} from "rxjs"
|
|
||||||
import {
|
|
||||||
filter,
|
filter,
|
||||||
map,
|
map,
|
||||||
mapTo,
|
|
||||||
observeOn,
|
|
||||||
switchMap,
|
switchMap,
|
||||||
switchMapTo,
|
switchMapTo,
|
||||||
tap
|
|
||||||
} from "rxjs/operators"
|
} from "rxjs/operators"
|
||||||
|
|
||||||
import { getElement, getElements, watchMedia } from "observables"
|
import {
|
||||||
|
getElementOrThrow,
|
||||||
|
getElements,
|
||||||
|
getLocationHash,
|
||||||
|
setLocationHash,
|
||||||
|
watchMedia
|
||||||
|
} from "observables"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Helper types
|
* Helper types
|
||||||
@ -86,27 +84,20 @@ export function patchDetails(
|
|||||||
})
|
})
|
||||||
|
|
||||||
/* Open parent details before anchor jump */
|
/* Open parent details before anchor jump */
|
||||||
merge(hash$, of(location.hash))
|
merge(hash$, of(getLocationHash()))
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(hash => !!hash.length),
|
filter(hash => !!hash.length),
|
||||||
switchMap(hash => of(getElement<HTMLElement>(hash) || document.body)
|
switchMap(hash => of(getElementOrThrow<HTMLElement>(hash))
|
||||||
.pipe(
|
.pipe(
|
||||||
map(el => el.closest("details")!),
|
map(el => el.closest("details")!),
|
||||||
filter(el => el && !el.open),
|
filter(el => el && !el.open),
|
||||||
|
map(el => [el, hash] as const)
|
||||||
/* Open details and temporarily reset anchor */
|
)
|
||||||
tap(el => {
|
),
|
||||||
|
catchError(() => NEVER)
|
||||||
|
)
|
||||||
|
.subscribe(([el, hash]) => {
|
||||||
el.setAttribute("open", "")
|
el.setAttribute("open", "")
|
||||||
location.hash = ""
|
setLocationHash(hash)
|
||||||
}),
|
|
||||||
|
|
||||||
/* Defer anchor jump to next animation frame */
|
|
||||||
observeOn(animationFrameScheduler),
|
|
||||||
mapTo(hash)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subscribe(hash => {
|
|
||||||
location.hash = hash
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,11 @@ import { ajax } from "rxjs/ajax"
|
|||||||
import { map, pluck } from "rxjs/operators"
|
import { map, pluck } from "rxjs/operators"
|
||||||
|
|
||||||
import { SearchIndexOptions } from "integrations/search"
|
import { SearchIndexOptions } from "integrations/search"
|
||||||
import { WorkerHandler, watchWorker } from "observables"
|
import {
|
||||||
|
WorkerHandler,
|
||||||
|
getLocation,
|
||||||
|
watchWorker
|
||||||
|
} from "observables"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SearchMessage,
|
SearchMessage,
|
||||||
@ -83,7 +87,7 @@ export function setupSearchWorker(
|
|||||||
url: string, { base, index }: SetupOptions
|
url: string, { base, index }: SetupOptions
|
||||||
): WorkerHandler<SearchMessage> {
|
): WorkerHandler<SearchMessage> {
|
||||||
const worker = new Worker(url)
|
const worker = new Worker(url)
|
||||||
const prefix = new URL(base, location.href)
|
const prefix = new URL(base, getLocation())
|
||||||
|
|
||||||
/* Create communication channels and resolve relative links */
|
/* Create communication channels and resolve relative links */
|
||||||
const tx$ = new Subject<SearchMessage>()
|
const tx$ = new Subject<SearchMessage>()
|
||||||
|
Loading…
Reference in New Issue
Block a user