diff --git a/src/assets/javascripts/index.ts b/src/assets/javascripts/index.ts index 8037b001d..529a6482c 100644 --- a/src/assets/javascripts/index.ts +++ b/src/assets/javascripts/index.ts @@ -73,7 +73,7 @@ import { watchComponentMap } from "components2" import { mountClipboard } from "./integrations/clipboard" -import { patchTables } from "patches/table" +import { patchTables, patchDetails } from "patches" /* ---------------------------------------------------------------------------- * Types @@ -268,6 +268,9 @@ export function initialize(config: unknown) { /* ----------------------------------------------------------------------- */ + // TODO: general keyboard handler... + // put into main!? + // search$ // .pipe( // filter(not), @@ -330,8 +333,11 @@ export function initialize(config: unknown) { }) // TODO: this is just a re-rendering patch... - // patchTables({ document$ }) - // .subscribe(console.log) + patchTables({ document$ }) + .subscribe(console.log) + + patchDetails({ document$ }) + .subscribe(console.log) // /* Wrap all data tables for better overflow scrolling */ // const placeholder = document.createElement("table") diff --git a/src/assets/javascripts/integrations/search/_/index.ts b/src/assets/javascripts/integrations/search/_/index.ts index 1b9e7de13..e5e70e2a0 100644 --- a/src/assets/javascripts/integrations/search/_/index.ts +++ b/src/assets/javascripts/integrations/search/_/index.ts @@ -89,6 +89,12 @@ export interface SearchResult { * Class * ------------------------------------------------------------------------- */ +/** + * Search index + * + * Note that `lunr` is injected via Webpack, as it will otherwise also be + * bundled in the application bundle. + */ export class SearchIndex { /** diff --git a/src/assets/javascripts/patches/details/index.ts b/src/assets/javascripts/patches/details/index.ts new file mode 100644 index 000000000..d66c00365 --- /dev/null +++ b/src/assets/javascripts/patches/details/index.ts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016-2020 Martin Donath + * + * 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 { identity } from "ramda" +import { Observable, fromEvent, merge } from "rxjs" +import { + filter, + map, + shareReplay, + switchMapTo, + tap +} from "rxjs/operators" + +import { getElements, watchMedia } from "observables" + +/* ---------------------------------------------------------------------------- + * Helper types + * ------------------------------------------------------------------------- */ + +/** + * Mount options + */ +interface MountOptions { + document$: Observable /* Document observable */ +} + +/* ---------------------------------------------------------------------------- + * Functions + * ------------------------------------------------------------------------- */ + +/** + * Patch all `details` elements + * + * @param options - Options + * + * @return Details elements observable + */ +export function patchDetails( + { document$ }: MountOptions +): Observable { + return merge( + watchMedia("print").pipe(filter(identity)), // Webkit + fromEvent(window, "beforeprint") // IE, FF + ) + .pipe( + switchMapTo(document$), + map(() => getElements("details")), + tap(els => { + for (const detail of els) + detail.setAttribute("open", "") + }), + shareReplay(1) + ) +} diff --git a/src/assets/javascripts/patches/index.ts b/src/assets/javascripts/patches/index.ts index 749065d5a..49a308501 100644 --- a/src/assets/javascripts/patches/index.ts +++ b/src/assets/javascripts/patches/index.ts @@ -20,4 +20,5 @@ * IN THE SOFTWARE. */ +export * from "./details" export * from "./table" diff --git a/src/assets/javascripts/patches/table/index.ts b/src/assets/javascripts/patches/table/index.ts index ceef3aaa2..988c7a7d9 100644 --- a/src/assets/javascripts/patches/table/index.ts +++ b/src/assets/javascripts/patches/table/index.ts @@ -51,11 +51,11 @@ interface MountOptions { export function patchTables( { document$ }: MountOptions ): Observable { + const placeholder = document.createElement("table") return document$ .pipe( map(() => getElements("table:not([class])")), tap(els => { - const placeholder = document.createElement("table") for (const el of els) { el.replaceWith(placeholder) placeholder.replaceWith(renderTable(el))