Added method to retrieve element or throw

This commit is contained in:
squidfunk 2020-02-14 09:52:22 +01:00
parent 718b51bac9
commit 8c92565b7b
6 changed files with 50 additions and 29 deletions

View File

@ -24,8 +24,7 @@ import { Observable, OperatorFunction, pipe } from "rxjs"
import {
distinctUntilKeyChanged,
shareReplay,
switchMap,
tap
switchMap
} from "rxjs/operators"
import {

View File

@ -32,7 +32,7 @@
* @param selector - Query selector
* @param node - Node of reference
*
* @return Element
* @return Element or nothing
*/
export function getElement<T extends HTMLElement>(
selector: string, node: ParentNode = document
@ -40,6 +40,38 @@ export function getElement<T extends HTMLElement>(
return node.querySelector<T>(selector) || undefined
}
/**
* Retrieve an element matching a query selector or throw a reference error
*
* @template T - Element type
*
* @param selector - Query selector
* @param node - Node of reference
*
* @return Element
*/
export function getElementOrThrow<T extends HTMLElement>(
selector: string, node: ParentNode = document
): T {
const el = getElement<T>(selector, node)
if (typeof el === "undefined")
throw new ReferenceError(
`Missing element: expected "${selector}" to match an element`
)
return el
}
/**
* Retrieve the currently active element
*
* @return Element
*/
export function getActiveElement(): HTMLElement | undefined {
return document.activeElement instanceof HTMLElement
? document.activeElement
: undefined
}
/**
* Retrieve all elements matching the query selector
*
@ -55,16 +87,3 @@ export function getElements<T extends HTMLElement>(
): T[] {
return Array.from(node.querySelectorAll<T>(selector))
}
/* ------------------------------------------------------------------------- */
/**
* Retrieve the currently active element
*
* @return Element
*/
export function getActiveElement(): HTMLElement | undefined {
return document.activeElement instanceof HTMLElement
? document.activeElement
: undefined
}

View File

@ -44,7 +44,10 @@ import {
setOverflowScrolling
} from "actions"
import { getElement } from "../../agent"
import {
getElement,
getElementOrThrow
} from "../../agent"
/* ----------------------------------------------------------------------------
* Types
@ -67,7 +70,7 @@ export interface NavigationLayer {
*
* On iOS we want to add `-webkit-overflow-scrolling: touch` for the menus
* contained in the drawer, but as the navigational layers are nested, we can
* only add it to the navigation layer or extremely weird cropping will occur.
* only add it to the topmost layer or extremely weird cropping will occur.
* This implementation keeps track of the previous and current layer.
*
* @param els - Navigation elements
@ -81,19 +84,19 @@ export function watchNavigationLayer(
for (const el of els) {
const label = getElement<HTMLLabelElement>("label", el)
if (typeof label !== "undefined") {
const input = getElement<HTMLInputElement>(`#${label.htmlFor}`)!
const input = getElementOrThrow<HTMLInputElement>(`#${label.htmlFor}`)
table.set(input, el)
}
}
/* Determine active layer */
/* Determine topmost layer */
const layer$ = merge(
...[...table.keys()].map(input => fromEvent(input, "change"))
)
.pipe(
map(() => getElement(".md-nav__list", table.get(
map(() => getElementOrThrow(".md-nav__list", table.get(
findLast(({ checked }) => checked, [...table.keys()])!
))!)
)))
)
/* Return previous and next layer */
@ -139,7 +142,7 @@ export function paintNavigationLayer(
finalize(() => {
for (const el of els)
resetOverflowScrolling(
getElement(".md-nav__list", el)!
getElementOrThrow(".md-nav__list", el)
)
})
)

View File

@ -45,7 +45,7 @@ import {
import { SearchResult } from "modules"
import { renderSearchResult } from "templates"
import { getElement } from "../../agent"
import { getElementOrThrow } from "../../agent"
import { SearchQuery } from "../query"
/* ----------------------------------------------------------------------------
@ -75,8 +75,8 @@ interface PaintOptions {
export function paintSearchResult(
el: HTMLElement, { query$, fetch$ }: PaintOptions
): MonoTypeOperatorFunction<SearchResult[]> {
const list = getElement(".md-search-result__list", el)!
const meta = getElement(".md-search-result__meta", el)!
const list = getElementOrThrow(".md-search-result__list", el)
const meta = getElementOrThrow(".md-search-result__meta", el)
return pipe(
/* Paint search result metadata */

View File

@ -20,7 +20,7 @@
* IN THE SOFTWARE.
*/
import { getElement } from "observables"
import { getElementOrThrow } from "observables"
/* ----------------------------------------------------------------------------
* Data
@ -45,7 +45,7 @@ let lang: Record<string, string>
*/
export function translate(key: string, value?: string): string {
if (typeof lang === "undefined") {
const el = getElement("#__lang")!
const el = getElementOrThrow("#__lang")
lang = JSON.parse(el.innerText)
}
if (typeof lang[key] === "undefined") {

View File

@ -301,7 +301,7 @@ $codehilite-whitespace: transparent;
// When pymdownx.superfences is enabled but codehilite is disabled,
// pymdownx.highlight will be used. When this happens, the outer
// container and tables get this class names by default.
// container and tables get this class names by default
.highlight {
@extend .codehilite;
}