mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Improved graceful handling of broken search when browsing locally
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -223,7 +223,7 @@
|
|||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ 'assets/javascripts/bundle.d7b0ad22.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/bundle.ddd52ceb.min.js' | url }}"></script>
|
||||||
{% for path in config["extra_javascript"] %}
|
{% for path in config["extra_javascript"] %}
|
||||||
<script src="{{ path | url }}"></script>
|
<script src="{{ path | url }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export function resetBackToTopState(
|
|||||||
* @param el - Back-to-top element
|
* @param el - Back-to-top element
|
||||||
* @param value - Back-to-top offset
|
* @param value - Back-to-top offset
|
||||||
*/
|
*/
|
||||||
export function setBackToTopOffset(
|
export function setBackToTopOffset(
|
||||||
el: HTMLElement, value: number
|
el: HTMLElement, value: number
|
||||||
): void {
|
): void {
|
||||||
el.style.top = `${value}px`
|
el.style.top = `${value}px`
|
||||||
|
|||||||
@@ -85,96 +85,103 @@ export function mountSearch(
|
|||||||
el: HTMLElement, { index$, keyboard$ }: MountOptions
|
el: HTMLElement, { index$, keyboard$ }: MountOptions
|
||||||
): Observable<Component<Search>> {
|
): Observable<Component<Search>> {
|
||||||
const config = configuration()
|
const config = configuration()
|
||||||
const worker = setupSearchWorker(config.search, index$)
|
try {
|
||||||
|
const worker = setupSearchWorker(config.search, index$)
|
||||||
|
|
||||||
/* Retrieve nested components */
|
/* Retrieve nested components */
|
||||||
const query = getComponentElement("search-query", el)
|
const query = getComponentElement("search-query", el)
|
||||||
const result = getComponentElement("search-result", el)
|
const result = getComponentElement("search-result", el)
|
||||||
|
|
||||||
/* Re-emit query when search is ready */
|
/* Re-emit query when search is ready */
|
||||||
const { tx$, rx$ } = worker
|
const { tx$, rx$ } = worker
|
||||||
tx$
|
tx$
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(isSearchQueryMessage),
|
filter(isSearchQueryMessage),
|
||||||
sample(rx$.pipe(filter(isSearchReadyMessage))),
|
sample(rx$.pipe(filter(isSearchReadyMessage))),
|
||||||
take(1)
|
take(1)
|
||||||
)
|
)
|
||||||
.subscribe(tx$.next.bind(tx$))
|
.subscribe(tx$.next.bind(tx$))
|
||||||
|
|
||||||
/* Set up search keyboard handlers */
|
/* Set up search keyboard handlers */
|
||||||
keyboard$
|
keyboard$
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(({ mode }) => mode === "search")
|
filter(({ mode }) => mode === "search")
|
||||||
)
|
)
|
||||||
.subscribe(key => {
|
.subscribe(key => {
|
||||||
const active = getActiveElement()
|
const active = getActiveElement()
|
||||||
switch (key.type) {
|
switch (key.type) {
|
||||||
|
|
||||||
/* Enter: prevent form submission */
|
/* Enter: prevent form submission */
|
||||||
case "Enter":
|
case "Enter":
|
||||||
if (active === query)
|
if (active === query)
|
||||||
|
key.claim()
|
||||||
|
break
|
||||||
|
|
||||||
|
/* Escape or Tab: close search */
|
||||||
|
case "Escape":
|
||||||
|
case "Tab":
|
||||||
|
setToggle("search", false)
|
||||||
|
setElementFocus(query, false)
|
||||||
|
break
|
||||||
|
|
||||||
|
/* Vertical arrows: select previous or next search result */
|
||||||
|
case "ArrowUp":
|
||||||
|
case "ArrowDown":
|
||||||
|
if (typeof active === "undefined") {
|
||||||
|
setElementFocus(query)
|
||||||
|
} else {
|
||||||
|
const els = [query, ...getElements(
|
||||||
|
":not(details) > [href], summary, details[open] [href]",
|
||||||
|
result
|
||||||
|
)]
|
||||||
|
const i = Math.max(0, (
|
||||||
|
Math.max(0, els.indexOf(active)) + els.length + (
|
||||||
|
key.type === "ArrowUp" ? -1 : +1
|
||||||
|
)
|
||||||
|
) % els.length)
|
||||||
|
setElementFocus(els[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent scrolling of page */
|
||||||
key.claim()
|
key.claim()
|
||||||
break
|
break
|
||||||
|
|
||||||
/* Escape or Tab: close search */
|
/* All other keys: hand to search query */
|
||||||
case "Escape":
|
default:
|
||||||
case "Tab":
|
if (query !== getActiveElement())
|
||||||
setToggle("search", false)
|
setElementFocus(query)
|
||||||
setElementFocus(query, false)
|
}
|
||||||
break
|
})
|
||||||
|
|
||||||
/* Vertical arrows: select previous or next search result */
|
/* Set up global keyboard handlers */
|
||||||
case "ArrowUp":
|
keyboard$
|
||||||
case "ArrowDown":
|
.pipe(
|
||||||
if (typeof active === "undefined") {
|
filter(({ mode }) => mode === "global"),
|
||||||
|
)
|
||||||
|
.subscribe(key => {
|
||||||
|
switch (key.type) {
|
||||||
|
|
||||||
|
/* Open search and select query */
|
||||||
|
case "f":
|
||||||
|
case "s":
|
||||||
|
case "/":
|
||||||
setElementFocus(query)
|
setElementFocus(query)
|
||||||
} else {
|
setElementSelection(query)
|
||||||
const els = [query, ...getElements(
|
key.claim()
|
||||||
":not(details) > [href], summary, details[open] [href]",
|
break
|
||||||
result
|
}
|
||||||
)]
|
})
|
||||||
const i = Math.max(0, (
|
|
||||||
Math.max(0, els.indexOf(active)) + els.length + (
|
|
||||||
key.type === "ArrowUp" ? -1 : +1
|
|
||||||
)
|
|
||||||
) % els.length)
|
|
||||||
setElementFocus(els[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prevent scrolling of page */
|
/* Create and return component */
|
||||||
key.claim()
|
const query$ = mountSearchQuery(query, worker)
|
||||||
break
|
return merge(
|
||||||
|
query$,
|
||||||
/* All other keys: hand to search query */
|
mountSearchResult(result, worker, { query$ })
|
||||||
default:
|
|
||||||
if (query !== getActiveElement())
|
|
||||||
setElementFocus(query)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Set up global keyboard handlers */
|
|
||||||
keyboard$
|
|
||||||
.pipe(
|
|
||||||
filter(({ mode }) => mode === "global"),
|
|
||||||
)
|
)
|
||||||
.subscribe(key => {
|
|
||||||
switch (key.type) {
|
|
||||||
|
|
||||||
/* Open search and select query */
|
/* Gracefully handle broken search */
|
||||||
case "f":
|
} catch (err) {
|
||||||
case "s":
|
el.hidden = true
|
||||||
case "/":
|
return NEVER
|
||||||
setElementFocus(query)
|
}
|
||||||
setElementSelection(query)
|
|
||||||
key.claim()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/* Create and return component */
|
|
||||||
const query$ = mountSearchQuery(query, worker)
|
|
||||||
return merge(
|
|
||||||
query$,
|
|
||||||
mountSearchResult(result, worker, { query$ })
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user