Added more inline comments and simplified component mounting

This commit is contained in:
squidfunk 2021-02-13 17:03:15 +01:00
parent 96797b471f
commit aacb5ca5a7
45 changed files with 155 additions and 84 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,16 @@
{
"assets/javascripts/bundle.js": "assets/javascripts/bundle.6b6cf576.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.6b6cf576.min.js.map",
"assets/javascripts/bundle.js": "assets/javascripts/bundle.b0aa5de8.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.b0aa5de8.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.e32ed4d0.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.e32ed4d0.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.b9424174.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.b9424174.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.c55d56a9.min.css",
"assets/stylesheets/main.css.map": "assets/stylesheets/main.c55d56a9.min.css.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.25519675.min.css",
"assets/stylesheets/main.css.map": "assets/stylesheets/main.25519675.min.css.map",
"assets/stylesheets/palette.css": "assets/stylesheets/palette.e70b70b6.min.css",
"assets/stylesheets/palette.css.map": "assets/stylesheets/palette.e70b70b6.min.css.map",
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.63116035.min.js",
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.63116035.min.js.map",
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.c607e7b3.min.js",
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.c607e7b3.min.js.map",
"overrides/assets/javascripts/vendor.js": "overrides/assets/javascripts/vendor.1aa446d9.min.js",
"overrides/assets/javascripts/vendor.js.map": "overrides/assets/javascripts/vendor.1aa446d9.min.js.map",
"overrides/assets/stylesheets/main.css": "overrides/assets/stylesheets/main.d67efea2.min.css",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -39,7 +39,7 @@
{% endif %}
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.c55d56a9.min.css' | url }}">
<link rel="stylesheet" href="{{ 'assets/stylesheets/main.25519675.min.css' | url }}">
{% if config.theme.palette %}
{% set palette = config.theme.palette %}
<link rel="stylesheet" href="{{ 'assets/stylesheets/palette.e70b70b6.min.css' | url }}">
@ -217,7 +217,7 @@
{% endblock %}
{% block scripts %}
<script src="{{ 'assets/javascripts/vendor.e32ed4d0.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.6b6cf576.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.b0aa5de8.min.js' | url }}"></script>
{% for path in config["extra_javascript"] %}
<script src="{{ path | url }}"></script>
{% endfor %}

View File

@ -1,2 +0,0 @@
!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){function t(t){for(var r,i,a=t[0],s=t[1],u=t[2],f=0,p=[];f<a.length;f++)i=a[f],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(r in s)Object.prototype.hasOwnProperty.call(s,r)&&(e[r]=s[r]);for(l&&l(t);p.length;)p.shift()();return c.push.apply(c,u||[]),n()}function n(){for(var e,t=0;t<c.length;t++){for(var n=c[t],r=!0,a=1;a<n.length;a++){var s=n[a];0!==o[s]&&(r=!1)}r&&(c.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={0:0},c=[];function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="";var a=window.webpackJsonp=window.webpackJsonp||[],s=a.push.bind(a);a.push=t,a=a.slice();for(var u=0;u<a.length;u++)t(a[u]);var l=s;return c.push([37,1]),n()}({37:function(e,t,n){"use strict";n.r(t);var r=n(20),o=n(3),c=n(38),i=n(29),a=n(25);n(32),n(39);function s(e,t=document){return t.querySelector(e)||void 0}function u(e,t=document){const n=s(e,t);if(void 0===n)throw new ReferenceError(`Missing element: expected "${e}" to be present`);return n}n(50);var l=n(51);var f=n(17),p=n(40),d=n(41),b=n(42),g=n(43),h=n(44);n(45),n(46);const v=new f.a;Object(p.a)(()=>Object(d.a)(new ResizeObserver(e=>{for(const t of e)v.next(t)}))).pipe(Object(i.a)(e=>b.a.pipe(Object(l.a)(e)).pipe(Object(g.a)(()=>e.disconnect()))),Object(h.a)(1));n(31);u("[data-md-toggle=drawer]"),u("[data-md-toggle=search]");n(47);n(52),n(53);n(48),n(49);function O(e,t){if("string"==typeof t||"number"==typeof t)e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(const n of t)O(e,n)}function j(e,t,...n){const r=document.createElement(e);if(t)for(const e of Object.keys(t))"boolean"!=typeof t[e]?r.setAttribute(e,t[e]):t[e]&&r.setAttribute(e,"");for(const e of n)O(r,e);return r}function m(e,t){return t.length?j("div",{class:""},j("span",null,function(e){if(e>999){return((e+1e-6)/1e3).toFixed(+((e-950)%1e3>99))+"k"}return e.toString()}(e.length)," results"),j("ul",{class:"tx-icon-search__list"},e.slice(0,10).map(e=>j("li",{class:"tx-icon-search__item"},j("span",{class:"twemoji"},j("img",{src:"https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/"+e,style:"width: 18px; height: 18px"}))," ",j("button",{class:"md-clipboard--inline","data-clipboard-text":":"+e.replace(/\.svg$/,"").replace(/\//g,"-")+":"},j("code",null,function(e,t){return`:${Object(r.wrap)(e.replace(/\.svg$/,"").replace(/\//g,"-"),t,{wrap:{tagOpen:"<b>",tagClose:"</b>"}})}:`}(e,t))))))):j("div",{class:""})}const y=u("#__config"),w=JSON.parse(y.textContent),x=Object(o.a)(fetch(w.base+"/overrides/assets/javascripts/icons.json").then(e=>e.json())),_=s("#icon-search");_&&x.pipe(Object(i.a)(e=>Object(c.a)(_,"keyup").pipe(Object(a.a)(()=>Object(r.filter)(e,_.value))))).subscribe(e=>{const t=u(".tx-icon-result");t.innerHTML="",t.appendChild(m(e,_.value))}),Object(c.a)(document.body,"click").subscribe(e=>{if(e.target instanceof HTMLElement){e.target.closest("a[href^=http]")instanceof HTMLLinkElement&&ga("send","event","outbound","click",y.href)}})}}));
//# sourceMappingURL=bundle.63116035.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){function t(t){for(var r,i,a=t[0],s=t[1],u=t[2],f=0,p=[];f<a.length;f++)i=a[f],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(r in s)Object.prototype.hasOwnProperty.call(s,r)&&(e[r]=s[r]);for(l&&l(t);p.length;)p.shift()();return c.push.apply(c,u||[]),n()}function n(){for(var e,t=0;t<c.length;t++){for(var n=c[t],r=!0,a=1;a<n.length;a++){var s=n[a];0!==o[s]&&(r=!1)}r&&(c.splice(t--,1),e=i(i.s=n[0]))}return e}var r={},o={0:0},c=[];function i(t){if(r[t])return r[t].exports;var n=r[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,i),n.l=!0,n.exports}i.m=e,i.c=r,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="";var a=window.webpackJsonp=window.webpackJsonp||[],s=a.push.bind(a);a.push=t,a=a.slice();for(var u=0;u<a.length;u++)t(a[u]);var l=s;return c.push([37,1]),n()}({37:function(e,t,n){"use strict";n.r(t);var r=n(20),o=n(3),c=n(38),i=n(29),a=n(25);n(32),n(39);function s(e,t=document){return t.querySelector(e)||void 0}function u(e,t=document){const n=s(e,t);if(void 0===n)throw new ReferenceError(`Missing element: expected "${e}" to be present`);return n}n(50);var l=n(51);var f=n(17),p=n(40),b=n(41),d=n(42),g=n(43),h=n(44);n(45),n(46);const v=new f.a;Object(p.a)(()=>Object(b.a)(new ResizeObserver(e=>{for(const t of e)v.next(t)}))).pipe(Object(i.a)(e=>d.a.pipe(Object(l.a)(e)).pipe(Object(g.a)(()=>e.disconnect()))),Object(h.a)(1));n(31);u("[data-md-toggle=drawer]"),u("[data-md-toggle=search]");n(47);function O(){return new URL(location.href)}n(52),n(53);n(48),n(49);const j=u("#__config"),m=JSON.parse(j.textContent);function y(e,t){if("string"==typeof t||"number"==typeof t)e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(const n of t)y(e,n)}function w(e,t,...n){const r=document.createElement(e);if(t)for(const e of Object.keys(t))"boolean"!=typeof t[e]?r.setAttribute(e,t[e]):t[e]&&r.setAttribute(e,"");for(const e of n)y(r,e);return r}m.base=new URL(m.base,O()).toString().replace(/\/$/,"");function x(e,t){return t.length?w("div",{class:""},w("span",null,function(e){if(e>999){return((e+1e-6)/1e3).toFixed(+((e-950)%1e3>99))+"k"}return e.toString()}(e.length)," results"),w("ul",{class:"tx-icon-search__list"},e.slice(0,10).map(e=>w("li",{class:"tx-icon-search__item"},w("span",{class:"twemoji"},w("img",{src:"https://raw.githubusercontent.com/squidfunk/mkdocs-material/master/material/.icons/"+e,style:"width: 18px; height: 18px"}))," ",w("button",{class:"md-clipboard--inline","data-clipboard-text":":"+e.replace(/\.svg$/,"").replace(/\//g,"-")+":"},w("code",null,function(e,t){return`:${Object(r.wrap)(e.replace(/\.svg$/,"").replace(/\//g,"-"),t,{wrap:{tagOpen:"<b>",tagClose:"</b>"}})}:`}(e,t))))))):w("div",{class:""})}const _=m,k=Object(o.a)(fetch(_.base+"/overrides/assets/javascripts/icons.json").then(e=>e.json())),S=s("#icon-search");S&&k.pipe(Object(i.a)(e=>Object(c.a)(S,"keyup").pipe(Object(a.a)(()=>Object(r.filter)(e,S.value))))).subscribe(e=>{const t=u(".tx-icon-result");t.innerHTML="",t.appendChild(x(e,S.value))}),Object(c.a)(document.body,"click").subscribe(e=>{if(e.target instanceof HTMLElement){e.target.closest("a[href^=http]")instanceof HTMLLinkElement&&ga("send","event","outbound","click",el.href)}})}}));
//# sourceMappingURL=bundle.c607e7b3.min.js.map

File diff suppressed because one or more lines are too long

View File

@ -54,5 +54,5 @@
{% block scripts %}
{{ super() }}
<script src="{{ 'overrides/assets/javascripts/vendor.1aa446d9.min.js' | url }}"></script>
<script src="{{ 'overrides/assets/javascripts/bundle.63116035.min.js' | url }}"></script>
<script src="{{ 'overrides/assets/javascripts/bundle.c607e7b3.min.js' | url }}"></script>
{% endblock %}

View File

@ -31,8 +31,11 @@ import { getElementOrThrow, getLocation } from "~/browser"
*/
export type Flag =
| "header.autohide" /* Hide header */
| "navigation.tabs" /* Tabs navigation */
| "navigation.expand" /* Automatic expansion */
| "navigation.instant" /* Instant loading */
| "navigation.sections" /* Sections navigation */
| "navigation.tabs" /* Tabs navigation */
| "toc.integrate" /* Integrated table of contents */
/* ------------------------------------------------------------------------- */

View File

@ -67,19 +67,19 @@ export function watchPrint(): Observable<void> {
/* ------------------------------------------------------------------------- */
/**
* Toggle an observable with another one
* Toggle an observable with a media observable
*
* @template T - Data type
*
* @param toggle$ - Toggle observable
* @param query$ - Media observable
* @param factory - Observable factory
*
* @returns Toggled observable
*/
export function at<T>(
toggle$: Observable<boolean>, factory: () => Observable<T>
query$: Observable<boolean>, factory: () => Observable<T>
): Observable<T> {
return toggle$
return query$
.pipe(
switchMap(active => active ? factory() : NEVER)
)

View File

@ -20,6 +20,8 @@
* IN THE SOFTWARE.
*/
import { getElementOrThrow, getElements } from "~/browser"
/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */
@ -31,12 +33,14 @@ export type ComponentType =
| "announce" /* Announcement bar */
| "container" /* Container */
| "content" /* Content */
| "dialog" /* Dialog */
| "header" /* Header */
| "header-title" /* Header title */
| "main" /* Main area */
| "search" /* Search */
| "search-query" /* Search input */
| "search-result" /* Search results */
| "sidebar" /* Sidebar */
| "skip" /* Skip link */
| "source" /* Repository information */
| "tabs" /* Navigation tabs */
@ -55,3 +59,39 @@ export type Component<
T & {
ref: U /* Component reference */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Retrieve the element for a given component or throw a reference error
*
* @template T - Element type
*
* @param type - Component type
* @param node - Node of reference
*
* @returns Element
*/
export function getComponentElement<T extends HTMLElement>(
type: ComponentType, node: ParentNode = document
): T {
return getElementOrThrow(`[data-md-component=${type}]`, node)
}
/**
* Retrieve all elements for a given component
*
* @template T - Element type
*
* @param type - Component type
* @param node - Node of reference
*
* @returns Elements
*/
export function getComponentElements<T extends HTMLElement>(
type: ComponentType, node: ParentNode = document
): T[] {
return getElements(`[data-md-component=${type}]`, node)
}

View File

@ -61,6 +61,9 @@ interface MountOptions {
/**
* Mount content
*
* This function mounts all components that are found in the content of the
* actual article, including code blocks, data tables and details.
*
* @param el - Content element
* @param options - Options
*

View File

@ -111,8 +111,8 @@ export function watchCodeBlock(
/**
* Mount code block
*
* This function ensures that overflowing code blocks are focusable by keyboard,
* so they can be scrolled without a mouse to improve on accessibility.
* This function ensures that an overflowing code block is focusable through
* keyboard, so it can be scrolled without a mouse to improve on accessibility.
*
* @param el - Code block element
* @param options - Options

View File

@ -88,8 +88,8 @@ export function watchDetails(
/**
* Mount details
*
* This function ensures that `details` tags are opened prior to printing, so
* the whole content of the page is included and on anchor jumps.
* This function ensures that `details` tags are opened on anchor jumps and
* prior to printing, so the whole content of the page is visible.
*
* @param el - Details element
* @param options - Options

View File

@ -52,6 +52,9 @@ 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.
*
* @param el - Data table element
*
* @returns Data table component observable

View File

@ -105,6 +105,9 @@ 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.
*
* @param el - Dialog element
* @param options - Options
*

View File

@ -34,12 +34,15 @@ import {
combineLatestWith,
distinctUntilChanged,
distinctUntilKeyChanged,
endWith,
filter,
finalize,
map,
observeOn,
shareReplay,
startWith,
switchMap
switchMap,
tap
} from "rxjs/operators"
import { feature } from "~/_"
@ -118,7 +121,7 @@ function isHidden({ viewport$ }: WatchOptions): Observable<boolean> {
.pipe(
filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100),
map(([, [direction]]) => direction),
distinctUntilChanged(),
distinctUntilChanged()
)
/* Compute threshold for autohiding */
@ -127,7 +130,7 @@ function isHidden({ viewport$ }: WatchOptions): Observable<boolean> {
.pipe(
map(([{ offset }, search]) => offset.y > 400 && !search),
distinctUntilChanged(),
switchMap(active => active ? hidden$ : NEVER),
switchMap(active => active ? hidden$ : of(false)),
startWith(false)
)
}
@ -173,10 +176,8 @@ export function watchHeader(
/**
* Mount header
*
* The header must be connected to the main area observable outside of the
* operator function, as the header will persist in-between document switches
* while the main area is replaced. However, the header observable must be
* passed to this function, so we connect both via a long-living subject.
* This function manages the different states of the header, i.e. whether it's
* hidden or rendered with a shadow. This depends heavily on the main area.
*
* @param el - Header element
* @param options - Options

View File

@ -20,7 +20,12 @@
* IN THE SOFTWARE.
*/
import { NEVER, Observable, Subject, animationFrameScheduler } from "rxjs"
import {
NEVER,
Observable,
Subject,
animationFrameScheduler
} from "rxjs"
import {
distinctUntilKeyChanged,
finalize,
@ -104,6 +109,9 @@ export function watchHeaderTitle(
/**
* Mount header title
*
* This function swaps the header title from the site title to the title of the
* current page when the user scrolls past the first headline.
*
* @param el - Header title element
* @param options - Options
*

View File

@ -27,7 +27,6 @@ import { configuration } from "~/_"
import {
Keyboard,
getActiveElement,
getElementOrThrow,
getElements,
requestJSON,
setElementFocus,
@ -41,7 +40,7 @@ import {
setupSearchWorker
} from "~/integrations"
import { Component } from "../../_"
import { Component, getComponentElement } from "../../_"
import { SearchQuery, mountSearchQuery } from "../query"
import { SearchResult, mountSearchResult } from "../result"
@ -89,6 +88,9 @@ function fetchSearchIndex(url: string) {
/**
* Mount search
*
* This function sets up the search functionality, including the underlying
* web worker and all keyboard bindings.
*
* @param el - Search element
* @param options - Options
*
@ -103,8 +105,8 @@ export function mountSearch(
))
/* Retrieve elements */
const query = getElementOrThrow("[data-md-component=search-query]", el)
const result = getElementOrThrow("[data-md-component=search-result]", el)
const query = getComponentElement("search-query", el)
const result = getComponentElement("search-result", el)
/* Re-emit query when search is ready */
const { tx$, rx$ } = worker

View File

@ -64,6 +64,9 @@ 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.
*
* @param el - Repository information element
*
* @returns Repository information observable

View File

@ -95,6 +95,9 @@ export function watchTabs(
/**
* Mount navigation tabs
*
* This function hides the navigation tabs when scrolling past the threshold
* and makes them reappear in a nice CSS animation when scrolling back up.
*
* @param el - Navigation tabs element
* @param options - Options
*

View File

@ -34,8 +34,6 @@ import { feature } from "./_"
import {
at,
getElement,
getElementOrThrow,
getElements,
setToggle,
watchDocument,
watchKeyboard,
@ -46,6 +44,8 @@ import {
watchViewport
} from "./browser"
import {
getComponentElement,
getComponentElements,
mountContent,
mountDialog,
mountHeader,
@ -129,16 +129,11 @@ keyboard$
patchIndeterminate({ document$ })
patchScrollfix({ document$ })
/* Set up header observable */
const header$ = watchHeader(
getElementOrThrow("[data-md-component=header]"),
{ viewport$ }
)
/* Set up main area observable */
/* Set up header and main area observable */
const header$ = watchHeader(getComponentElement("header"), { viewport$ })
const main$ = document$
.pipe(
map(() => getElementOrThrow("[data-md-component=main]")),
map(() => getComponentElement("main")),
switchMap(el => watchMain(el, { viewport$, header$ })),
shareReplay(1)
)
@ -147,23 +142,23 @@ const main$ = document$
const control$ = merge(
/* Dialog */
...getElements("[data-md-component=dialog]")
...getComponentElements("dialog")
.map(child => mountDialog(child, { alert$ })),
/* Header */
...getElements("[data-md-component=header]")
...getComponentElements("header")
.map(child => mountHeader(child, { viewport$, header$, main$ })),
/* Search */
...getElements("[data-md-component=search]")
...getComponentElements("search")
.map(child => mountSearch(child, { keyboard$ })),
/* Repository information */
...getElements("[data-md-component=source]")
...getComponentElements("source")
.map(child => mountSource(child as HTMLAnchorElement)),
/* Navigation tabs */
...getElements("[data-md-component=tabs]")
...getComponentElements("tabs")
.map(child => mountTabs(child, { viewport$, header$ })),
)
@ -171,22 +166,22 @@ const control$ = merge(
const content$ = defer(() => merge(
/* Content */
...getElements("[data-md-component=content]")
...getComponentElements("content")
.map(child => mountContent(child, { target$, viewport$, print$ })),
/* Header title */
...getElements("[data-md-component=header-title]")
...getComponentElements("header-title")
.map(child => mountHeaderTitle(child, { viewport$, header$ })),
/* Sidebar */
...getElements("[data-md-component=sidebar]")
...getComponentElements("sidebar")
.map(child => child.getAttribute("data-md-type") === "navigation"
? at(screen$, () => mountSidebar(child, { viewport$, header$, main$ }))
: at(tablet$, () => mountSidebar(child, { viewport$, header$, main$ }))
),
/* Table of contents */
...getElements("[data-md-component=toc]")
...getComponentElements("toc")
.map(child => mountTableOfContents(child, { viewport$, header$ })),
))
@ -194,7 +189,8 @@ const content$ = defer(() => merge(
const component$ = document$
.pipe(
switchMap(() => content$),
mergeWith(control$)
mergeWith(control$),
shareReplay(1)
)
/* Subscribe to all components */

View File

@ -51,7 +51,6 @@ import {
ViewportOffset,
createElement,
getElement,
getElementOrThrow,
getElements,
replaceElement,
request,
@ -60,6 +59,7 @@ import {
setLocationHash,
setViewportOffset
} from "~/browser"
import { getComponentElement } from "~/components"
/* ----------------------------------------------------------------------------
* Types
@ -261,14 +261,12 @@ export function setupInstantLoading(
setViewportOffset(offset || { y: 0 })
})
/* Replace components */
/* Replace meta tags and components */
document$
.pipe(
skip(1)
)
.subscribe(replacement => {
/* Replace meta tags and components */
for (const selector of [
/* Meta tags */
@ -298,7 +296,7 @@ export function setupInstantLoading(
document$
.pipe(
skip(1),
map(() => getElementOrThrow("[data-md-component=container]")),
map(() => getComponentElement("container")),
switchMap(el => of(...getElements("script", el))),
concatMap(el => {
const script = createElement("script")

View File

@ -42,6 +42,9 @@ interface PatchOptions {
/**
* Patch indeterminate checkboxes
*
* This function will replace the indeterminate "pseudo state" with the actual
* indeterminate state, which is used to keep navigation always expanded.
*
* @param options - Options
*/
export function patchIndeterminate(

View File

@ -34,7 +34,7 @@ import { h } from "~/utilities"
*
* @returns Element
*/
export function renderClipboardButton(id: string) {
export function renderClipboardButton(id: string): HTMLElement {
return (
<button
class="md-clipboard md-icon"

View File

@ -47,7 +47,7 @@ const enum Flag {
/**
* Render a search document
*
* @param section - Search document
* @param document - Search document
* @param flag - Render flags
*
* @returns Element
@ -106,8 +106,8 @@ function renderSearchDocument(
* @returns Element
*/
export function renderSearchResult(
result: SearchResult, threshold: number = Infinity
) {
result: SearchResult, threshold = Infinity
): HTMLElement {
const docs = [...result]
/* Find and extract parent article */

View File

@ -34,7 +34,7 @@ import { h } from "~/utilities"
*
* @returns Element
*/
export function renderSourceFacts(facts: SourceFacts) {
export function renderSourceFacts(facts: SourceFacts): HTMLElement {
return (
<ul class="md-source__facts">
{facts.map(fact => (

View File

@ -33,7 +33,7 @@ import { h } from "utilities"
*
* @returns Element
*/
export function renderTable(table: HTMLElement) {
export function renderTable(table: HTMLElement): HTMLElement {
return (
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">

View File

@ -20,5 +20,5 @@
* IN THE SOFTWARE.
*/
export * from "./jsx"
export * from "./h"
export * from "./string"

View File

@ -164,7 +164,7 @@ kbd {
}
}
// Code blocks
// Code block
code,
pre,
kbd {
@ -177,7 +177,7 @@ kbd {
}
}
// Inline code blocks
// Inline code block
code {
padding: 0 px2em(4px, 13.6px);
font-size: px2em(13.6px);

View File

@ -39,7 +39,8 @@
// Arithmatex content
> * {
width: min-content;
margin: 1em auto !important; // stylelint-disable-line
// stylelint-disable-next-line declaration-no-important
margin: 1em auto !important;
padding: 0 px2rem(16px);
touch-action: auto;
}

View File

@ -27,7 +27,7 @@
// Scoped in typesetted content to match specificity of regular content
.md-typeset {
// Deletions, additions and comments
// Deletion, addition or comment
del.critic,
ins.critic,
.critic.comment {

View File

@ -80,11 +80,11 @@
content: "";
}
// Inline copy to clipboard
// Inline button
&--inline {
cursor: pointer;
// Code blocks
// Code block
code {
transition:
color 250ms,

View File

@ -27,7 +27,7 @@
// Scoped in typesetted content to match specificity of regular content
.md-typeset {
// Button
// Form button
.md-button {
display: inline-block;
padding: px2em(10px) px2em(32px);
@ -56,9 +56,8 @@
}
}
// Input
// Form input
.md-input {
width: 100%;
height: px2rem(36px);
padding: 0 px2rem(12px);
font-size: px2rem(16px);
@ -75,5 +74,10 @@
0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15),
0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15);
}
// Stretch to full width
&--stretch {
width: 100%;
}
}
}

View File

@ -72,7 +72,7 @@
}
// Header navigation - if the header exceeds the default height of `48px`, i.e.
// by adding a bigger logo, the items are agned at the center
// by adding a bigger logo, the items are aligned at the center
.md-header-nav {
display: flex;
align-items: center;

View File

@ -25,13 +25,13 @@ import { filter } from "fuzzaldrin-plus"
import { from, fromEvent } from "rxjs"
import { map, switchMap } from "rxjs/operators"
import { configuration } from "~/_"
import { getElement, getElementOrThrow } from "~/browser"
import { renderIconSearch } from "./templates/icon"
// Obtain configuration
const el = getElementOrThrow("#__config")
const config = JSON.parse(el.textContent!)
const config = configuration()
// Now, load icons.json
const icons$ =