Added back keyboard handlers
This commit is contained in:
parent
44751785a0
commit
e7850ca184
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
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"assets/javascripts/bundle.js": "assets/javascripts/bundle.4fa4ebaf.min.js",
|
"assets/javascripts/bundle.js": "assets/javascripts/bundle.d8c6976f.min.js",
|
||||||
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.4fa4ebaf.min.js.map",
|
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.d8c6976f.min.js.map",
|
||||||
"assets/javascripts/vendor.js": "assets/javascripts/vendor.e32ed4d0.min.js",
|
"assets/javascripts/vendor.js": "assets/javascripts/vendor.e32ed4d0.min.js",
|
||||||
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.e32ed4d0.min.js.map",
|
"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": "assets/javascripts/worker/search.b9424174.min.js",
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
"assets/stylesheets/main.css.map": "assets/stylesheets/main.a86e6725.min.css.map",
|
"assets/stylesheets/main.css.map": "assets/stylesheets/main.a86e6725.min.css.map",
|
||||||
"assets/stylesheets/palette.css": "assets/stylesheets/palette.e70b70b6.min.css",
|
"assets/stylesheets/palette.css": "assets/stylesheets/palette.e70b70b6.min.css",
|
||||||
"assets/stylesheets/palette.css.map": "assets/stylesheets/palette.e70b70b6.min.css.map",
|
"assets/stylesheets/palette.css.map": "assets/stylesheets/palette.e70b70b6.min.css.map",
|
||||||
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.9f9f98ea.min.js",
|
"overrides/assets/javascripts/bundle.js": "overrides/assets/javascripts/bundle.63116035.min.js",
|
||||||
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.9f9f98ea.min.js.map",
|
"overrides/assets/javascripts/bundle.js.map": "overrides/assets/javascripts/bundle.63116035.min.js.map",
|
||||||
"overrides/assets/javascripts/vendor.js": "overrides/assets/javascripts/vendor.1aa446d9.min.js",
|
"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/javascripts/vendor.js.map": "overrides/assets/javascripts/vendor.1aa446d9.min.js.map",
|
||||||
"overrides/assets/stylesheets/main.css": "overrides/assets/stylesheets/main.8e98f424.min.css",
|
"overrides/assets/stylesheets/main.css": "overrides/assets/stylesheets/main.8e98f424.min.css",
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script src="{{ 'assets/javascripts/vendor.e32ed4d0.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/vendor.e32ed4d0.min.js' | url }}"></script>
|
||||||
<script src="{{ 'assets/javascripts/bundle.4fa4ebaf.min.js' | url }}"></script>
|
<script src="{{ 'assets/javascripts/bundle.d8c6976f.min.js' | url }}"></script>
|
||||||
{% for path in config["extra_javascript"] %}
|
{% for path in config["extra_javascript"] %}
|
||||||
<script src="{{ path | url }}"></script>
|
<script src="{{ path | url }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +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),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);n(47);u("[data-md-toggle=drawer]"),u("[data-md-toggle=search]");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)}})}}));
|
!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.9f9f98ea.min.js.map
|
//# sourceMappingURL=bundle.63116035.min.js.map
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -54,5 +54,5 @@
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script src="{{ 'overrides/assets/javascripts/vendor.1aa446d9.min.js' | url }}"></script>
|
<script src="{{ 'overrides/assets/javascripts/vendor.1aa446d9.min.js' | url }}"></script>
|
||||||
<script src="{{ 'overrides/assets/javascripts/bundle.9f9f98ea.min.js' | url }}"></script>
|
<script src="{{ 'overrides/assets/javascripts/bundle.63116035.min.js' | url }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -23,20 +23,33 @@
|
||||||
import { Observable, fromEvent } from "rxjs"
|
import { Observable, fromEvent } from "rxjs"
|
||||||
import { filter, map, share } from "rxjs/operators"
|
import { filter, map, share } from "rxjs/operators"
|
||||||
|
|
||||||
|
import { getActiveElement } from "../element"
|
||||||
|
import { getToggle } from "../toggle"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Types
|
* Types
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key
|
* Keyboard mode
|
||||||
*/
|
*/
|
||||||
export interface Key {
|
export type KeyboardMode =
|
||||||
|
| "global" /* Global */
|
||||||
|
| "search" /* Search is open */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keyboard
|
||||||
|
*/
|
||||||
|
export interface Keyboard {
|
||||||
|
mode: KeyboardMode /* Keyboard mode */
|
||||||
type: string /* Key type */
|
type: string /* Key type */
|
||||||
claim(): void /* Key claim */
|
claim(): void /* Key claim */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Functions
|
* Helper functions
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,7 +59,7 @@ export interface Key {
|
||||||
*
|
*
|
||||||
* @returns Test result
|
* @returns Test result
|
||||||
*/
|
*/
|
||||||
export function isSusceptibleToKeyboard(el: HTMLElement): boolean {
|
function isSusceptibleToKeyboard(el: HTMLElement): boolean {
|
||||||
switch (el.tagName) {
|
switch (el.tagName) {
|
||||||
|
|
||||||
/* Form elements */
|
/* Form elements */
|
||||||
|
|
@ -61,24 +74,35 @@ export function isSusceptibleToKeyboard(el: HTMLElement): boolean {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Functions
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watch keyboard
|
* Watch keyboard
|
||||||
*
|
*
|
||||||
* @returns Keyboard observable
|
* @returns Keyboard observable
|
||||||
*/
|
*/
|
||||||
export function watchKeyboard(): Observable<Key> {
|
export function watchKeyboard(): Observable<Keyboard> {
|
||||||
return fromEvent<KeyboardEvent>(window, "keydown")
|
return fromEvent<KeyboardEvent>(window, "keydown")
|
||||||
.pipe(
|
.pipe(
|
||||||
filter(ev => !(ev.metaKey || ev.ctrlKey)),
|
filter(ev => !(ev.metaKey || ev.ctrlKey)),
|
||||||
map(ev => ({
|
map(ev => ({
|
||||||
|
mode: getToggle("search") ? "search" : "global",
|
||||||
type: ev.key,
|
type: ev.key,
|
||||||
claim() {
|
claim() {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
ev.stopPropagation()
|
ev.stopPropagation()
|
||||||
}
|
}
|
||||||
})),
|
} as Keyboard)),
|
||||||
|
filter(({ mode }) => {
|
||||||
|
if (mode === "global") {
|
||||||
|
const active = getActiveElement()
|
||||||
|
if (typeof active !== "undefined")
|
||||||
|
return !isSusceptibleToKeyboard(active)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}),
|
||||||
share()
|
share()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,14 @@ import { filter, sample, take } from "rxjs/operators"
|
||||||
|
|
||||||
import { configuration } from "~/_"
|
import { configuration } from "~/_"
|
||||||
import {
|
import {
|
||||||
|
Keyboard,
|
||||||
|
getActiveElement,
|
||||||
getElementOrThrow,
|
getElementOrThrow,
|
||||||
requestJSON
|
getElements,
|
||||||
|
requestJSON,
|
||||||
|
setElementFocus,
|
||||||
|
setElementSelection,
|
||||||
|
setToggle
|
||||||
} from "~/browser"
|
} from "~/browser"
|
||||||
import {
|
import {
|
||||||
SearchIndex,
|
SearchIndex,
|
||||||
|
|
@ -50,6 +56,17 @@ export type Search =
|
||||||
| SearchQuery
|
| SearchQuery
|
||||||
| SearchResult
|
| SearchResult
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Helper types
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mount options
|
||||||
|
*/
|
||||||
|
interface MountOptions {
|
||||||
|
keyboard$: Observable<Keyboard> /* Keyboard observable */
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Helper functions
|
* Helper functions
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
@ -73,17 +90,22 @@ function fetchSearchIndex(url: string) {
|
||||||
* Mount search
|
* Mount search
|
||||||
*
|
*
|
||||||
* @param el - Search element
|
* @param el - Search element
|
||||||
|
* @param options - Options
|
||||||
*
|
*
|
||||||
* @returns Search component observable
|
* @returns Search component observable
|
||||||
*/
|
*/
|
||||||
export function mountSearch(
|
export function mountSearch(
|
||||||
el: HTMLElement
|
el: HTMLElement, { keyboard$ }: MountOptions
|
||||||
): Observable<Component<Search>> {
|
): Observable<Component<Search>> {
|
||||||
const config = configuration()
|
const config = configuration()
|
||||||
const worker = setupSearchWorker(config.search, fetchSearchIndex(
|
const worker = setupSearchWorker(config.search, fetchSearchIndex(
|
||||||
`${config.base}/search/search_index.json`
|
`${config.base}/search/search_index.json`
|
||||||
))
|
))
|
||||||
|
|
||||||
|
/* Retrieve elements */
|
||||||
|
const query = getElementOrThrow("[data-md-component=search-query]", el)
|
||||||
|
const result = getElementOrThrow("[data-md-component=search-result]", el)
|
||||||
|
|
||||||
/* Re-emit query when search is ready */
|
/* Re-emit query when search is ready */
|
||||||
const { tx$, rx$ } = worker
|
const { tx$, rx$ } = worker
|
||||||
tx$
|
tx$
|
||||||
|
|
@ -94,18 +116,80 @@ export function mountSearch(
|
||||||
)
|
)
|
||||||
.subscribe(tx$.next.bind(tx$))
|
.subscribe(tx$.next.bind(tx$))
|
||||||
|
|
||||||
/* Mount search query component */
|
/* Set up search keyboard handlers */
|
||||||
const query$ = mountSearchQuery(
|
keyboard$
|
||||||
getElementOrThrow("[data-md-component=search-query]", el),
|
.pipe(
|
||||||
worker
|
filter(({ mode }) => mode === "search")
|
||||||
)
|
)
|
||||||
|
.subscribe(key => {
|
||||||
|
const active = getActiveElement()
|
||||||
|
switch (key.type) {
|
||||||
|
|
||||||
/* Mount search result and return component */
|
/* Enter: prevent form submission */
|
||||||
|
case "Enter":
|
||||||
|
if (active === query)
|
||||||
|
key.claim()
|
||||||
|
break
|
||||||
|
|
||||||
|
/* Escape or Tab: close search */
|
||||||
|
case "Escape":
|
||||||
|
case "Tab":
|
||||||
|
setToggle("search", false)
|
||||||
|
setElementFocus(query, false)
|
||||||
|
break
|
||||||
|
|
||||||
|
/* Vertical arrows: select previous or next search result */
|
||||||
|
case "ArrowUp":
|
||||||
|
case "ArrowDown":
|
||||||
|
if (typeof active === "undefined") {
|
||||||
|
setElementFocus(query)
|
||||||
|
} else {
|
||||||
|
const els = [query, ...getElements(
|
||||||
|
":not(details) > [href], summary, details[open] [href]",
|
||||||
|
result
|
||||||
|
)]
|
||||||
|
const i = Math.max(0, (
|
||||||
|
Math.max(0, els.indexOf(active)) + els.length + (
|
||||||
|
key.type === "ArrowUp" ? -1 : +1
|
||||||
|
)
|
||||||
|
) % els.length)
|
||||||
|
setElementFocus(els[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent scrolling of page */
|
||||||
|
key.claim()
|
||||||
|
break
|
||||||
|
|
||||||
|
/* All other keys: hand to search query */
|
||||||
|
default:
|
||||||
|
if (query !== getActiveElement())
|
||||||
|
setElementFocus(query)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Set up global keyboard handlers */
|
||||||
|
keyboard$
|
||||||
|
.pipe(
|
||||||
|
filter(({ mode }) => mode === "global"),
|
||||||
|
)
|
||||||
|
.subscribe(key => {
|
||||||
|
switch (key.type) {
|
||||||
|
|
||||||
|
/* Open search and select query */
|
||||||
|
case "f":
|
||||||
|
case "s":
|
||||||
|
case "/":
|
||||||
|
setElementFocus(query)
|
||||||
|
setElementSelection(query)
|
||||||
|
key.claim()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Create and return component */
|
||||||
|
const query$ = mountSearchQuery(query as HTMLInputElement, worker)
|
||||||
return merge(
|
return merge(
|
||||||
query$,
|
query$,
|
||||||
mountSearchResult(
|
mountSearchResult(result, worker, { query$ })
|
||||||
getElementOrThrow("[data-md-component=search-result]", el),
|
|
||||||
worker, { query$ }
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
import "focus-visible"
|
import "focus-visible"
|
||||||
import { Subject, defer, merge } from "rxjs"
|
import { Subject, defer, merge } from "rxjs"
|
||||||
import {
|
import {
|
||||||
|
filter,
|
||||||
map,
|
map,
|
||||||
mergeWith,
|
mergeWith,
|
||||||
shareReplay,
|
shareReplay,
|
||||||
|
|
@ -32,9 +33,11 @@ import {
|
||||||
import { feature } from "./_"
|
import { feature } from "./_"
|
||||||
import {
|
import {
|
||||||
at,
|
at,
|
||||||
|
getElement,
|
||||||
getElementOrThrow,
|
getElementOrThrow,
|
||||||
getElements,
|
getElements,
|
||||||
watchDocument,
|
watchDocument,
|
||||||
|
watchKeyboard,
|
||||||
watchLocation,
|
watchLocation,
|
||||||
watchLocationTarget,
|
watchLocationTarget,
|
||||||
watchMedia,
|
watchMedia,
|
||||||
|
|
@ -64,7 +67,7 @@ import {
|
||||||
} from "./patches"
|
} from "./patches"
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
* Program
|
* Application
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Yay, JavaScript is available */
|
/* Yay, JavaScript is available */
|
||||||
|
|
@ -75,6 +78,7 @@ document.documentElement.classList.add("js")
|
||||||
const document$ = watchDocument()
|
const document$ = watchDocument()
|
||||||
const location$ = watchLocation()
|
const location$ = watchLocation()
|
||||||
const target$ = watchLocationTarget()
|
const target$ = watchLocationTarget()
|
||||||
|
const keyboard$ = watchKeyboard()
|
||||||
|
|
||||||
/* Set up media observables */
|
/* Set up media observables */
|
||||||
const viewport$ = watchViewport()
|
const viewport$ = watchViewport()
|
||||||
|
|
@ -90,6 +94,32 @@ setupClipboardJS({ alert$ })
|
||||||
if (feature("navigation.instant"))
|
if (feature("navigation.instant"))
|
||||||
setupInstantLoading({ document$, location$, viewport$ })
|
setupInstantLoading({ document$, location$, viewport$ })
|
||||||
|
|
||||||
|
/* Set up global keyboard handlers */
|
||||||
|
keyboard$
|
||||||
|
.pipe(
|
||||||
|
filter(({ mode }) => mode === "global")
|
||||||
|
)
|
||||||
|
.subscribe(key => {
|
||||||
|
switch (key.type) {
|
||||||
|
|
||||||
|
/* Go to previous page */
|
||||||
|
case "p":
|
||||||
|
case ",":
|
||||||
|
const prev = getElement("[href][rel=prev]")
|
||||||
|
if (typeof prev !== "undefined")
|
||||||
|
prev.click()
|
||||||
|
break
|
||||||
|
|
||||||
|
/* Go to next page */
|
||||||
|
case "n":
|
||||||
|
case ".":
|
||||||
|
const next = getElement("[href][rel=next]")
|
||||||
|
if (typeof next !== "undefined")
|
||||||
|
next.click()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/* Set up patches */
|
/* Set up patches */
|
||||||
patchIndeterminate({ document$ })
|
patchIndeterminate({ document$ })
|
||||||
patchScrollfix({ document$ })
|
patchScrollfix({ document$ })
|
||||||
|
|
@ -121,7 +151,7 @@ const control$ = merge(
|
||||||
|
|
||||||
/* Search */
|
/* Search */
|
||||||
...getElements("[data-md-component=search]")
|
...getElements("[data-md-component=search]")
|
||||||
.map(child => mountSearch(child)),
|
.map(child => mountSearch(child, { keyboard$ })),
|
||||||
|
|
||||||
/* Repository information */
|
/* Repository information */
|
||||||
...getElements("[data-md-component=source]")
|
...getElements("[data-md-component=source]")
|
||||||
|
|
@ -162,16 +192,18 @@ const component$ = document$
|
||||||
mergeWith(control$)
|
mergeWith(control$)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Subscribe to all components */
|
||||||
component$.subscribe()
|
component$.subscribe()
|
||||||
|
|
||||||
/* Export to window */
|
/* Export to window */
|
||||||
export {
|
export {
|
||||||
document$,
|
document$,
|
||||||
component$,
|
|
||||||
viewport$,
|
|
||||||
location$,
|
location$,
|
||||||
target$,
|
target$,
|
||||||
screen$,
|
keyboard$,
|
||||||
|
viewport$,
|
||||||
tablet$,
|
tablet$,
|
||||||
print$
|
screen$,
|
||||||
|
print$,
|
||||||
|
component$
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue