mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-08-01 02:08:46 -04:00
Formatting + moved search index fetching to top level
This commit is contained in:
@@ -61,6 +61,32 @@ export type Component<
|
||||
ref: U /* Component reference */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper types
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Component type map
|
||||
*/
|
||||
interface ComponentTypeMap {
|
||||
"announce": HTMLElement /* Announcement bar */
|
||||
"container": HTMLElement /* Container */
|
||||
"content": HTMLElement /* Content */
|
||||
"dialog": HTMLElement /* Dialog */
|
||||
"header": HTMLElement /* Header */
|
||||
"header-title": HTMLElement /* Header title */
|
||||
"header-topic": HTMLElement /* Header topic */
|
||||
"main": HTMLElement /* Main area */
|
||||
"search": HTMLElement /* Search */
|
||||
"search-query": HTMLInputElement /* Search input */
|
||||
"search-result": HTMLElement /* Search results */
|
||||
"sidebar": HTMLElement /* Sidebar */
|
||||
"skip": HTMLAnchorElement /* Skip link */
|
||||
"source": HTMLAnchorElement /* Repository information */
|
||||
"tabs": HTMLElement /* Navigation tabs */
|
||||
"toc": HTMLElement /* Table of contents */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@@ -68,31 +94,31 @@ export type Component<
|
||||
/**
|
||||
* Retrieve the element for a given component or throw a reference error
|
||||
*
|
||||
* @template T - Element type
|
||||
* @template T - Component type
|
||||
*
|
||||
* @param type - Component type
|
||||
* @param node - Node of reference
|
||||
*
|
||||
* @returns Element
|
||||
*/
|
||||
export function getComponentElement<T extends HTMLElement>(
|
||||
type: ComponentType, node: ParentNode = document
|
||||
): T {
|
||||
export function getComponentElement<T extends ComponentType>(
|
||||
type: T, node: ParentNode = document
|
||||
): ComponentTypeMap[T] {
|
||||
return getElementOrThrow(`[data-md-component=${type}]`, node)
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all elements for a given component
|
||||
*
|
||||
* @template T - Element type
|
||||
* @template T - Component type
|
||||
*
|
||||
* @param type - Component type
|
||||
* @param node - Node of reference
|
||||
*
|
||||
* @returns Elements
|
||||
*/
|
||||
export function getComponentElements<T extends HTMLElement>(
|
||||
type: ComponentType, node: ParentNode = document
|
||||
): T[] {
|
||||
export function getComponentElements<T extends ComponentType>(
|
||||
type: T, node: ParentNode = document
|
||||
): ComponentTypeMap[T][] {
|
||||
return getElements(`[data-md-component=${type}]`, node)
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ let index = 0
|
||||
/**
|
||||
* Watch code block
|
||||
*
|
||||
* This function will monitor size changes of the viewport, as well as switches
|
||||
* of content tabs with embedded code blocks, as both may trigger overflow.
|
||||
* This function monitors size changes of the viewport, as well as switches of
|
||||
* content tabs with embedded code blocks, as both may trigger overflow.
|
||||
*
|
||||
* @param el - Code block element
|
||||
* @param options - Options
|
||||
@@ -163,7 +163,7 @@ export function mountCodeBlock(
|
||||
resetFocusable(el)
|
||||
})
|
||||
|
||||
/* Inject button for Clipboard.js integration */
|
||||
/* Render button for Clipboard.js integration */
|
||||
if (ClipboardJS.isSupported()) {
|
||||
const parent = el.closest("pre")!
|
||||
parent.id = `__code_${index++}`
|
||||
|
||||
@@ -52,8 +52,8 @@ const sentinel = createElement("table")
|
||||
/**
|
||||
* Mount data table
|
||||
*
|
||||
* This function wraps a data table in another scrollable container, so they
|
||||
* can be scrolled on smaller screen sizes and won't break the layout.
|
||||
* This function wraps a data table in another scrollable container, so it can
|
||||
* be smoothly scrolled on smaller screen sizes and won't break the layout.
|
||||
*
|
||||
* @param el - Data table element
|
||||
*
|
||||
|
||||
@@ -105,8 +105,8 @@ export function watchDialog(
|
||||
/**
|
||||
* Mount dialog
|
||||
*
|
||||
* This function makes the dialog in the right corner appear when a new alert
|
||||
* is emitted through the subject that is passed as part of the options.
|
||||
* This function reveals the dialog in the right cornerwhen a new alert is
|
||||
* emitted through the subject that is passed as part of the options.
|
||||
*
|
||||
* @param el - Dialog element
|
||||
* @param options - Options
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
Keyboard,
|
||||
getActiveElement,
|
||||
getElements,
|
||||
requestJSON,
|
||||
setElementFocus,
|
||||
setElementSelection,
|
||||
setToggle
|
||||
@@ -63,24 +62,10 @@ export type Search =
|
||||
* Mount options
|
||||
*/
|
||||
interface MountOptions {
|
||||
index$: ObservableInput<SearchIndex> /* Search index observable */
|
||||
keyboard$: Observable<Keyboard> /* Keyboard observable */
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Helper functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Fetch search index
|
||||
*
|
||||
* @param url - Search index URL
|
||||
*
|
||||
* @returns Promise or observable
|
||||
*/
|
||||
function fetchSearchIndex(url: string): ObservableInput<SearchIndex> {
|
||||
return __search?.index || requestJSON<SearchIndex>(url)
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* Functions
|
||||
* ------------------------------------------------------------------------- */
|
||||
@@ -97,16 +82,14 @@ function fetchSearchIndex(url: string): ObservableInput<SearchIndex> {
|
||||
* @returns Search component observable
|
||||
*/
|
||||
export function mountSearch(
|
||||
el: HTMLElement, { keyboard$ }: MountOptions
|
||||
el: HTMLElement, { index$, keyboard$ }: MountOptions
|
||||
): Observable<Component<Search>> {
|
||||
if (location.protocol === "file:")
|
||||
return NEVER
|
||||
|
||||
/* Set up search worker */
|
||||
const config = configuration()
|
||||
const worker = setupSearchWorker(config.search, fetchSearchIndex(
|
||||
`${config.base}/search/search_index.json`
|
||||
))
|
||||
const worker = setupSearchWorker(config.search, index$)
|
||||
|
||||
/* Retrieve nested components */
|
||||
const query = getComponentElement("search-query", el)
|
||||
@@ -193,7 +176,7 @@ export function mountSearch(
|
||||
})
|
||||
|
||||
/* Create and return component */
|
||||
const query$ = mountSearchQuery(query as HTMLInputElement, worker)
|
||||
const query$ = mountSearchQuery(query, worker)
|
||||
return merge(
|
||||
query$,
|
||||
mountSearchResult(result, worker, { query$ })
|
||||
|
||||
@@ -33,7 +33,6 @@ import {
|
||||
distinctUntilKeyChanged,
|
||||
finalize,
|
||||
map,
|
||||
startWith,
|
||||
takeLast,
|
||||
takeUntil,
|
||||
tap
|
||||
@@ -96,7 +95,6 @@ export function watchSearchQuery(
|
||||
)
|
||||
.pipe(
|
||||
map(() => fn(el.value)),
|
||||
startWith(fn(el.value)),
|
||||
distinctUntilChanged()
|
||||
)
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ interface MountOptions {
|
||||
/**
|
||||
* Mount search result list
|
||||
*
|
||||
* This function will perform a lazy rendering of the search results, depending
|
||||
* on the vertical offset of the search result container.
|
||||
* This function performs a lazy rendering of the search results, depending on
|
||||
* the vertical offset of the search result container.
|
||||
*
|
||||
* @param el - Search result list element
|
||||
* @param worker - Search worker
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
|
||||
import { setSourceFacts, setSourceState } from "~/actions"
|
||||
import { renderSourceFacts } from "~/templates"
|
||||
import { hash } from "~/utilities"
|
||||
import { digest } from "~/utilities"
|
||||
|
||||
import { Component } from "../../_"
|
||||
import { SourceFacts, fetchSourceFacts } from "../facts"
|
||||
@@ -53,7 +53,7 @@ export interface Source {
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Repository facts observable
|
||||
* Repository information observable
|
||||
*/
|
||||
let fetch$: Observable<Source>
|
||||
|
||||
@@ -64,8 +64,8 @@ let fetch$: Observable<Source>
|
||||
/**
|
||||
* Watch repository information
|
||||
*
|
||||
* This function will try to read the repository facts from session storage,
|
||||
* and if unsuccessful, fetch them from the underlying provider.
|
||||
* This function tries to read the repository facts from session storage, and
|
||||
* if unsuccessful, fetches them from the underlying provider.
|
||||
*
|
||||
* @param el - Repository information element
|
||||
*
|
||||
@@ -74,18 +74,15 @@ let fetch$: Observable<Source>
|
||||
export function watchSource(
|
||||
el: HTMLAnchorElement
|
||||
): Observable<Source> {
|
||||
const digest = hash(el.href).toString()
|
||||
|
||||
/* Fetch repository facts once */
|
||||
return fetch$ ||= defer(() => {
|
||||
const data = sessionStorage.getItem(digest)
|
||||
const data = sessionStorage.getItem(digest("__repo"))
|
||||
if (data) {
|
||||
return of(JSON.parse(data))
|
||||
return of<SourceFacts>(JSON.parse(data))
|
||||
} else {
|
||||
const value$ = fetchSourceFacts(el.href)
|
||||
value$.subscribe(value => {
|
||||
try {
|
||||
sessionStorage.setItem(digest, JSON.stringify(value))
|
||||
sessionStorage.setItem(digest("__repo"), JSON.stringify(value))
|
||||
} catch (err) {
|
||||
/* Uncritical, just swallow */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user