diff --git a/src/assets/javascripts/components2/main/index.ts b/src/assets/javascripts/components2/main/index.ts index be8876c4b..3fa3c0926 100644 --- a/src/assets/javascripts/components2/main/index.ts +++ b/src/assets/javascripts/components2/main/index.ts @@ -24,8 +24,7 @@ import { Observable, OperatorFunction, pipe } from "rxjs" import { distinctUntilKeyChanged, shareReplay, - switchMap, - tap + switchMap } from "rxjs/operators" import { diff --git a/src/assets/javascripts/observables/agent/element/_/index.ts b/src/assets/javascripts/observables/agent/element/_/index.ts index fc91c8b6a..c0fedac50 100644 --- a/src/assets/javascripts/observables/agent/element/_/index.ts +++ b/src/assets/javascripts/observables/agent/element/_/index.ts @@ -32,7 +32,7 @@ * @param selector - Query selector * @param node - Node of reference * - * @return Element + * @return Element or nothing */ export function getElement( selector: string, node: ParentNode = document @@ -40,6 +40,38 @@ export function getElement( return node.querySelector(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( + selector: string, node: ParentNode = document +): T { + const el = getElement(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[] { return Array.from(node.querySelectorAll(selector)) } - -/* ------------------------------------------------------------------------- */ - -/** - * Retrieve the currently active element - * - * @return Element - */ -export function getActiveElement(): HTMLElement | undefined { - return document.activeElement instanceof HTMLElement - ? document.activeElement - : undefined -} diff --git a/src/assets/javascripts/observables/navigation/layer/index.ts b/src/assets/javascripts/observables/navigation/layer/index.ts index b5b49fd74..56944d565 100644 --- a/src/assets/javascripts/observables/navigation/layer/index.ts +++ b/src/assets/javascripts/observables/navigation/layer/index.ts @@ -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("label", el) if (typeof label !== "undefined") { - const input = getElement(`#${label.htmlFor}`)! + const input = getElementOrThrow(`#${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) ) }) ) diff --git a/src/assets/javascripts/observables/search/result/index.ts b/src/assets/javascripts/observables/search/result/index.ts index 97edf19e7..410f4bbcb 100644 --- a/src/assets/javascripts/observables/search/result/index.ts +++ b/src/assets/javascripts/observables/search/result/index.ts @@ -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 { - 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 */ diff --git a/src/assets/javascripts/utilities/string/index.ts b/src/assets/javascripts/utilities/string/index.ts index 46fc48f19..bfd47a2d9 100644 --- a/src/assets/javascripts/utilities/string/index.ts +++ b/src/assets/javascripts/utilities/string/index.ts @@ -20,7 +20,7 @@ * IN THE SOFTWARE. */ -import { getElement } from "observables" +import { getElementOrThrow } from "observables" /* ---------------------------------------------------------------------------- * Data @@ -45,7 +45,7 @@ let lang: Record */ 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") { diff --git a/src/assets/stylesheets/extensions/_codehilite.scss b/src/assets/stylesheets/extensions/_codehilite.scss index 95ba1d9f2..911baeaaf 100644 --- a/src/assets/stylesheets/extensions/_codehilite.scss +++ b/src/assets/stylesheets/extensions/_codehilite.scss @@ -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; }