5-72

5-72 helps novice musicians master sound engineering by analyzing the FX chains of world-famous artists
Log | Files | Refs

commit e3025db8124d9edea764957c02be2d3cbdbca88d
parent 5179e76831640536103e02f8965181416f4f8ead
Author: Ismail Dalgatov <29144912+ismaildalgatov@users.noreply.github.com>
Date:   Wed, 24 Aug 2022 14:33:06 +0300

Update material

Diffstat:
Dsrc/.icons/logo.afdesign | 0
Dsrc/.icons/logo.svg | 6------
Dsrc/404.html | 28----------------------------
Dsrc/__init__.py | 0
Dsrc/assets/images/favicon.png | 0
Dsrc/assets/javascripts/_/index.ts | 146-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/document/index.ts | 48------------------------------------------------
Dsrc/assets/javascripts/browser/element/_/.eslintrc | 5-----
Dsrc/assets/javascripts/browser/element/_/index.ts | 120-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/element/focus/index.ts | 72------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/element/index.ts | 27---------------------------
Dsrc/assets/javascripts/browser/element/offset/_/index.ts | 86-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/element/offset/content/index.ts | 76----------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/element/offset/index.ts | 24------------------------
Dsrc/assets/javascripts/browser/element/size/_/index.ts | 142-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/element/size/content/index.ts | 43-------------------------------------------
Dsrc/assets/javascripts/browser/element/size/index.ts | 24------------------------
Dsrc/assets/javascripts/browser/element/visibility/index.ts | 131-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/index.ts | 32--------------------------------
Dsrc/assets/javascripts/browser/keyboard/index.ts | 123-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/location/_/index.ts | 61-------------------------------------------------------------
Dsrc/assets/javascripts/browser/location/hash/index.ts | 92-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/location/index.ts | 24------------------------
Dsrc/assets/javascripts/browser/media/index.ts | 95-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/request/index.ts | 101-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/script/index.ts | 70----------------------------------------------------------------------
Dsrc/assets/javascripts/browser/toggle/index.ts | 102-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/viewport/_/index.ts | 69---------------------------------------------------------------------
Dsrc/assets/javascripts/browser/viewport/at/index.ts | 84-------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/viewport/index.ts | 26--------------------------
Dsrc/assets/javascripts/browser/viewport/offset/index.ts | 78------------------------------------------------------------------------------
Dsrc/assets/javascripts/browser/viewport/size/index.ts | 71-----------------------------------------------------------------------
Dsrc/assets/javascripts/browser/worker/index.ts | 106-------------------------------------------------------------------------------
Dsrc/assets/javascripts/bundle.ts | 273-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/_/index.ts | 136-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/announce/index.ts | 110-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/consent/index.ts | 108-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/_/index.ts | 115-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/annotation/_/index.ts | 185-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/annotation/index.ts | 24------------------------
Dsrc/assets/javascripts/components/content/annotation/list/index.ts | 167-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/code/_/index.ts | 227-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/code/index.ts | 24------------------------
Dsrc/assets/javascripts/components/content/code/mermaid/index.css | 371-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/code/mermaid/index.ts | 122-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/details/index.ts | 141-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/index.ts | 28----------------------------
Dsrc/assets/javascripts/components/content/table/index.ts | 70----------------------------------------------------------------------
Dsrc/assets/javascripts/components/content/tabs/index.ts | 222-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/dialog/index.ts | 128-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/header/_/index.ts | 199-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/header/index.ts | 24------------------------
Dsrc/assets/javascripts/components/header/title/index.ts | 135-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/index.ts | 36------------------------------------
Dsrc/assets/javascripts/components/main/index.ts | 125-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/palette/index.ts | 150-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/_/index.ts | 242-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/highlight/.eslintrc | 5-----
Dsrc/assets/javascripts/components/search/highlight/index.ts | 115-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/index.ts | 28----------------------------
Dsrc/assets/javascripts/components/search/query/index.ts | 201-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/result/index.ts | 168-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/share/index.ts | 121-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/search/suggest/index.ts | 154-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/sidebar/index.ts | 180-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/source/_/index.ts | 127-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/source/facts/_/index.ts | 88-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/source/facts/github/index.ts | 103-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/source/facts/gitlab/index.ts | 61-------------------------------------------------------------
Dsrc/assets/javascripts/components/source/facts/index.ts | 25-------------------------
Dsrc/assets/javascripts/components/source/index.ts | 24------------------------
Dsrc/assets/javascripts/components/tabs/index.ts | 144-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/toc/index.ts | 331-------------------------------------------------------------------------------
Dsrc/assets/javascripts/components/top/index.ts | 176-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/clipboard/index.ts | 96-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/index.ts | 27---------------------------
Dsrc/assets/javascripts/integrations/instant/.eslintrc | 6------
Dsrc/assets/javascripts/integrations/instant/index.ts | 320-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/_/.eslintrc | 6------
Dsrc/assets/javascripts/integrations/search/_/index.ts | 325-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/document/index.ts | 107-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/highlighter/index.ts | 91-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/index.ts | 28----------------------------
Dsrc/assets/javascripts/integrations/search/options/index.ts | 48------------------------------------------------
Dsrc/assets/javascripts/integrations/search/query/_/.eslintrc | 5-----
Dsrc/assets/javascripts/integrations/search/query/_/index.ts | 93-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/query/index.ts | 24------------------------
Dsrc/assets/javascripts/integrations/search/query/transform/.eslintrc | 5-----
Dsrc/assets/javascripts/integrations/search/query/transform/index.ts | 71-----------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/worker/_/index.ts | 142-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/worker/index.ts | 24------------------------
Dsrc/assets/javascripts/integrations/search/worker/main/.eslintrc | 5-----
Dsrc/assets/javascripts/integrations/search/worker/main/index.ts | 174-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/search/worker/message/index.ts | 137-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/sitemap/index.ts | 107-------------------------------------------------------------------------------
Dsrc/assets/javascripts/integrations/version/.eslintrc | 5-----
Dsrc/assets/javascripts/integrations/version/index.ts | 174-------------------------------------------------------------------------------
Dsrc/assets/javascripts/patches/indeterminate/index.ts | 86-------------------------------------------------------------------------------
Dsrc/assets/javascripts/patches/index.ts | 25-------------------------
Dsrc/assets/javascripts/patches/scrollfix/index.ts | 100-------------------------------------------------------------------------------
Dsrc/assets/javascripts/patches/scrolllock/index.ts | 89-------------------------------------------------------------------------------
Dsrc/assets/javascripts/polyfills/index.ts | 96-------------------------------------------------------------------------------
Dsrc/assets/javascripts/templates/annotation/index.tsx | 47-----------------------------------------------
Dsrc/assets/javascripts/templates/clipboard/index.tsx | 45---------------------------------------------
Dsrc/assets/javascripts/templates/index.ts | 29-----------------------------
Dsrc/assets/javascripts/templates/search/index.tsx | 162-------------------------------------------------------------------------------
Dsrc/assets/javascripts/templates/source/index.tsx | 47-----------------------------------------------
Dsrc/assets/javascripts/templates/tabbed/index.tsx | 56--------------------------------------------------------
Dsrc/assets/javascripts/templates/table/index.tsx | 44--------------------------------------------
Dsrc/assets/javascripts/templates/version/index.tsx | 92-------------------------------------------------------------------------------
Dsrc/assets/javascripts/utilities/h/.eslintrc | 7-------
Dsrc/assets/javascripts/utilities/h/index.ts | 131-------------------------------------------------------------------------------
Dsrc/assets/javascripts/utilities/index.ts | 24------------------------
Dsrc/assets/javascripts/utilities/string/index.ts | 72------------------------------------------------------------------------
Dsrc/assets/javascripts/workers/search.ts | 23-----------------------
Dsrc/assets/stylesheets/_config.scss | 42------------------------------------------
Dsrc/assets/stylesheets/main.scss | 80-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/_colors.scss | 134-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/_icons.scss | 37-------------------------------------
Dsrc/assets/stylesheets/main/_modifiers.scss | 58----------------------------------------------------------
Dsrc/assets/stylesheets/main/_resets.scss | 118-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/_typeset.scss | 619-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/markdown/_admonition.scss | 183-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/markdown/_footnotes.scss | 145-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/markdown/_toc.scss | 92-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss | 52----------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_critic.scss | 78------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_details.scss | 116-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_emoji.scss | 43-------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_highlight.scss | 381-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_keys.scss | 115-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss | 393-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss | 79-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/integrations/_mermaid.scss | 43-------------------------------------------
Dsrc/assets/stylesheets/main/layout/_banner.scss | 63---------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_base.scss | 183-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_clipboard.scss | 101-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_consent.scss | 127-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_content.scss | 102-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_dialog.scss | 65-----------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_feedback.scss | 110-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_footer.scss | 202-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_form.scss | 83-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_header.scss | 262-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_nav.scss | 642-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_search.scss | 713-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_select.scss | 115-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_sidebar.scss | 181-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_source.scss | 181-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_tabs.scss | 110-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_tag.scss | 65-----------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_tooltip.scss | 253-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_top.scss | 82-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/main/layout/_version.scss | 149-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/palette.scss | 40----------------------------------------
Dsrc/assets/stylesheets/palette/_accent.scss | 61-------------------------------------------------------------
Dsrc/assets/stylesheets/palette/_primary.scss | 193-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/palette/_scheme.scss | 152-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/utilities/_break.scss | 219-------------------------------------------------------------------------------
Dsrc/assets/stylesheets/utilities/_convert.scss | 79-------------------------------------------------------------------------------
Dsrc/base.html | 412-------------------------------------------------------------------------------
Dsrc/main.html | 23-----------------------
Dsrc/mkdocs_theme.yml | 68--------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/bundle.ts | 55-------------------------------------------------------
Dsrc/overrides/assets/javascripts/components/_/index.ts | 104-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/components/iconsearch/_/index.ts | 94-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/components/iconsearch/index.ts | 25-------------------------
Dsrc/overrides/assets/javascripts/components/iconsearch/query/index.ts | 96-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/components/iconsearch/result/index.ts | 237-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/components/index.ts | 25-------------------------
Dsrc/overrides/assets/javascripts/components/sponsorship/index.ts | 149-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/integrations/analytics/index.ts | 42------------------------------------------
Dsrc/overrides/assets/javascripts/integrations/index.ts | 23-----------------------
Dsrc/overrides/assets/javascripts/templates/iconsearch/index.tsx | 95-------------------------------------------------------------------------------
Dsrc/overrides/assets/javascripts/templates/index.ts | 24------------------------
Dsrc/overrides/assets/javascripts/templates/sponsorship/index.tsx | 67-------------------------------------------------------------------
Dsrc/overrides/assets/stylesheets/main.scss | 46----------------------------------------------
Dsrc/overrides/assets/stylesheets/main/_shame.scss | 25-------------------------
Dsrc/overrides/assets/stylesheets/main/_typeset.scss | 165-------------------------------------------------------------------------------
Dsrc/overrides/assets/stylesheets/main/layout/_banner.scss | 46----------------------------------------------
Dsrc/overrides/assets/stylesheets/main/layout/_hero.scss | 124-------------------------------------------------------------------------------
Dsrc/overrides/assets/stylesheets/main/layout/_iconsearch.scss | 137-------------------------------------------------------------------------------
Dsrc/overrides/assets/stylesheets/main/layout/_sponsorship.scss | 129-------------------------------------------------------------------------------
Dsrc/overrides/blog.html | 76----------------------------------------------------------------------------
Dsrc/overrides/home.html | 106-------------------------------------------------------------------------------
Dsrc/overrides/main.html | 57---------------------------------------------------------
Dsrc/overrides/partials/content.html | 68--------------------------------------------------------------------
Dsrc/partials/consent.html | 91-------------------------------------------------------------------------------
Dsrc/partials/content.html | 59-----------------------------------------------------------
Dsrc/partials/copyright.html | 33---------------------------------
Dsrc/partials/feedback.html | 85-------------------------------------------------------------------------------
Dsrc/partials/footer.html | 96-------------------------------------------------------------------------------
Dsrc/partials/header.html | 161-------------------------------------------------------------------------------
Dsrc/partials/icons.html | 37-------------------------------------
Dsrc/partials/integrations/analytics.html | 49-------------------------------------------------
Dsrc/partials/integrations/analytics/google.html | 168-------------------------------------------------------------------------------
Dsrc/partials/javascripts/announce.html | 31-------------------------------
Dsrc/partials/javascripts/base.html | 48------------------------------------------------
Dsrc/partials/javascripts/consent.html | 62--------------------------------------------------------------
Dsrc/partials/javascripts/content.html | 39---------------------------------------
Dsrc/partials/javascripts/outdated.html | 29-----------------------------
Dsrc/partials/javascripts/palette.html | 29-----------------------------
Dsrc/partials/language.html | 28----------------------------
Dsrc/partials/languages/af.html | 44--------------------------------------------
Dsrc/partials/languages/ar.html | 45---------------------------------------------
Dsrc/partials/languages/bg.html | 51---------------------------------------------------
Dsrc/partials/languages/bn.html | 49-------------------------------------------------
Dsrc/partials/languages/ca.html | 43-------------------------------------------
Dsrc/partials/languages/cs.html | 43-------------------------------------------
Dsrc/partials/languages/da.html | 44--------------------------------------------
Dsrc/partials/languages/de.html | 58----------------------------------------------------------
Dsrc/partials/languages/el.html | 58----------------------------------------------------------
Dsrc/partials/languages/en.html | 65-----------------------------------------------------------------
Dsrc/partials/languages/eo.html | 49-------------------------------------------------
Dsrc/partials/languages/es.html | 58----------------------------------------------------------
Dsrc/partials/languages/et.html | 43-------------------------------------------
Dsrc/partials/languages/fa.html | 45---------------------------------------------
Dsrc/partials/languages/fi.html | 44--------------------------------------------
Dsrc/partials/languages/fr.html | 59-----------------------------------------------------------
Dsrc/partials/languages/gl.html | 56--------------------------------------------------------
Dsrc/partials/languages/he.html | 63---------------------------------------------------------------
Dsrc/partials/languages/hi.html | 44--------------------------------------------
Dsrc/partials/languages/hr.html | 61-------------------------------------------------------------
Dsrc/partials/languages/hu.html | 53-----------------------------------------------------
Dsrc/partials/languages/hy.html | 58----------------------------------------------------------
Dsrc/partials/languages/id.html | 43-------------------------------------------
Dsrc/partials/languages/is.html | 50--------------------------------------------------
Dsrc/partials/languages/it.html | 58----------------------------------------------------------
Dsrc/partials/languages/ja.html | 55-------------------------------------------------------
Dsrc/partials/languages/ka.html | 49-------------------------------------------------
Dsrc/partials/languages/kr.html | 54------------------------------------------------------
Dsrc/partials/languages/lt.html | 58----------------------------------------------------------
Dsrc/partials/languages/lv.html | 55-------------------------------------------------------
Dsrc/partials/languages/mk.html | 56--------------------------------------------------------
Dsrc/partials/languages/mn.html | 51---------------------------------------------------
Dsrc/partials/languages/ms.html | 55-------------------------------------------------------
Dsrc/partials/languages/my.html | 49-------------------------------------------------
Dsrc/partials/languages/nl.html | 44--------------------------------------------
Dsrc/partials/languages/nn.html | 44--------------------------------------------
Dsrc/partials/languages/no.html | 44--------------------------------------------
Dsrc/partials/languages/pl.html | 53-----------------------------------------------------
Dsrc/partials/languages/pt-BR.html | 57---------------------------------------------------------
Dsrc/partials/languages/pt.html | 58----------------------------------------------------------
Dsrc/partials/languages/ro.html | 44--------------------------------------------
Dsrc/partials/languages/ru.html | 58----------------------------------------------------------
Dsrc/partials/languages/sh.html | 57---------------------------------------------------------
Dsrc/partials/languages/si.html | 51---------------------------------------------------
Dsrc/partials/languages/sk.html | 43-------------------------------------------
Dsrc/partials/languages/sl.html | 43-------------------------------------------
Dsrc/partials/languages/sr.html | 57---------------------------------------------------------
Dsrc/partials/languages/sv.html | 60------------------------------------------------------------
Dsrc/partials/languages/th.html | 44--------------------------------------------
Dsrc/partials/languages/tl.html | 57---------------------------------------------------------
Dsrc/partials/languages/tr.html | 44--------------------------------------------
Dsrc/partials/languages/uk.html | 44--------------------------------------------
Dsrc/partials/languages/ur.html | 59-----------------------------------------------------------
Dsrc/partials/languages/uz.html | 58----------------------------------------------------------
Dsrc/partials/languages/vi.html | 44--------------------------------------------
Dsrc/partials/languages/zh-Hant.html | 47-----------------------------------------------
Dsrc/partials/languages/zh-TW.html | 53-----------------------------------------------------
Dsrc/partials/languages/zh.html | 64----------------------------------------------------------------
Dsrc/partials/logo.html | 29-----------------------------
Dsrc/partials/nav-item.html | 170-------------------------------------------------------------------------------
Dsrc/partials/nav.html | 68--------------------------------------------------------------------
Dsrc/partials/palette.html | 66------------------------------------------------------------------
Dsrc/partials/search.html | 103-------------------------------------------------------------------------------
Dsrc/partials/social.html | 40----------------------------------------
Dsrc/partials/source-file.html | 44--------------------------------------------
Dsrc/partials/source.html | 37-------------------------------------
Dsrc/partials/tabs-item.html | 56--------------------------------------------------------
Dsrc/partials/tabs.html | 39---------------------------------------
Dsrc/partials/tags.html | 41-----------------------------------------
Dsrc/partials/toc-item.html | 39---------------------------------------
Dsrc/partials/toc.html | 56--------------------------------------------------------
Dsrc/plugins/__init__.py | 0
Dsrc/plugins/search/__init__.py | 0
Dsrc/plugins/search/plugin.py | 55-------------------------------------------------------
Dsrc/plugins/tags/__init__.py | 0
Dsrc/plugins/tags/plugin.py | 138-------------------------------------------------------------------------------
279 files changed, 0 insertions(+), 25598 deletions(-)

diff --git a/src/.icons/logo.afdesign b/src/.icons/logo.afdesign Binary files differ. diff --git a/src/.icons/logo.svg b/src/.icons/logo.svg @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 89"> - <path d="M3.136,17.387l0,42.932l42.932,21.467l-42.932,-64.399Z" /> - <path d="M21.91,8l42.933,64.398l-18.775,9.388l-42.932,-64.399l18.774,-9.387Z" style="fill-opacity: 0.5" /> - <path d="M67.535,17.387l-27.262,18.156l21.878,32.818l5.384,2.691l0,-53.665Z" /> - <path d="M67.535,17.387l0,53.666l18.774,-9.388l0,-53.665l-18.774,9.387Z" style="fill-opacity: 0.25" /> -</svg> diff --git a/src/404.html b/src/404.html @@ -1,28 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -{% extends "main.html" %} - -<!-- Content --> -{% block content %} - <h1>404 - Not found</h1> -{% endblock %} diff --git a/src/__init__.py b/src/__init__.py diff --git a/src/assets/images/favicon.png b/src/assets/images/favicon.png Binary files differ. diff --git a/src/assets/javascripts/_/index.ts b/src/assets/javascripts/_/index.ts @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { getElement, getLocation } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Feature flag - */ -export type Flag = - | "announce.dismiss" /* Dismissable announcement bar */ - | "content.code.annotate" /* Code annotations */ - | "content.tabs.link" /* Link content tabs */ - | "header.autohide" /* Hide header */ - | "navigation.expand" /* Automatic expansion */ - | "navigation.indexes" /* Section pages */ - | "navigation.instant" /* Instant loading */ - | "navigation.sections" /* Section navigation */ - | "navigation.tabs" /* Tabs navigation */ - | "navigation.tabs.sticky" /* Tabs navigation (sticky) */ - | "navigation.top" /* Back-to-top button */ - | "navigation.tracking" /* Anchor tracking */ - | "search.highlight" /* Search highlighting */ - | "search.share" /* Search sharing */ - | "search.suggest" /* Search suggestions */ - | "toc.integrate" /* Integrated table of contents */ - -/* ------------------------------------------------------------------------- */ - -/** - * Translation - */ -export type Translation = - | "clipboard.copy" /* Copy to clipboard */ - | "clipboard.copied" /* Copied to clipboard */ - | "search.config.lang" /* Search language */ - | "search.config.pipeline" /* Search pipeline */ - | "search.config.separator" /* Search separator */ - | "search.placeholder" /* Search */ - | "search.result.placeholder" /* Type to start searching */ - | "search.result.none" /* No matching documents */ - | "search.result.one" /* 1 matching document */ - | "search.result.other" /* # matching documents */ - | "search.result.more.one" /* 1 more on this page */ - | "search.result.more.other" /* # more on this page */ - | "search.result.term.missing" /* Missing */ - | "select.version.title" /* Version selector */ - -/** - * Translations - */ -export type Translations = Record<Translation, string> - -/* ------------------------------------------------------------------------- */ - -/** - * Versioning - */ -export interface Versioning { - provider: "mike" /* Version provider */ - default?: string /* Default version */ -} - -/** - * Configuration - */ -export interface Config { - base: string /* Base URL */ - features: Flag[] /* Feature flags */ - translations: Translations /* Translations */ - search: string /* Search worker URL */ - version?: Versioning /* Versioning */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration and make base URL absolute - */ -const script = getElement("#__config") -const config: Config = JSON.parse(script.textContent!) -config.base = `${new URL(config.base, getLocation())}` - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration - * - * @returns Global configuration - */ -export function configuration(): Config { - return config -} - -/** - * Check whether a feature flag is enabled - * - * @param flag - Feature flag - * - * @returns Test result - */ -export function feature(flag: Flag): boolean { - return config.features.includes(flag) -} - -/** - * Retrieve the translation for the given key - * - * @param key - Key to be translated - * @param value - Positional value, if any - * - * @returns Translation - */ -export function translation( - key: Translation, value?: string | number -): string { - return typeof value !== "undefined" - ? config.translations[key].replace("#", value.toString()) - : config.translations[key] -} diff --git a/src/assets/javascripts/browser/document/index.ts b/src/assets/javascripts/browser/document/index.ts @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - ReplaySubject, - Subject, - fromEvent -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch document - * - * Documents are implemented as subjects, so all downstream observables are - * automatically updated when a new document is emitted. - * - * @returns Document subject - */ -export function watchDocument(): Subject<Document> { - const document$ = new ReplaySubject<Document>(1) - fromEvent(document, "DOMContentLoaded", { once: true }) - .subscribe(() => document$.next(document)) - - /* Return document */ - return document$ -} diff --git a/src/assets/javascripts/browser/element/_/.eslintrc b/src/assets/javascripts/browser/element/_/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "jsdoc/require-jsdoc": "off" - } -} diff --git a/src/assets/javascripts/browser/element/_/index.ts b/src/assets/javascripts/browser/element/_/index.ts @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve all elements matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Elements - */ -export function getElements<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T][] - -export function getElements<T extends HTMLElement>( - selector: string, node?: ParentNode -): T[] - -export function getElements<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T[] { - return Array.from(node.querySelectorAll<T>(selector)) -} - -/** - * Retrieve an element matching a query selector or throw a reference error - * - * Note that this function assumes that the element is present. If unsure if an - * element is existent, use the `getOptionalElement` function instead. - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element - */ -export function getElement<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] - -export function getElement<T extends HTMLElement>( - selector: string, node?: ParentNode -): T - -export function getElement<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T { - const el = getOptionalElement<T>(selector, node) - if (typeof el === "undefined") - throw new ReferenceError( - `Missing element: expected "${selector}" to be present` - ) - - /* Return element */ - return el -} - -/* ------------------------------------------------------------------------- */ - -/** - * Retrieve an optional element matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element or nothing - */ -export function getOptionalElement<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] | undefined - -export function getOptionalElement<T extends HTMLElement>( - selector: string, node?: ParentNode -): T | undefined - -export function getOptionalElement<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T | undefined { - return node.querySelector<T>(selector) || undefined -} - -/** - * Retrieve the currently active element - * - * @returns Element or nothing - */ -export function getActiveElement(): HTMLElement | undefined { - return document.activeElement instanceof HTMLElement - ? document.activeElement || undefined - : undefined -} diff --git a/src/assets/javascripts/browser/element/focus/index.ts b/src/assets/javascripts/browser/element/focus/index.ts @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - debounceTime, - distinctUntilChanged, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -import { getActiveElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch element focus - * - * Previously, this function used `focus` and `blur` events to determine whether - * an element is focused, but this doesn't work if there are focusable elements - * within the elements itself. A better solutions are `focusin` and `focusout` - * events, which bubble up the tree and allow for more fine-grained control. - * - * `debounceTime` is necessary, because when a focus change happens inside an - * element, the observable would first emit `false` and then `true` again. - * - * @param el - Element - * - * @returns Element focus observable - */ -export function watchElementFocus( - el: HTMLElement -): Observable<boolean> { - return merge( - fromEvent(document.body, "focusin"), - fromEvent(document.body, "focusout") - ) - .pipe( - debounceTime(1), - map(() => { - const active = getActiveElement() - return typeof active !== "undefined" - ? el.contains(active) - : false - }), - startWith(el === getActiveElement()), - distinctUntilChanged() - ) -} diff --git a/src/assets/javascripts/browser/element/index.ts b/src/assets/javascripts/browser/element/index.ts @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./focus" -export * from "./offset" -export * from "./size" -export * from "./visibility" diff --git a/src/assets/javascripts/browser/element/offset/_/index.ts b/src/assets/javascripts/browser/element/offset/_/index.ts @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - animationFrameScheduler, - auditTime, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element offset - * - * @param el - Element - * - * @returns Element offset - */ -export function getElementOffset( - el: HTMLElement -): ElementOffset { - return { - x: el.offsetLeft, - y: el.offsetTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element offset - * - * @param el - Element - * - * @returns Element offset observable - */ -export function watchElementOffset( - el: HTMLElement -): Observable<ElementOffset> { - return merge( - fromEvent(window, "load"), - fromEvent(window, "resize") - ) - .pipe( - auditTime(0, animationFrameScheduler), - map(() => getElementOffset(el)), - startWith(getElementOffset(el)) - ) -} diff --git a/src/assets/javascripts/browser/element/offset/content/index.ts b/src/assets/javascripts/browser/element/offset/content/index.ts @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - animationFrameScheduler, - auditTime, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -import { ElementOffset } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element content offset (= scroll offset) - * - * @param el - Element - * - * @returns Element content offset - */ -export function getElementContentOffset( - el: HTMLElement -): ElementOffset { - return { - x: el.scrollLeft, - y: el.scrollTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element content offset - * - * @param el - Element - * - * @returns Element content offset observable - */ -export function watchElementContentOffset( - el: HTMLElement -): Observable<ElementOffset> { - return merge( - fromEvent(el, "scroll"), - fromEvent(window, "resize") - ) - .pipe( - auditTime(0, animationFrameScheduler), - map(() => getElementContentOffset(el)), - startWith(getElementContentOffset(el)) - ) -} diff --git a/src/assets/javascripts/browser/element/offset/index.ts b/src/assets/javascripts/browser/element/offset/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./content" diff --git a/src/assets/javascripts/browser/element/size/_/index.ts b/src/assets/javascripts/browser/element/size/_/index.ts @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 ResizeObserver from "resize-observer-polyfill" -import { - NEVER, - Observable, - Subject, - defer, - filter, - finalize, - map, - merge, - of, - shareReplay, - startWith, - switchMap, - tap -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementSize { - width: number /* Element width */ - height: number /* Element height */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Resize observer entry subject - */ -const entry$ = new Subject<ResizeObserverEntry>() - -/** - * Resize observer observable - * - * This observable will create a `ResizeObserver` on the first subscription - * and will automatically terminate it when there are no more subscribers. - * It's quite important to centralize observation in a single `ResizeObserver`, - * as the performance difference can be quite dramatic, as the link shows. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => of( - new ResizeObserver(entries => { - for (const entry of entries) - entry$.next(entry) - }) -)) - .pipe( - switchMap(observer => merge(NEVER, of(observer)) - .pipe( - finalize(() => observer.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element size - * - * @param el - Element - * - * @returns Element size - */ -export function getElementSize( - el: HTMLElement -): ElementSize { - return { - width: el.offsetWidth, - height: el.offsetHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element size - * - * This function returns an observable that subscribes to a single internal - * instance of `ResizeObserver` upon subscription, and emit resize events until - * termination. Note that this function should not be called with the same - * element twice, as the first unsubscription will terminate observation. - * - * Sadly, we can't use the `DOMRect` objects returned by the observer, because - * we need the emitted values to be consistent with `getElementSize`, which will - * return the used values (rounded) and not actual values (unrounded). Thus, we - * use the `offset*` properties. See the linked GitHub issue. - * - * @see https://bit.ly/3m0k3he - GitHub issue - * - * @param el - Element - * - * @returns Element size observable - */ -export function watchElementSize( - el: HTMLElement -): Observable<ElementSize> { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(() => getElementSize(el)) - ) - ), - startWith(getElementSize(el)) - ) -} diff --git a/src/assets/javascripts/browser/element/size/content/index.ts b/src/assets/javascripts/browser/element/size/content/index.ts @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { ElementSize } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element content size (= scroll width and height) - * - * @param el - Element - * - * @returns Element content size - */ -export function getElementContentSize( - el: HTMLElement -): ElementSize { - return { - width: el.scrollWidth, - height: el.scrollHeight - } -} diff --git a/src/assets/javascripts/browser/element/size/index.ts b/src/assets/javascripts/browser/element/size/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./content" diff --git a/src/assets/javascripts/browser/element/visibility/index.ts b/src/assets/javascripts/browser/element/visibility/index.ts @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - NEVER, - Observable, - Subject, - defer, - distinctUntilChanged, - filter, - finalize, - map, - merge, - of, - shareReplay, - switchMap, - tap -} from "rxjs" - -import { - getElementContentSize, - getElementSize, - watchElementContentOffset -} from "~/browser" - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Intersection observer entry subject - */ -const entry$ = new Subject<IntersectionObserverEntry>() - -/** - * Intersection observer observable - * - * This observable will create an `IntersectionObserver` on first subscription - * and will automatically terminate it when there are no more subscribers. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => of( - new IntersectionObserver(entries => { - for (const entry of entries) - entry$.next(entry) - }, { - threshold: 0 - }) -)) - .pipe( - switchMap(observer => merge(NEVER, of(observer)) - .pipe( - finalize(() => observer.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch element visibility - * - * @param el - Element - * - * @returns Element visibility observable - */ -export function watchElementVisibility( - el: HTMLElement -): Observable<boolean> { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(({ isIntersecting }) => isIntersecting) - ) - ) - ) -} - -/** - * Watch element boundary - * - * This function returns an observable which emits whether the bottom content - * boundary (= scroll offset) of an element is within a certain threshold. - * - * @param el - Element - * @param threshold - Threshold - * - * @returns Element boundary observable - */ -export function watchElementBoundary( - el: HTMLElement, threshold = 16 -): Observable<boolean> { - return watchElementContentOffset(el) - .pipe( - map(({ y }) => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return y >= ( - content.height - visible.height - threshold - ) - }), - distinctUntilChanged() - ) -} diff --git a/src/assets/javascripts/browser/index.ts b/src/assets/javascripts/browser/index.ts @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./document" -export * from "./element" -export * from "./keyboard" -export * from "./location" -export * from "./media" -export * from "./request" -export * from "./script" -export * from "./toggle" -export * from "./viewport" -export * from "./worker" diff --git a/src/assets/javascripts/browser/keyboard/index.ts b/src/assets/javascripts/browser/keyboard/index.ts @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - filter, - fromEvent, - map, - share -} from "rxjs" - -import { getActiveElement } from "../element" -import { getToggle } from "../toggle" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Keyboard mode - */ -export type KeyboardMode = - | "global" /* Global */ - | "search" /* Search is open */ - -/* ------------------------------------------------------------------------- */ - -/** - * Keyboard - */ -export interface Keyboard { - mode: KeyboardMode /* Keyboard mode */ - type: string /* Key type */ - claim(): void /* Key claim */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether an element may receive keyboard input - * - * @param el - Element - * @param type - Key type - * - * @returns Test result - */ -function isSusceptibleToKeyboard( - el: HTMLElement, type: string -): boolean { - switch (el.constructor) { - - /* Input elements */ - case HTMLInputElement: - /* @ts-expect-error - omit unnecessary type cast */ - if (el.type === "radio") - return /^Arrow/.test(type) - else - return true - - /* Select element and textarea */ - case HTMLSelectElement: - case HTMLTextAreaElement: - return true - - /* Everything else */ - default: - return el.isContentEditable - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch keyboard - * - * @returns Keyboard observable - */ -export function watchKeyboard(): Observable<Keyboard> { - return fromEvent<KeyboardEvent>(window, "keydown") - .pipe( - filter(ev => !(ev.metaKey || ev.ctrlKey)), - map(ev => ({ - mode: getToggle("search") ? "search" : "global", - type: ev.key, - claim() { - ev.preventDefault() - ev.stopPropagation() - } - } as Keyboard)), - filter(({ mode, type }) => { - if (mode === "global") { - const active = getActiveElement() - if (typeof active !== "undefined") - return !isSusceptibleToKeyboard(active, type) - } - return true - }), - share() - ) -} diff --git a/src/assets/javascripts/browser/location/_/index.ts b/src/assets/javascripts/browser/location/_/index.ts @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Subject } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location - * - * This function returns a `URL` object (and not `Location`) to normalize the - * typings across the application. Furthermore, locations need to be tracked - * without setting them and `Location` is a singleton which represents the - * current location. - * - * @returns URL - */ -export function getLocation(): URL { - return new URL(location.href) -} - -/** - * Set location - * - * @param url - URL to change to - */ -export function setLocation(url: URL): void { - location.href = url.href -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location - * - * @returns Location subject - */ -export function watchLocation(): Subject<URL> { - return new Subject<URL>() -} diff --git a/src/assets/javascripts/browser/location/hash/index.ts b/src/assets/javascripts/browser/location/hash/index.ts @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - filter, - fromEvent, - map, - shareReplay, - startWith -} from "rxjs" - -import { getOptionalElement } from "~/browser" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location hash - * - * @returns Location hash - */ -export function getLocationHash(): string { - return location.hash.substring(1) -} - -/** - * Set location hash - * - * Setting a new fragment identifier via `location.hash` will have no effect - * if the value doesn't change. When a new fragment identifier is set, we want - * the browser to target the respective element at all times, which is why we - * use this dirty little trick. - * - * @param hash - Location hash - */ -export function setLocationHash(hash: string): void { - const el = h("a", { href: hash }) - el.addEventListener("click", ev => ev.stopPropagation()) - el.click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location hash - * - * @returns Location hash observable - */ -export function watchLocationHash(): Observable<string> { - return fromEvent<HashChangeEvent>(window, "hashchange") - .pipe( - map(getLocationHash), - startWith(getLocationHash()), - filter(hash => hash.length > 0), - shareReplay(1) - ) -} - -/** - * Watch location target - * - * @returns Location target observable - */ -export function watchLocationTarget(): Observable<HTMLElement> { - return watchLocationHash() - .pipe( - map(id => getOptionalElement(`[id="${id}"]`)!), - filter(el => typeof el !== "undefined") - ) -} diff --git a/src/assets/javascripts/browser/location/index.ts b/src/assets/javascripts/browser/location/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./hash" diff --git a/src/assets/javascripts/browser/media/index.ts b/src/assets/javascripts/browser/media/index.ts @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - fromEvent, - fromEventPattern, - map, - merge, - startWith, - switchMap -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch media query - * - * Note that although `MediaQueryList.addListener` is deprecated we have to - * use it, because it's the only way to ensure proper downward compatibility. - * - * @see https://bit.ly/3dUBH2m - GitHub issue - * - * @param query - Media query - * - * @returns Media observable - */ -export function watchMedia(query: string): Observable<boolean> { - const media = matchMedia(query) - return fromEventPattern<boolean>(next => ( - media.addListener(() => next(media.matches)) - )) - .pipe( - startWith(media.matches) - ) -} - -/** - * Watch print mode - * - * @returns Print observable - */ -export function watchPrint(): Observable<boolean> { - const media = matchMedia("print") - return merge( - fromEvent(window, "beforeprint").pipe(map(() => true)), - fromEvent(window, "afterprint").pipe(map(() => false)) - ) - .pipe( - startWith(media.matches) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Toggle an observable with a media observable - * - * @template T - Data type - * - * @param query$ - Media observable - * @param factory - Observable factory - * - * @returns Toggled observable - */ -export function at<T>( - query$: Observable<boolean>, factory: () => Observable<T> -): Observable<T> { - return query$ - .pipe( - switchMap(active => active ? factory() : EMPTY) - ) -} diff --git a/src/assets/javascripts/browser/request/index.ts b/src/assets/javascripts/browser/request/index.ts @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - catchError, - from, - map, - of, - shareReplay, - switchMap, - throwError -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch the given URL - * - * If the request fails (e.g. when dispatched from `file://` locations), the - * observable will complete without emitting a value. - * - * @param url - Request URL - * @param options - Options - * - * @returns Response observable - */ -export function request( - url: URL | string, options: RequestInit = { credentials: "same-origin" } -): Observable<Response> { - return from(fetch(`${url}`, options)) - .pipe( - catchError(() => EMPTY), - switchMap(res => res.status !== 200 - ? throwError(() => new Error(res.statusText)) - : of(res) - ) - ) -} - -/** - * Fetch JSON from the given URL - * - * @template T - Data type - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestJSON<T>( - url: URL | string, options?: RequestInit -): Observable<T> { - return request(url, options) - .pipe( - switchMap(res => res.json()), - shareReplay(1) - ) -} - -/** - * Fetch XML from the given URL - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestXML( - url: URL | string, options?: RequestInit -): Observable<Document> { - const dom = new DOMParser() - return request(url, options) - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/xml")), - shareReplay(1) - ) -} diff --git a/src/assets/javascripts/browser/script/index.ts b/src/assets/javascripts/browser/script/index.ts @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - defer, - finalize, - fromEvent, - map, - merge, - switchMap, - take, - throwError -} from "rxjs" - -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create and load a `script` element - * - * This function returns an observable that will emit when the script was - * successfully loaded, or throw an error if it didn't. - * - * @param src - Script URL - * - * @returns Script observable - */ -export function watchScript(src: string): Observable<void> { - const script = h("script", { src }) - return defer(() => { - document.head.appendChild(script) - return merge( - fromEvent(script, "load"), - fromEvent(script, "error") - .pipe( - switchMap(() => ( - throwError(() => new ReferenceError(`Invalid script: ${src}`)) - )) - ) - ) - .pipe( - map(() => undefined), - finalize(() => document.head.removeChild(script)), - take(1) - ) - }) -} diff --git a/src/assets/javascripts/browser/toggle/index.ts b/src/assets/javascripts/browser/toggle/index.ts @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - fromEvent, - map, - startWith -} from "rxjs" - -import { getElement } from "../element" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Toggle - */ -export type Toggle = - | "drawer" /* Toggle for drawer */ - | "search" /* Toggle for search */ - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Toggle map - */ -const toggles: Record<Toggle, HTMLInputElement> = { - drawer: getElement("[data-md-toggle=drawer]"), - search: getElement("[data-md-toggle=search]") -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the value of a toggle - * - * @param name - Toggle - * - * @returns Toggle value - */ -export function getToggle(name: Toggle): boolean { - return toggles[name].checked -} - -/** - * Set toggle - * - * Simulating a click event seems to be the most cross-browser compatible way - * of changing the value while also emitting a `change` event. Before, Material - * used `CustomEvent` to programmatically change the value of a toggle, but this - * is a much simpler and cleaner solution which doesn't require a polyfill. - * - * @param name - Toggle - * @param value - Toggle value - */ -export function setToggle(name: Toggle, value: boolean): void { - if (toggles[name].checked !== value) - toggles[name].click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch toggle - * - * @param name - Toggle - * - * @returns Toggle value observable - */ -export function watchToggle(name: Toggle): Observable<boolean> { - const el = toggles[name] - return fromEvent(el, "change") - .pipe( - map(() => el.checked), - startWith(el.checked) - ) -} diff --git a/src/assets/javascripts/browser/viewport/_/index.ts b/src/assets/javascripts/browser/viewport/_/index.ts @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - combineLatest, - map, - shareReplay -} from "rxjs" - -import { - ViewportOffset, - watchViewportOffset -} from "../offset" -import { - ViewportSize, - watchViewportSize -} from "../size" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport - */ -export interface Viewport { - offset: ViewportOffset /* Viewport offset */ - size: ViewportSize /* Viewport size */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch viewport - * - * @returns Viewport observable - */ -export function watchViewport(): Observable<Viewport> { - return combineLatest([ - watchViewportOffset(), - watchViewportSize() - ]) - .pipe( - map(([offset, size]) => ({ offset, size })), - shareReplay(1) - ) -} diff --git a/src/assets/javascripts/browser/viewport/at/index.ts b/src/assets/javascripts/browser/viewport/at/index.ts @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - combineLatest, - distinctUntilKeyChanged, - map -} from "rxjs" - -import { Header } from "~/components" - -import { getElementOffset } from "../../element" -import { Viewport } from "../_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch viewport relative to element - * - * @param el - Element - * @param options - Options - * - * @returns Viewport observable - */ -export function watchViewportAt( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<Viewport> { - const size$ = viewport$ - .pipe( - distinctUntilKeyChanged("size") - ) - - /* Compute element offset */ - const offset$ = combineLatest([size$, header$]) - .pipe( - map(() => getElementOffset(el)) - ) - - /* Compute relative viewport, return hot observable */ - return combineLatest([header$, viewport$, offset$]) - .pipe( - map(([{ height }, { offset, size }, { x, y }]) => ({ - offset: { - x: offset.x - x, - y: offset.y - y + height - }, - size - })) - ) -} diff --git a/src/assets/javascripts/browser/viewport/index.ts b/src/assets/javascripts/browser/viewport/index.ts @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./at" -export * from "./offset" -export * from "./size" diff --git a/src/assets/javascripts/browser/viewport/offset/index.ts b/src/assets/javascripts/browser/viewport/offset/index.ts @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport offset - */ -export interface ViewportOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport offset - * - * On iOS Safari, viewport offset can be negative due to overflow scrolling. - * As this may induce strange behaviors downstream, we'll just limit it to 0. - * - * @returns Viewport offset - */ -export function getViewportOffset(): ViewportOffset { - return { - x: Math.max(0, scrollX), - y: Math.max(0, scrollY) - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport offset - * - * @returns Viewport offset observable - */ -export function watchViewportOffset(): Observable<ViewportOffset> { - return merge( - fromEvent(window, "scroll", { passive: true }), - fromEvent(window, "resize", { passive: true }) - ) - .pipe( - map(getViewportOffset), - startWith(getViewportOffset()) - ) -} diff --git a/src/assets/javascripts/browser/viewport/size/index.ts b/src/assets/javascripts/browser/viewport/size/index.ts @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - fromEvent, - map, - startWith -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport size - */ -export interface ViewportSize { - width: number /* Viewport width */ - height: number /* Viewport height */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport size - * - * @returns Viewport size - */ -export function getViewportSize(): ViewportSize { - return { - width: innerWidth, - height: innerHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport size - * - * @returns Viewport size observable - */ -export function watchViewportSize(): Observable<ViewportSize> { - return fromEvent(window, "resize", { passive: true }) - .pipe( - map(getViewportSize), - startWith(getViewportSize()) - ) -} diff --git a/src/assets/javascripts/browser/worker/index.ts b/src/assets/javascripts/browser/worker/index.ts @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - fromEvent, - map, - share, - switchMap, - tap, - throttle -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Worker message - */ -export interface WorkerMessage { - type: unknown /* Message type */ - data?: unknown /* Message data */ -} - -/** - * Worker handler - * - * @template T - Message type - */ -export interface WorkerHandler< - T extends WorkerMessage -> { - tx$: Subject<T> /* Message transmission subject */ - rx$: Observable<T> /* Message receive observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - * - * @template T - Worker message type - */ -interface WatchOptions<T extends WorkerMessage> { - tx$: Observable<T> /* Message transmission observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch a web worker - * - * This function returns an observable that sends all values emitted by the - * message observable to the web worker. Web worker communication is expected - * to be bidirectional (request-response) and synchronous. Messages that are - * emitted during a pending request are throttled, the last one is emitted. - * - * @param worker - Web worker - * @param options - Options - * - * @returns Worker message observable - */ -export function watchWorker<T extends WorkerMessage>( - worker: Worker, { tx$ }: WatchOptions<T> -): Observable<T> { - - /* Intercept messages from worker-like objects */ - const rx$ = fromEvent<MessageEvent>(worker, "message") - .pipe( - map(({ data }) => data as T) - ) - - /* Send and receive messages, return hot observable */ - return tx$ - .pipe( - throttle(() => rx$, { leading: true, trailing: true }), - tap(message => worker.postMessage(message)), - switchMap(() => rx$), - share() - ) -} diff --git a/src/assets/javascripts/bundle.ts b/src/assets/javascripts/bundle.ts @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 "array-flat-polyfill" -import "focus-visible" -import "unfetch/polyfill" -import "url-polyfill" - -import { - EMPTY, - NEVER, - Subject, - defer, - delay, - filter, - map, - merge, - mergeWith, - shareReplay, - switchMap -} from "rxjs" - -import { configuration, feature } from "./_" -import { - at, - getOptionalElement, - requestJSON, - setToggle, - watchDocument, - watchKeyboard, - watchLocation, - watchLocationTarget, - watchMedia, - watchPrint, - watchViewport -} from "./browser" -import { - getComponentElement, - getComponentElements, - mountAnnounce, - mountBackToTop, - mountConsent, - mountContent, - mountDialog, - mountHeader, - mountHeaderTitle, - mountPalette, - mountSearch, - mountSearchHiglight, - mountSidebar, - mountSource, - mountTableOfContents, - mountTabs, - watchHeader, - watchMain -} from "./components" -import { - SearchIndex, - setupClipboardJS, - setupInstantLoading, - setupVersionSelector -} from "./integrations" -import { - patchIndeterminate, - patchScrollfix, - patchScrolllock -} from "./patches" -import "./polyfills" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Yay, JavaScript is available */ -document.documentElement.classList.remove("no-js") -document.documentElement.classList.add("js") - -/* Set up navigation observables and subjects */ -const document$ = watchDocument() -const location$ = watchLocation() -const target$ = watchLocationTarget() -const keyboard$ = watchKeyboard() - -/* Set up media observables */ -const viewport$ = watchViewport() -const tablet$ = watchMedia("(min-width: 960px)") -const screen$ = watchMedia("(min-width: 1220px)") -const print$ = watchPrint() - -/* Retrieve search index, if search is enabled */ -const config = configuration() -const index$ = document.forms.namedItem("search") - ? __search?.index || requestJSON<SearchIndex>( - new URL("search/search_index.json", config.base) - ) - : NEVER - -/* Set up Clipboard.js integration */ -const alert$ = new Subject<string>() -setupClipboardJS({ alert$ }) - -/* Set up instant loading, if enabled */ -if (feature("navigation.instant")) - setupInstantLoading({ document$, location$, viewport$ }) - -/* Set up version selector */ -if (config.version?.provider === "mike") - setupVersionSelector({ document$ }) - -/* Always close drawer and search on navigation */ -merge(location$, target$) - .pipe( - delay(125) - ) - .subscribe(() => { - setToggle("drawer", false) - setToggle("search", false) - }) - -/* 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 = getOptionalElement("[href][rel=prev]") - if (typeof prev !== "undefined") - prev.click() - break - - /* Go to next page */ - case "n": - case ".": - const next = getOptionalElement("[href][rel=next]") - if (typeof next !== "undefined") - next.click() - break - } - }) - -/* Set up patches */ -patchIndeterminate({ document$, tablet$ }) -patchScrollfix({ document$ }) -patchScrolllock({ viewport$, tablet$ }) - -/* Set up header and main area observable */ -const header$ = watchHeader(getComponentElement("header"), { viewport$ }) -const main$ = document$ - .pipe( - map(() => getComponentElement("main")), - switchMap(el => watchMain(el, { viewport$, header$ })), - shareReplay(1) - ) - -/* Set up control component observables */ -const control$ = merge( - - /* Consent */ - ...getComponentElements("consent") - .map(el => mountConsent(el, { target$ })), - - /* Dialog */ - ...getComponentElements("dialog") - .map(el => mountDialog(el, { alert$ })), - - /* Header */ - ...getComponentElements("header") - .map(el => mountHeader(el, { viewport$, header$, main$ })), - - /* Color palette */ - ...getComponentElements("palette") - .map(el => mountPalette(el)), - - /* Search */ - ...getComponentElements("search") - .map(el => mountSearch(el, { index$, keyboard$ })), - - /* Repository information */ - ...getComponentElements("source") - .map(el => mountSource(el)) -) - -/* Set up content component observables */ -const content$ = defer(() => merge( - - /* Announcement bar */ - ...getComponentElements("announce") - .map(el => mountAnnounce(el)), - - /* Content */ - ...getComponentElements("content") - .map(el => mountContent(el, { target$, print$ })), - - /* Search highlighting */ - ...getComponentElements("content") - .map(el => feature("search.highlight") - ? mountSearchHiglight(el, { index$, location$ }) - : EMPTY - ), - - /* Header title */ - ...getComponentElements("header-title") - .map(el => mountHeaderTitle(el, { viewport$, header$ })), - - /* Sidebar */ - ...getComponentElements("sidebar") - .map(el => el.getAttribute("data-md-type") === "navigation" - ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ })) - : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ })) - ), - - /* Navigation tabs */ - ...getComponentElements("tabs") - .map(el => mountTabs(el, { viewport$, header$ })), - - /* Table of contents */ - ...getComponentElements("toc") - .map(el => mountTableOfContents(el, { viewport$, header$, target$ })), - - /* Back-to-top button */ - ...getComponentElements("top") - .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ })) -)) - -/* Set up component observables */ -const component$ = document$ - .pipe( - switchMap(() => content$), - mergeWith(control$), - shareReplay(1) - ) - -/* Subscribe to all components */ -component$.subscribe() - -/* ---------------------------------------------------------------------------- - * Exports - * ------------------------------------------------------------------------- */ - -window.document$ = document$ /* Document observable */ -window.location$ = location$ /* Location subject */ -window.target$ = target$ /* Location target observable */ -window.keyboard$ = keyboard$ /* Keyboard observable */ -window.viewport$ = viewport$ /* Viewport observable */ -window.tablet$ = tablet$ /* Media tablet observable */ -window.screen$ = screen$ /* Media screen observable */ -window.print$ = print$ /* Media print observable */ -window.alert$ = alert$ /* Alert subject */ -window.component$ = component$ /* Component observable */ diff --git a/src/assets/javascripts/components/_/index.ts b/src/assets/javascripts/components/_/index.ts @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { getElement, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "announce" /* Announcement bar */ - | "container" /* Container */ - | "consent" /* Consent */ - | "content" /* Content */ - | "dialog" /* Dialog */ - | "header" /* Header */ - | "header-title" /* Header title */ - | "header-topic" /* Header topic */ - | "main" /* Main area */ - | "outdated" /* Version warning */ - | "palette" /* Color palette */ - | "search" /* Search */ - | "search-query" /* Search input */ - | "search-result" /* Search results */ - | "search-share" /* Search sharing */ - | "search-suggest" /* Search suggestions */ - | "sidebar" /* Sidebar */ - | "skip" /* Skip link */ - | "source" /* Repository information */ - | "tabs" /* Navigation tabs */ - | "toc" /* Table of contents */ - | "top" /* Back-to-top button */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "announce": HTMLElement /* Announcement bar */ - "container": HTMLElement /* Container */ - "consent": HTMLElement /* Consent */ - "content": HTMLElement /* Content */ - "dialog": HTMLElement /* Dialog */ - "header": HTMLElement /* Header */ - "header-title": HTMLElement /* Header title */ - "header-topic": HTMLElement /* Header topic */ - "main": HTMLElement /* Main area */ - "outdated": HTMLElement /* Version warning */ - "palette": HTMLElement /* Color palette */ - "search": HTMLElement /* Search */ - "search-query": HTMLInputElement /* Search input */ - "search-result": HTMLElement /* Search results */ - "search-share": HTMLAnchorElement /* Search sharing */ - "search-suggest": HTMLElement /* Search suggestions */ - "sidebar": HTMLElement /* Sidebar */ - "skip": HTMLAnchorElement /* Skip link */ - "source": HTMLAnchorElement /* Repository information */ - "tabs": HTMLElement /* Navigation tabs */ - "toc": HTMLElement /* Table of contents */ - "top": HTMLAnchorElement /* Back-to-top button */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElement(`[data-md-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-md-component=${type}]`, node) -} diff --git a/src/assets/javascripts/components/announce/index.ts b/src/assets/javascripts/components/announce/index.ts @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - Subject, - defer, - finalize, - fromEvent, - map, - startWith, - tap -} from "rxjs" - -import { feature } from "~/_" -import { getElement } from "~/browser" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Announcement bar - */ -export interface Announce { - hash: number /* Content hash */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch announcement bar - * - * @param el - Announcement bar element - * - * @returns Announcement bar observable - */ -export function watchAnnounce( - el: HTMLElement -): Observable<Announce> { - const button = getElement(".md-typeset > :first-child", el) - return fromEvent(button, "click", { once: true }) - .pipe( - map(() => getElement(".md-typeset", el)), - map(content => ({ hash: __md_hash(content.innerHTML) })) - ) -} - -/** - * Mount announcement bar - * - * @param el - Announcement bar element - * - * @returns Announcement bar component observable - */ -export function mountAnnounce( - el: HTMLElement -): Observable<Component<Announce>> { - if (!feature("announce.dismiss") || !el.childElementCount) - return EMPTY - - /* Mount component on subscription */ - return defer(() => { - const push$ = new Subject<Announce>() - push$ - .pipe( - startWith({ hash: __md_get<number>("__announce") }) - ) - .subscribe(({ hash }) => { - if (hash && hash === (__md_get<number>("__announce") ?? hash)) { - el.hidden = true - - /* Persist preference in local storage */ - __md_set<number>("__announce", hash) - } - }) - - /* Create and return component */ - return watchAnnounce(el) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/consent/index.ts b/src/assets/javascripts/components/consent/index.ts @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - finalize, - map, - tap -} from "rxjs" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Consent - */ -export interface Consent { - hidden: boolean /* Consent is hidden */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - target$: Observable<HTMLElement> /* Target observable */ -} - -/** - * Mount options - */ -interface MountOptions { - target$: Observable<HTMLElement> /* Target observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch consent - * - * @param el - Consent element - * @param options - Options - * - * @returns Consent observable - */ -export function watchConsent( - el: HTMLElement, { target$ }: WatchOptions -): Observable<Consent> { - return target$ - .pipe( - map(target => ({ hidden: target !== el })) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount consent - * - * @param el - Consent element - * @param options - Options - * - * @returns Consent component observable - */ -export function mountConsent( - el: HTMLElement, options: MountOptions -): Observable<Component<Consent>> { - const internal$ = new Subject<Consent>() - internal$.subscribe(({ hidden }) => { - el.hidden = hidden - }) - - /* Create and return component */ - return watchConsent(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/assets/javascripts/components/content/_/index.ts b/src/assets/javascripts/components/content/_/index.ts @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Observable, merge } from "rxjs" - -import { getElements } from "~/browser" - -import { Component } from "../../_" -import { Annotation } from "../annotation" -import { - CodeBlock, - Mermaid, - mountCodeBlock, - mountMermaid -} from "../code" -import { - Details, - mountDetails -} from "../details" -import { - DataTable, - mountDataTable -} from "../table" -import { - ContentTabs, - mountContentTabs -} from "../tabs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Content - */ -export type Content = - | Annotation - | ContentTabs - | CodeBlock - | Mermaid - | DataTable - | Details - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - target$: Observable<HTMLElement> /* Location target observable */ - print$: Observable<boolean> /* Media print observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * 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 - * - * @returns Content component observable - */ -export function mountContent( - el: HTMLElement, { target$, print$ }: MountOptions -): Observable<Component<Content>> { - return merge( - - /* Code blocks */ - ...getElements("pre:not(.mermaid) > code", el) - .map(child => mountCodeBlock(child, { print$ })), - - /* Mermaid diagrams */ - ...getElements("pre.mermaid", el) - .map(child => mountMermaid(child)), - - /* Data tables */ - ...getElements("table:not([class])", el) - .map(child => mountDataTable(child)), - - /* Details */ - ...getElements("details", el) - .map(child => mountDetails(child, { target$, print$ })), - - /* Content tabs */ - ...getElements("[data-tabs]", el) - .map(child => mountContentTabs(child)) - ) -} diff --git a/src/assets/javascripts/components/content/annotation/_/index.ts b/src/assets/javascripts/components/content/annotation/_/index.ts @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - Subject, - animationFrameScheduler, - combineLatest, - defer, - finalize, - fromEvent, - map, - switchMap, - take, - takeLast, - takeUntil, - tap, - throttleTime -} from "rxjs" - -import { - ElementOffset, - getElement, - getElementSize, - watchElementContentOffset, - watchElementFocus, - watchElementOffset, - watchElementVisibility -} from "~/browser" - -import { Component } from "../../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Annotation - */ -export interface Annotation { - active: boolean /* Annotation is active */ - offset: ElementOffset /* Annotation offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch annotation - * - * @param el - Annotation element - * @param container - Containing element - * - * @returns Annotation observable - */ -export function watchAnnotation( - el: HTMLElement, container: HTMLElement -): Observable<Annotation> { - const offset$ = defer(() => combineLatest([ - watchElementOffset(el), - watchElementContentOffset(container) - ])) - .pipe( - map(([{ x, y }, scroll]) => { - const { width } = getElementSize(el) - return ({ - x: x - scroll.x + width / 2, - y: y - scroll.y - }) - }) - ) - - /* Actively watch annotation on focus */ - return watchElementFocus(el) - .pipe( - switchMap(active => offset$ - .pipe( - map(offset => ({ active, offset })), - take(+!active || Infinity) - ) - ) - ) -} - -/** - * Mount annotation - * - * @param el - Annotation element - * @param container - Containing element - * - * @returns Annotation component observable - */ -export function mountAnnotation( - el: HTMLElement, container: HTMLElement -): Observable<Component<Annotation>> { - return defer(() => { - const push$ = new Subject<Annotation>() - push$.subscribe({ - - /* Handle emission */ - next({ offset }) { - el.style.setProperty("--md-tooltip-x", `${offset.x}px`) - el.style.setProperty("--md-tooltip-y", `${offset.y}px`) - }, - - /* Handle complete */ - complete() { - el.style.removeProperty("--md-tooltip-x") - el.style.removeProperty("--md-tooltip-y") - } - }) - - /* Start animation only when annotation is visible */ - const done$ = push$.pipe(takeLast(1)) - watchElementVisibility(el) - .pipe( - takeUntil(done$) - ) - .subscribe(visible => { - el.toggleAttribute("data-md-visible", visible) - }) - - /* Track relative origin of tooltip */ - push$ - .pipe( - throttleTime(500, animationFrameScheduler), - map(() => container.getBoundingClientRect()), - map(({ x }) => x) - ) - .subscribe({ - - /* Handle emission */ - next(origin) { - if (origin) - el.style.setProperty("--md-tooltip-0", `${-origin}px`) - else - el.style.removeProperty("--md-tooltip-0") - }, - - /* Handle complete */ - complete() { - el.style.removeProperty("--md-tooltip-0") - } - }) - - /* Close open annotation on click */ - const index = getElement(":scope > :last-child", el) - const blur$ = fromEvent(index, "mousedown", { once: true }) - push$ - .pipe( - switchMap(({ active }) => active ? blur$ : EMPTY), - tap(ev => ev.preventDefault()) - ) - .subscribe(() => el.blur()) - - /* Create and return component */ - return watchAnnotation(el, container) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/content/annotation/index.ts b/src/assets/javascripts/components/content/annotation/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./list" diff --git a/src/assets/javascripts/components/content/annotation/list/index.ts b/src/assets/javascripts/components/content/annotation/list/index.ts @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - Subject, - defer, - finalize, - merge, - share, - takeLast, - takeUntil -} from "rxjs" - -import { - getElement, - getElements, - getOptionalElement -} from "~/browser" -import { renderAnnotation } from "~/templates" - -import { Component } from "../../../_" -import { - Annotation, - mountAnnotation -} from "../_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - print$: Observable<boolean> /* Media print observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Find all annotation markers in the given code block - * - * @param container - Containing element - * - * @returns Annotation markers - */ -function findAnnotationMarkers(container: HTMLElement): Text[] { - const markers: Text[] = [] - for (const comment of getElements(".c, .c1, .cm", container)) { - let match: RegExpExecArray | null - - /* Split text at marker and add to list */ - let text = comment.firstChild as Text - if (text instanceof Text) - while ((match = /\((\d+)\)/.exec(text.textContent!))) { - const marker = text.splitText(match.index) - text = marker.splitText(match[0].length) - markers.push(marker) - } - } - return markers -} - -/** - * Swap the child nodes of two elements - * - * @param source - Source element - * @param target - Target element - */ -function swap(source: HTMLElement, target: HTMLElement): void { - target.append(...Array.from(source.childNodes)) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount annotation list - * - * This function analyzes the containing code block and checks for markers - * referring to elements in the given annotation list. If no markers are found, - * the list is left untouched. Otherwise, list elements are rendered as - * annotations inside the code block. - * - * @param el - Annotation list element - * @param container - Containing element - * @param options - Options - * - * @returns Annotation component observable - */ -export function mountAnnotationList( - el: HTMLElement, container: HTMLElement, { print$ }: MountOptions -): Observable<Component<Annotation>> { - - /* Find and replace all markers with empty annotations */ - const annotations = new Map<number, HTMLElement>() - for (const marker of findAnnotationMarkers(container)) { - const [, id] = marker.textContent!.match(/\((\d+)\)/)! - if (getOptionalElement(`li:nth-child(${id})`, el)) { - annotations.set(+id, renderAnnotation(+id)) - marker.replaceWith(annotations.get(+id)!) - } - } - - /* Keep list if there are no annotations to render */ - if (annotations.size === 0) - return EMPTY - - /* Create and return component */ - return defer(() => { - const done$ = new Subject<void>() - - /* Handle print mode - see https://bit.ly/3rgPdpt */ - print$ - .pipe( - takeUntil(done$.pipe(takeLast(1))) - ) - .subscribe(active => { - el.hidden = !active - - /* Show annotations in code block or list (print) */ - for (const [id, annotation] of annotations) { - const inner = getElement(".md-typeset", annotation) - const child = getElement(`li:nth-child(${id})`, el) - if (!active) - swap(child, inner) - else - swap(inner, child) - } - }) - - /* Create and return component */ - return merge(...[...annotations] - .map(([, annotation]) => ( - mountAnnotation(annotation, container) - )) - ) - .pipe( - finalize(() => done$.complete()), - share() - ) - }) -} diff --git a/src/assets/javascripts/components/content/code/_/index.ts b/src/assets/javascripts/components/content/code/_/index.ts @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 ClipboardJS from "clipboard" -import { - EMPTY, - Observable, - Subject, - defer, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - finalize, - map, - mergeWith, - switchMap, - take, - takeLast, - takeUntil, - tap -} from "rxjs" - -import { feature } from "~/_" -import { - getElementContentSize, - watchElementSize, - watchElementVisibility -} from "~/browser" -import { renderClipboardButton } from "~/templates" - -import { Component } from "../../../_" -import { - Annotation, - mountAnnotationList -} from "../../annotation" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Code block - */ -export interface CodeBlock { - scrollable: boolean /* Code block overflows */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - print$: Observable<boolean> /* Media print observable */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Global sequence number for Clipboard.js integration - */ -let sequence = 0 - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Find candidate list element directly following a code block - * - * @param el - Code block element - * - * @returns List element or nothing - */ -function findCandidateList(el: HTMLElement): HTMLElement | undefined { - if (el.nextElementSibling) { - const sibling = el.nextElementSibling as HTMLElement - if (sibling.tagName === "OL") - return sibling - - /* Skip empty paragraphs - see https://bit.ly/3r4ZJ2O */ - else if (sibling.tagName === "P" && !sibling.children.length) - return findCandidateList(sibling) - } - - /* Everything else */ - return undefined -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch code block - * - * This function monitors size changes of the viewport, as well as switches of - * content tabs with embedded code blocks, as both may trigger overflow. - * - * @param el - Code block element - * - * @returns Code block observable - */ -export function watchCodeBlock( - el: HTMLElement -): Observable<CodeBlock> { - return watchElementSize(el) - .pipe( - map(({ width }) => { - const content = getElementContentSize(el) - return { - scrollable: content.width > width - } - }), - distinctUntilKeyChanged("scrollable") - ) -} - -/** - * Mount code block - * - * This function ensures that an overflowing code block is focusable through - * keyboard, so it can be scrolled without a mouse to improve on accessibility. - * Furthermore, if code annotations are enabled, they are mounted if and only - * if the code block is currently visible, e.g., not in a hidden content tab. - * - * @param el - Code block element - * @param options - Options - * - * @returns Code block and annotation component observable - */ -export function mountCodeBlock( - el: HTMLElement, options: MountOptions -): Observable<Component<CodeBlock | Annotation>> { - const { matches: hover } = matchMedia("(hover)") - - /* Defer mounting of code block - see https://bit.ly/3vHVoVD */ - const factory$ = defer(() => { - const push$ = new Subject<CodeBlock>() - push$.subscribe(({ scrollable }) => { - if (scrollable && hover) - el.setAttribute("tabindex", "0") - else - el.removeAttribute("tabindex") - }) - - /* Render button for Clipboard.js integration */ - if (ClipboardJS.isSupported()) { - const parent = el.closest("pre")! - parent.id = `__code_${++sequence}` - parent.insertBefore( - renderClipboardButton(parent.id), - el - ) - } - - /* Handle code annotations */ - const container = el.closest(".highlight") - if (container instanceof HTMLElement) { - const list = findCandidateList(container) - - /* Mount code annotations, if enabled */ - if (typeof list !== "undefined" && ( - container.classList.contains("annotate") || - feature("content.code.annotate") - )) { - const annotations$ = mountAnnotationList(list, el, options) - - /* Create and return component */ - return watchCodeBlock(el) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })), - mergeWith( - watchElementSize(container) - .pipe( - takeUntil(push$.pipe(takeLast(1))), - map(({ width, height }) => width && height), - distinctUntilChanged(), - switchMap(active => active ? annotations$ : EMPTY) - ) - ) - ) - } - } - - /* Create and return component */ - return watchCodeBlock(el) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) - - /* Mount code block on first sight */ - return watchElementVisibility(el) - .pipe( - filter(visible => visible), - take(1), - switchMap(() => factory$) - ) -} diff --git a/src/assets/javascripts/components/content/code/index.ts b/src/assets/javascripts/components/content/code/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./mermaid" diff --git a/src/assets/javascripts/components/content/code/mermaid/index.css b/src/assets/javascripts/components/content/code/mermaid/index.css @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Rules: general - * ------------------------------------------------------------------------- */ - -/* General node */ -.node circle, -.node ellipse, -.node path, -.node polygon, -.node rect { - fill: var(--md-mermaid-node-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* General marker */ -marker { - fill: var(--md-mermaid-edge-color) !important; -} - -/* General edge label */ -.edgeLabel .label rect { - fill: transparent; -} - -/* ---------------------------------------------------------------------------- - * Rules: flowcharts - * ------------------------------------------------------------------------- */ - -/* Flowchart node label */ -.label { - color: var(--md-mermaid-label-fg-color); - font-family: var(--md-mermaid-font-family); -} - -/* Flowchart node label container */ -.label foreignObject { - overflow: visible; - line-height: initial; -} - -/* Flowchart edge label in node label */ -.label div .edgeLabel { - color: var(--md-mermaid-label-fg-color); - background-color: var(--md-mermaid-label-bg-color); -} - -/* Flowchart edge label */ -.edgeLabel, -.edgeLabel rect { - color: var(--md-mermaid-edge-color); - background-color: var(--md-mermaid-label-bg-color); - fill: var(--md-mermaid-label-bg-color); -} - -/* Flowchart edge path */ -.edgePath .path, -.flowchart-link { - stroke: var(--md-mermaid-edge-color); -} - -/* Flowchart arrow head */ -.edgePath .arrowheadPath { - fill: var(--md-mermaid-edge-color); - stroke: none; -} - -/* Flowchart subgraph */ -.cluster rect { - fill: var(--md-default-fg-color--lightest); - stroke: var(--md-default-fg-color--lighter); -} - -/* Flowchart subgraph labels */ -.cluster span { - color: var(--md-mermaid-label-fg-color); - font-family: var(--md-mermaid-font-family); -} - -/* Flowchart markers */ -defs #flowchart-circleStart, -defs #flowchart-circleEnd, -defs #flowchart-crossStart, -defs #flowchart-crossEnd, -defs #flowchart-pointStart, -defs #flowchart-pointEnd { - stroke: none; -} - -/* ---------------------------------------------------------------------------- - * Rules: class diagrams - * ------------------------------------------------------------------------- */ - -/* Class group node */ -g.classGroup line, -g.classGroup rect { - fill: var(--md-mermaid-node-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* Class group node text */ -g.classGroup text { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color); -} - -/* Class label box */ -.classLabel .box { - background-color: var(--md-mermaid-label-bg-color); - opacity: 1; - fill: var(--md-mermaid-label-bg-color); -} - -/* Class label text */ -.classLabel .label { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color); -} - -/* Class group divider */ -.node .divider { - stroke: var(--md-mermaid-node-fg-color); -} - -/* Class relation */ -.relation { - stroke: var(--md-mermaid-edge-color); -} - -/* Class relation cardinality */ -.cardinality { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color); -} - -/* Class relation cardinality text */ -.cardinality text { - fill: inherit !important; -} - -/* Class extension, composition and dependency marker */ -defs #classDiagram-extensionStart, -defs #classDiagram-extensionEnd, -defs #classDiagram-compositionStart, -defs #classDiagram-compositionEnd, -defs #classDiagram-dependencyStart, -defs #classDiagram-dependencyEnd { - fill: var(--md-mermaid-edge-color) !important; - stroke: var(--md-mermaid-edge-color) !important; -} - -/* Class aggregation marker */ -defs #classDiagram-aggregationStart, -defs #classDiagram-aggregationEnd { - fill: var(--md-mermaid-label-bg-color) !important; - stroke: var(--md-mermaid-edge-color) !important; -} - -/* ---------------------------------------------------------------------------- - * Rules: state diagrams - * ------------------------------------------------------------------------- */ - -/* State group node */ -g.stateGroup rect { - fill: var(--md-mermaid-node-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* State group title */ -g.stateGroup .state-title { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color) !important; -} - -/* State group background */ -g.stateGroup .composit { - fill: var(--md-mermaid-label-bg-color); -} - -/* State node label */ -.nodeLabel { - color: var(--md-mermaid-label-fg-color); - font-family: var(--md-mermaid-font-family); -} - -/* State start and end marker */ -.start-state, -.node circle.state-start, -.node circle.state-end { - fill: var(--md-mermaid-edge-color); - stroke: none; -} - -/* State end marker */ -.end-state-outer, -.end-state-inner { - fill: var(--md-mermaid-edge-color); -} - -/* State end marker */ -.end-state-inner, -.node circle.state-end { - stroke: var(--md-mermaid-label-bg-color); -} - -/* State transition */ -.transition { - stroke: var(--md-mermaid-edge-color); -} - -/* State fork and join */ -[id^=state-fork] rect, -[id^=state-join] rect { - fill: var(--md-mermaid-edge-color) !important; - stroke: none !important; -} - -/* State cluster (yes, 2x... Mermaid WTF) */ -.statediagram-cluster.statediagram-cluster .inner { - fill: var(--md-default-bg-color); -} - -/* State cluster node */ -.statediagram-cluster rect { - fill: var(--md-mermaid-node-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* State cluster divider */ -.statediagram-state rect.divider { - fill: var(--md-default-fg-color--lightest); - stroke: var(--md-default-fg-color--lighter); -} - -/* State diagram markers */ -defs #statediagram-barbEnd { - stroke: var(--md-mermaid-edge-color); -} - -/* ---------------------------------------------------------------------------- - * Rules: entity-relationship diagrams - * ------------------------------------------------------------------------- */ - - /* Entity node */ -.entityBox { - fill: var(--md-mermaid-label-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* Entity node label */ -.entityLabel { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color); -} - -/* Entity relationship label container */ -.relationshipLabelBox { - background-color: var(--md-mermaid-label-bg-color); - opacity: 1; - fill: var(--md-mermaid-label-bg-color); - fill-opacity: 1; -} - -/* Entity relationship label */ -.relationshipLabel { - fill: var(--md-mermaid-label-fg-color); -} - -/* Entity relationship line { */ -.relationshipLine { - stroke: var(--md-mermaid-edge-color); -} - -/* Entity relationship line markers */ -defs #ZERO_OR_ONE_START *, -defs #ZERO_OR_ONE_END *, -defs #ZERO_OR_MORE_START *, -defs #ZERO_OR_MORE_END *, -defs #ONLY_ONE_START *, -defs #ONLY_ONE_END *, -defs #ONE_OR_MORE_START *, -defs #ONE_OR_MORE_END * { - stroke: var(--md-mermaid-edge-color) !important; -} - -/* Entity relationship line markers */ -defs #ZERO_OR_MORE_START circle, -defs #ZERO_OR_MORE_END circle { - fill: var(--md-mermaid-label-bg-color); -} - -/* ---------------------------------------------------------------------------- - * Rules: sequence diagrams - * ------------------------------------------------------------------------- */ - -/* Sequence actor */ -.actor { - fill: var(--md-mermaid-label-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* Sequence actor text */ -text.actor > tspan { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-label-fg-color); -} - -/* Sequence actor line */ -line { - stroke: var(--md-default-fg-color--lighter); -} - -/* Sequence message line */ -.messageLine0, -.messageLine1 { - stroke: var(--md-mermaid-edge-color); -} - -/* Sequence message and loop text */ -.messageText, -.loopText > tspan { - font-family: var(--md-mermaid-font-family) !important; - fill: var(--md-mermaid-edge-color); - stroke: none; -} - -/* Sequence arrow head */ -#arrowhead path { - fill: var(--md-mermaid-edge-color); - stroke: none; -} - -/* Sequence loop line */ -.loopLine { - fill: var(--md-mermaid-node-bg-color); - stroke: var(--md-mermaid-node-fg-color); -} - -/* Sequence label box */ -.labelBox { - fill: var(--md-mermaid-node-bg-color); - stroke: none; -} - -/* Sequence label text */ -.labelText, -.labelText > span { - font-family: var(--md-mermaid-font-family); - fill: var(--md-mermaid-node-fg-color); -} diff --git a/src/assets/javascripts/components/content/code/mermaid/index.ts b/src/assets/javascripts/components/content/code/mermaid/index.ts @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - map, - of, - shareReplay, - tap -} from "rxjs" - -import { watchScript } from "~/browser" -import { h } from "~/utilities" - -import { Component } from "../../../_" - -import themeCSS from "./index.css" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Mermaid diagram - */ -export interface Mermaid {} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Mermaid instance observable - */ -let mermaid$: Observable<void> - -/** - * Global sequence number for diagrams - */ -let sequence = 0 - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch Mermaid script - * - * @returns Mermaid scripts observable - */ -function fetchScripts(): Observable<void> { - return typeof mermaid === "undefined" || mermaid instanceof Element - ? watchScript("https://unpkg.com/mermaid@9.0.1/dist/mermaid.min.js") - : of(undefined) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount Mermaid diagram - * - * @param el - Code block element - * - * @returns Mermaid diagram component observable - */ -export function mountMermaid( - el: HTMLElement -): Observable<Component<Mermaid>> { - el.classList.remove("mermaid") // Hack: mitigate https://bit.ly/3CiN6Du - mermaid$ ||= fetchScripts() - .pipe( - tap(() => mermaid.initialize({ - startOnLoad: false, - themeCSS - })), - map(() => undefined), - shareReplay(1) - ) - - /* Render diagram */ - mermaid$.subscribe(() => { - el.classList.add("mermaid") // Hack: mitigate https://bit.ly/3CiN6Du - const id = `__mermaid_${sequence++}` - const host = h("div", { class: "mermaid" }) - mermaid.mermaidAPI.render(id, el.textContent, (svg: string) => { - - /* Create a shadow root and inject diagram */ - const shadow = host.attachShadow({ mode: "closed" }) - shadow.innerHTML = svg - - /* Replace code block with diagram */ - el.replaceWith(host) - }) - }) - - /* Create and return component */ - return mermaid$ - .pipe( - map(() => ({ ref: el })) - ) -} diff --git a/src/assets/javascripts/components/content/details/index.ts b/src/assets/javascripts/components/content/details/index.ts @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - defer, - filter, - finalize, - map, - merge, - tap -} from "rxjs" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Details - */ -export interface Details { - action: "open" | "close" /* Details state */ - reveal?: boolean /* Details is revealed */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - target$: Observable<HTMLElement> /* Location target observable */ - print$: Observable<boolean> /* Media print observable */ -} - -/** - * Mount options - */ -interface MountOptions { - target$: Observable<HTMLElement> /* Location target observable */ - print$: Observable<boolean> /* Media print observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch details - * - * @param el - Details element - * @param options - Options - * - * @returns Details observable - */ -export function watchDetails( - el: HTMLDetailsElement, { target$, print$ }: WatchOptions -): Observable<Details> { - let open = true - return merge( - - /* Open and focus details on location target */ - target$ - .pipe( - map(target => target.closest("details:not([open])")!), - filter(details => el === details), - map(() => ({ - action: "open", reveal: true - }) as Details) - ), - - /* Open details on print and close afterwards */ - print$ - .pipe( - filter(active => active || !open), - tap(() => open = el.open), - map(active => ({ - action: active ? "open" : "close" - }) as Details) - ) - ) -} - -/** - * Mount details - * - * 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 - * - * @returns Details component observable - */ -export function mountDetails( - el: HTMLDetailsElement, options: MountOptions -): Observable<Component<Details>> { - return defer(() => { - const push$ = new Subject<Details>() - push$.subscribe(({ action, reveal }) => { - if (action === "open") - el.setAttribute("open", "") - else - el.removeAttribute("open") - if (reveal) - el.scrollIntoView() - }) - - /* Create and return component */ - return watchDetails(el, options) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/content/index.ts b/src/assets/javascripts/components/content/index.ts @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./annotation" -export * from "./code" -export * from "./details" -export * from "./table" -export * from "./tabs" diff --git a/src/assets/javascripts/components/content/table/index.ts b/src/assets/javascripts/components/content/table/index.ts @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Observable, of } from "rxjs" - -import { renderTable } from "~/templates" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Data table - */ -export interface DataTable {} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Sentinel for replacement - */ -const sentinel = h("table") - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount data table - * - * This function wraps a data table in another scrollable container, so it can - * be smoothly scrolled on smaller screen sizes and won't break the layout. - * - * @param el - Data table element - * - * @returns Data table component observable - */ -export function mountDataTable( - el: HTMLElement -): Observable<Component<DataTable>> { - el.replaceWith(sentinel) - sentinel.replaceWith(renderTable(el)) - - /* Create and return component */ - return of({ ref: el }) -} diff --git a/src/assets/javascripts/components/content/tabs/index.ts b/src/assets/javascripts/components/content/tabs/index.ts @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - animationFrameScheduler, - asyncScheduler, - auditTime, - combineLatest, - defer, - finalize, - fromEvent, - map, - merge, - skip, - startWith, - subscribeOn, - takeLast, - takeUntil, - tap -} from "rxjs" - -import { feature } from "~/_" -import { - getElement, - getElementContentOffset, - getElementContentSize, - getElementOffset, - getElementSize, - getElements, - watchElementContentOffset, - watchElementSize -} from "~/browser" -import { renderTabbedControl } from "~/templates" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Content tabs - */ -export interface ContentTabs { - active: HTMLLabelElement /* Active tab label */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch content tabs - * - * @param el - Content tabs element - * - * @returns Content tabs observable - */ -export function watchContentTabs( - el: HTMLElement -): Observable<ContentTabs> { - const inputs = getElements<HTMLInputElement>(":scope > input", el) - const initial = inputs.find(input => input.checked) || inputs[0] - return merge(...inputs.map(input => fromEvent(input, "change") - .pipe( - map(() => getElement<HTMLLabelElement>(`label[for="${input.id}"]`)) - ) - )) - .pipe( - startWith(getElement<HTMLLabelElement>(`label[for="${initial.id}"]`)), - map(active => ({ active })) - ) -} - -/** - * Mount content tabs - * - * This function scrolls the active tab into view. While this functionality is - * provided by browsers as part of `scrollInfoView`, browsers will always also - * scroll the vertical axis, which we do not want. Thus, we decided to provide - * this functionality ourselves. - * - * @param el - Content tabs element - * - * @returns Content tabs component observable - */ -export function mountContentTabs( - el: HTMLElement -): Observable<Component<ContentTabs>> { - - /* Render content tab previous button for pagination */ - const prev = renderTabbedControl("prev") - el.append(prev) - - /* Render content tab next button for pagination */ - const next = renderTabbedControl("next") - el.append(next) - - /* Mount component on subscription */ - const container = getElement(".tabbed-labels", el) - return defer(() => { - const push$ = new Subject<ContentTabs>() - const done$ = push$.pipe(takeLast(1)) - combineLatest([push$, watchElementSize(el)]) - .pipe( - auditTime(1, animationFrameScheduler), - takeUntil(done$) - ) - .subscribe({ - - /* Handle emission */ - next([{ active }, size]) { - const offset = getElementOffset(active) - const { width } = getElementSize(active) - - /* Set tab indicator offset and width */ - el.style.setProperty("--md-indicator-x", `${offset.x}px`) - el.style.setProperty("--md-indicator-width", `${width}px`) - - /* Scroll container to active content tab */ - const content = getElementContentOffset(container) - if ( - offset.x < content.x || - offset.x + width > content.x + size.width - ) - container.scrollTo({ - left: Math.max(0, offset.x - 16), - behavior: "smooth" - }) - }, - - /* Handle complete */ - complete() { - el.style.removeProperty("--md-indicator-x") - el.style.removeProperty("--md-indicator-width") - } - }) - - /* Hide content tab buttons on borders */ - combineLatest([ - watchElementContentOffset(container), - watchElementSize(container) - ]) - .pipe( - takeUntil(done$) - ) - .subscribe(([offset, size]) => { - const content = getElementContentSize(container) - prev.hidden = offset.x < 16 - next.hidden = offset.x > content.width - size.width - 16 - }) - - /* Paginate content tab container on click */ - merge( - fromEvent(prev, "click").pipe(map(() => -1)), - fromEvent(next, "click").pipe(map(() => +1)) - ) - .pipe( - takeUntil(done$) - ) - .subscribe(direction => { - const { width } = getElementSize(container) - container.scrollBy({ - left: width * direction, - behavior: "smooth" - }) - }) - - /* Set up linking of content tabs, if enabled */ - if (feature("content.tabs.link")) - push$.pipe(skip(1)) - .subscribe(({ active }) => { - const tab = active.innerText.trim() - for (const set of getElements("[data-tabs]")) - for (const input of getElements<HTMLInputElement>( - ":scope > input", set - )) { - const label = getElement(`label[for="${input.id}"]`) - if (label.innerText.trim() === tab) { - input.click() - break - } - } - - /* Persist active tabs in local storage */ - const tabs = __md_get<string[]>("__tabs") || [] - __md_set("__tabs", [...new Set([tab, ...tabs])]) - }) - - /* Create and return component */ - return watchContentTabs(el) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) - .pipe( - subscribeOn(asyncScheduler) - ) -} diff --git a/src/assets/javascripts/components/dialog/index.ts b/src/assets/javascripts/components/dialog/index.ts @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - defer, - delay, - finalize, - map, - merge, - of, - switchMap, - tap -} from "rxjs" - -import { getElement } from "~/browser" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Dialog - */ -export interface Dialog { - message: string /* Dialog message */ - active: boolean /* Dialog is active */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - alert$: Subject<string> /* Alert subject */ -} - -/** - * Mount options - */ -interface MountOptions { - alert$: Subject<string> /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch dialog - * - * @param _el - Dialog element - * @param options - Options - * - * @returns Dialog observable - */ -export function watchDialog( - _el: HTMLElement, { alert$ }: WatchOptions -): Observable<Dialog> { - return alert$ - .pipe( - switchMap(message => merge( - of(true), - of(false).pipe(delay(2000)) - ) - .pipe( - map(active => ({ message, active })) - ) - ) - ) -} - -/** - * Mount dialog - * - * This function reveals the dialog in the right corner when a new alert is - * emitted through the subject that is passed as part of the options. - * - * @param el - Dialog element - * @param options - Options - * - * @returns Dialog component observable - */ -export function mountDialog( - el: HTMLElement, options: MountOptions -): Observable<Component<Dialog>> { - const inner = getElement(".md-typeset", el) - return defer(() => { - const push$ = new Subject<Dialog>() - push$.subscribe(({ message, active }) => { - el.classList.toggle("md-dialog--active", active) - inner.textContent = message - }) - - /* Create and return component */ - return watchDialog(el, options) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/header/_/index.ts b/src/assets/javascripts/components/header/_/index.ts @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - bufferCount, - combineLatest, - combineLatestWith, - defer, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - map, - of, - shareReplay, - startWith, - switchMap, - takeLast, - takeUntil -} from "rxjs" - -import { feature } from "~/_" -import { - Viewport, - watchElementSize, - watchToggle -} from "~/browser" - -import { Component } from "../../_" -import { Main } from "../../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface Header { - height: number /* Header visible height */ - hidden: boolean /* Header is hidden */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Compute whether the header is hidden - * - * If the user scrolls past a certain threshold, the header can be hidden when - * scrolling down, and shown when scrolling up. - * - * @param options - Options - * - * @returns Toggle observable - */ -function isHidden({ viewport$ }: WatchOptions): Observable<boolean> { - if (!feature("header.autohide")) - return of(false) - - /* Compute direction and turning point */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => [a < b, b] as const), - distinctUntilKeyChanged(0) - ) - - /* Compute whether header should be hidden */ - const hidden$ = combineLatest([viewport$, direction$]) - .pipe( - filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100), - map(([, [direction]]) => direction), - distinctUntilChanged() - ) - - /* Compute threshold for hiding */ - const search$ = watchToggle("search") - return combineLatest([viewport$, search$]) - .pipe( - map(([{ offset }, search]) => offset.y > 400 && !search), - distinctUntilChanged(), - switchMap(active => active ? hidden$ : of(false)), - startWith(false) - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header - * - * @param el - Header element - * @param options - Options - * - * @returns Header observable - */ -export function watchHeader( - el: HTMLElement, options: WatchOptions -): Observable<Header> { - return defer(() => combineLatest([ - watchElementSize(el), - isHidden(options) - ])) - .pipe( - map(([{ height }, hidden]) => ({ - height, - hidden - })), - distinctUntilChanged((a, b) => ( - a.height === b.height && - a.hidden === b.hidden - )), - shareReplay(1) - ) -} - -/** - * Mount header - * - * 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 - * - * @returns Header component observable - */ -export function mountHeader( - el: HTMLElement, { header$, main$ }: MountOptions -): Observable<Component<Header>> { - return defer(() => { - const push$ = new Subject<Main>() - const done$ = push$.pipe(takeLast(1)) - push$ - .pipe( - distinctUntilKeyChanged("active"), - combineLatestWith(header$) - ) - .subscribe(([{ active }, { hidden }]) => { - el.classList.toggle("md-header--shadow", active && !hidden) - el.hidden = hidden - }) - - /* Link to main area */ - main$.subscribe(push$) - - /* Create and return component */ - return header$ - .pipe( - takeUntil(done$), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/header/index.ts b/src/assets/javascripts/components/header/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./title" diff --git a/src/assets/javascripts/components/header/title/index.ts b/src/assets/javascripts/components/header/title/index.ts @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - Subject, - defer, - distinctUntilKeyChanged, - finalize, - map, - tap -} from "rxjs" - -import { - Viewport, - getElementSize, - getOptionalElement, - watchViewportAt -} from "~/browser" - -import { Component } from "../../_" -import { Header } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface HeaderTitle { - active: boolean /* Header title is active */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header title - * - * @param el - Heading element - * @param options - Options - * - * @returns Header title observable - */ -export function watchHeaderTitle( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<HeaderTitle> { - return watchViewportAt(el, { viewport$, header$ }) - .pipe( - map(({ offset: { y } }) => { - const { height } = getElementSize(el) - return { - active: y >= height - } - }), - distinctUntilKeyChanged("active") - ) -} - -/** - * 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 - * - * @returns Header title component observable - */ -export function mountHeaderTitle( - el: HTMLElement, options: MountOptions -): Observable<Component<HeaderTitle>> { - return defer(() => { - const push$ = new Subject<HeaderTitle>() - push$.subscribe(({ active }) => { - el.classList.toggle("md-header__title--active", active) - }) - - /* Obtain headline, if any */ - const heading = getOptionalElement("article h1") - if (typeof heading === "undefined") - return EMPTY - - /* Create and return component */ - return watchHeaderTitle(heading, options) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/index.ts b/src/assets/javascripts/components/index.ts @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./announce" -export * from "./consent" -export * from "./content" -export * from "./dialog" -export * from "./header" -export * from "./main" -export * from "./palette" -export * from "./search" -export * from "./sidebar" -export * from "./source" -export * from "./tabs" -export * from "./toc" -export * from "./top" diff --git a/src/assets/javascripts/components/main/index.ts b/src/assets/javascripts/components/main/index.ts @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - combineLatest, - distinctUntilChanged, - distinctUntilKeyChanged, - map, - switchMap -} from "rxjs" - -import { - Viewport, - watchElementSize -} from "~/browser" - -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Main area - */ -export interface Main { - offset: number /* Main area top offset */ - height: number /* Main area visible height */ - active: boolean /* Main area is active */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch main area - * - * This function returns an observable that computes the visual parameters of - * the main area which depends on the viewport vertical offset and height, as - * well as the height of the header element, if the header is fixed. - * - * @param el - Main area element - * @param options - Options - * - * @returns Main area observable - */ -export function watchMain( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<Main> { - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - map(({ height }) => height), - distinctUntilChanged() - ) - - /* Compute the main area's top and bottom borders */ - const border$ = adjust$ - .pipe( - switchMap(() => watchElementSize(el) - .pipe( - map(({ height }) => ({ - top: el.offsetTop, - bottom: el.offsetTop + height - })), - distinctUntilKeyChanged("bottom") - ) - ) - ) - - /* Compute the main area's offset, visible height and if we scrolled past */ - return combineLatest([adjust$, border$, viewport$]) - .pipe( - map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => { - height = Math.max(0, height - - Math.max(0, top - y, header) - - Math.max(0, height + y - bottom) - ) - return { - offset: top - header, - height, - active: top - header <= y - } - }), - distinctUntilChanged((a, b) => ( - a.offset === b.offset && - a.height === b.height && - a.active === b.active - )) - ) -} diff --git a/src/assets/javascripts/components/palette/index.ts b/src/assets/javascripts/components/palette/index.ts @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - asyncScheduler, - defer, - finalize, - fromEvent, - map, - mergeMap, - observeOn, - of, - shareReplay, - startWith, - tap -} from "rxjs" - -import { getElements } from "~/browser" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Palette colors - */ -export interface PaletteColor { - scheme?: string /* Color scheme */ - primary?: string /* Primary color */ - accent?: string /* Accent color */ -} - -/** - * Palette - */ -export interface Palette { - index: number /* Palette index */ - color: PaletteColor /* Palette colors */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch color palette - * - * @param inputs - Color palette element - * - * @returns Color palette observable - */ -export function watchPalette( - inputs: HTMLInputElement[] -): Observable<Palette> { - const current = __md_get<Palette>("__palette") || { - index: inputs.findIndex(input => matchMedia( - input.getAttribute("data-md-color-media")! - ).matches) - } - - /* Emit changes in color palette */ - return of(...inputs) - .pipe( - mergeMap(input => fromEvent(input, "change") - .pipe( - map(() => input) - ) - ), - startWith(inputs[Math.max(0, current.index)]), - map(input => ({ - index: inputs.indexOf(input), - color: { - scheme: input.getAttribute("data-md-color-scheme"), - primary: input.getAttribute("data-md-color-primary"), - accent: input.getAttribute("data-md-color-accent") - } - } as Palette)), - shareReplay(1) - ) -} - -/** - * Mount color palette - * - * @param el - Color palette element - * - * @returns Color palette component observable - */ -export function mountPalette( - el: HTMLElement -): Observable<Component<Palette>> { - return defer(() => { - const push$ = new Subject<Palette>() - push$.subscribe(palette => { - document.body.setAttribute("data-md-color-switching", "") - - /* Set color palette */ - for (const [key, value] of Object.entries(palette.color)) - document.body.setAttribute(`data-md-color-${key}`, value) - - /* Toggle visibility */ - for (let index = 0; index < inputs.length; index++) { - const label = inputs[index].nextElementSibling - if (label instanceof HTMLElement) - label.hidden = palette.index !== index - } - - /* Persist preference in local storage */ - __md_set("__palette", palette) - }) - - /* Revert transition durations after color switch */ - push$.pipe(observeOn(asyncScheduler)) - .subscribe(() => { - document.body.removeAttribute("data-md-color-switching") - }) - - /* Create and return component */ - const inputs = getElements<HTMLInputElement>("input", el) - return watchPalette(inputs) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/search/_/index.ts b/src/assets/javascripts/components/search/_/index.ts @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - NEVER, - Observable, - ObservableInput, - filter, - merge, - mergeWith, - sample, - take -} from "rxjs" - -import { configuration } from "~/_" -import { - Keyboard, - getActiveElement, - getElements, - setToggle -} from "~/browser" -import { - SearchIndex, - SearchResult, - isSearchQueryMessage, - isSearchReadyMessage, - setupSearchWorker -} from "~/integrations" - -import { - Component, - getComponentElement, - getComponentElements -} from "../../_" -import { - SearchQuery, - mountSearchQuery -} from "../query" -import { mountSearchResult } from "../result" -import { - SearchShare, - mountSearchShare -} from "../share" -import { - SearchSuggest, - mountSearchSuggest -} from "../suggest" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search - */ -export type Search = - | SearchQuery - | SearchResult - | SearchShare - | SearchSuggest - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput<SearchIndex> /* Search index observable */ - keyboard$: Observable<Keyboard> /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * 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 - * - * @returns Search component observable - */ -export function mountSearch( - el: HTMLElement, { index$, keyboard$ }: MountOptions -): Observable<Component<Search>> { - const config = configuration() - try { - const url = __search?.worker || config.search - const worker = setupSearchWorker(url, index$) - - /* Retrieve query and result components */ - const query = getComponentElement("search-query", el) - const result = getComponentElement("search-result", el) - - /* Re-emit query when search is ready */ - const { tx$, rx$ } = worker - tx$ - .pipe( - filter(isSearchQueryMessage), - sample(rx$.pipe(filter(isSearchReadyMessage))), - take(1) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - const active = getActiveElement() - switch (key.type) { - - /* Enter: go to first (best) result */ - case "Enter": - if (active === query) { - const anchors = new Map<HTMLAnchorElement, number>() - for (const anchor of getElements<HTMLAnchorElement>( - ":first-child [href]", result - )) { - const article = anchor.firstElementChild! - anchors.set(anchor, parseFloat( - article.getAttribute("data-md-score")! - )) - } - - /* Go to result with highest score, if any */ - if (anchors.size) { - const [[best]] = [...anchors].sort(([, a], [, b]) => b - a) - best.click() - } - - /* Otherwise omit form submission */ - key.claim() - } - break - - /* Escape or Tab: close search */ - case "Escape": - case "Tab": - setToggle("search", false) - query.blur() - break - - /* Vertical arrows: select previous or next search result */ - case "ArrowUp": - case "ArrowDown": - if (typeof active === "undefined") { - query.focus() - } 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) - els[i].focus() - } - - /* Prevent scrolling of page */ - key.claim() - break - - /* All other keys: hand to search query */ - default: - if (query !== getActiveElement()) - query.focus() - } - }) - - /* 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 "/": - query.focus() - query.select() - - /* Prevent scrolling of page */ - key.claim() - break - } - }) - - /* Create and return component */ - const query$ = mountSearchQuery(query, worker) - const result$ = mountSearchResult(result, worker, { query$ }) - return merge(query$, result$) - .pipe( - mergeWith( - - /* Search sharing */ - ...getComponentElements("search-share", el) - .map(child => mountSearchShare(child, { query$ })), - - /* Search suggestions */ - ...getComponentElements("search-suggest", el) - .map(child => mountSearchSuggest(child, worker, { keyboard$ })) - ) - ) - - /* Gracefully handle broken search */ - } catch (err) { - el.hidden = true - return NEVER - } -} diff --git a/src/assets/javascripts/components/search/highlight/.eslintrc b/src/assets/javascripts/components/search/highlight/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "no-null/no-null": "off" - } -} diff --git a/src/assets/javascripts/components/search/highlight/index.ts b/src/assets/javascripts/components/search/highlight/index.ts @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - ObservableInput, - combineLatest, - filter, - map, - startWith -} from "rxjs" - -import { getLocation } from "~/browser" -import { - SearchIndex, - setupSearchHighlighter -} from "~/integrations" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlighting - */ -export interface SearchHighlight { - nodes: Map<ChildNode, string> /* Map of replacements */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput<SearchIndex> /* Search index observable */ - location$: Observable<URL> /* Location observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search highlighting - * - * @param el - Content element - * @param options - Options - * - * @returns Search highlighting component observable - */ -export function mountSearchHiglight( - el: HTMLElement, { index$, location$ }: MountOptions -): Observable<Component<SearchHighlight>> { - return combineLatest([ - index$, - location$ - .pipe( - startWith(getLocation()), - filter(url => !!url.searchParams.get("h")) - ) - ]) - .pipe( - map(([index, url]) => setupSearchHighlighter(index.config, true)( - url.searchParams.get("h")! - )), - map(fn => { - const nodes = new Map<ChildNode, string>() - - /* Traverse text nodes and collect matches */ - const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT) - for (let node = it.nextNode(); node; node = it.nextNode()) { - if (node.parentElement?.offsetHeight) { - const original = node.textContent! - const replaced = fn(original) - if (replaced.length > original.length) - nodes.set(node as ChildNode, replaced) - } - } - - /* Replace original nodes with matches */ - for (const [node, text] of nodes) { - const { childNodes } = h("span", null, text) - node.replaceWith(...Array.from(childNodes)) - } - - /* Return component */ - return { ref: el, nodes } - }) - ) -} diff --git a/src/assets/javascripts/components/search/index.ts b/src/assets/javascripts/components/search/index.ts @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./highlight" -export * from "./query" -export * from "./result" -export * from "./share" -export * from "./suggest" diff --git a/src/assets/javascripts/components/search/query/index.ts b/src/assets/javascripts/components/search/query/index.ts @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - combineLatest, - delay, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - finalize, - fromEvent, - map, - merge, - share, - shareReplay, - startWith, - take, - takeLast, - takeUntil, - tap -} from "rxjs" - -import { translation } from "~/_" -import { - getLocation, - setToggle, - watchElementFocus, - watchToggle -} from "~/browser" -import { - SearchMessageType, - SearchQueryMessage, - SearchWorker, - defaultTransform, - isSearchReadyMessage -} from "~/integrations" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query - */ -export interface SearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch search query - * - * Note that the focus event which triggers re-reading the current query value - * is delayed by `1ms` so the input's empty state is allowed to propagate. - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query observable - */ -export function watchSearchQuery( - el: HTMLInputElement, { rx$ }: SearchWorker -): Observable<SearchQuery> { - const fn = __search?.transform || defaultTransform - - /* Immediately show search dialog */ - const { searchParams } = getLocation() - if (searchParams.has("q")) - setToggle("search", true) - - /* Intercept query parameter (deep link) */ - const param$ = rx$ - .pipe( - filter(isSearchReadyMessage), - take(1), - map(() => searchParams.get("q") || "") - ) - - /* Remove query parameter when search is closed */ - watchToggle("search") - .pipe( - filter(active => !active), - take(1) - ) - .subscribe(() => { - const url = new URL(location.href) - url.searchParams.delete("q") - history.replaceState({}, "", `${url}`) - }) - - /* Set query from parameter */ - param$.subscribe(value => { // TODO: not ideal - find a better way - if (value) { - el.value = value - el.focus() - } - }) - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)), - param$ - ) - .pipe( - map(() => fn(el.value)), - startWith(""), - distinctUntilChanged(), - ) - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ value, focus })), - shareReplay(1) - ) -} - -/** - * Mount search query - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query component observable - */ -export function mountSearchQuery( - el: HTMLInputElement, { tx$, rx$ }: SearchWorker -): Observable<Component<SearchQuery, HTMLInputElement>> { - const push$ = new Subject<SearchQuery>() - const done$ = push$.pipe(takeLast(1)) - - /* Handle value changes */ - push$ - .pipe( - distinctUntilKeyChanged("value"), - map(({ value }): SearchQueryMessage => ({ - type: SearchMessageType.QUERY, - data: value - })) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Handle focus changes */ - push$ - .pipe( - distinctUntilKeyChanged("focus") - ) - .subscribe(({ focus }) => { - if (focus) { - setToggle("search", focus) - el.placeholder = "" - } else { - el.placeholder = translation("search.placeholder") - } - }) - - /* Handle reset */ - fromEvent(el.form!, "reset") - .pipe( - takeUntil(done$) - ) - .subscribe(() => el.focus()) - - /* Create and return component */ - return watchSearchQuery(el, { tx$, rx$ }) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })), - share() - ) -} diff --git a/src/assets/javascripts/components/search/result/index.ts b/src/assets/javascripts/components/search/result/index.ts @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - bufferCount, - filter, - finalize, - map, - merge, - of, - skipUntil, - switchMap, - take, - tap, - withLatestFrom, - zipWith -} from "rxjs" - -import { translation } from "~/_" -import { - getElement, - watchElementBoundary -} from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchReadyMessage, - isSearchResultMessage -} from "~/integrations" -import { renderSearchResultItem } from "~/templates" -import { round } from "~/utilities" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search result list - * - * This function performs a lazy rendering of the search results, depending on - * the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchResult( - el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions -): Observable<Component<SearchResult>> { - const push$ = new Subject<SearchResult>() - const boundary$ = watchElementBoundary(el.parentElement!) - .pipe( - filter(Boolean) - ) - - /* Retrieve nested components */ - const meta = getElement(":scope > :first-child", el) - const list = getElement(":scope > :last-child", el) - - /* Wait until search is ready */ - const ready$ = rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - - /* Update search result metadata */ - push$ - .pipe( - withLatestFrom(query$), - skipUntil(ready$) - ) - .subscribe(([{ items }, { value }]) => { - if (value) { - switch (items.length) { - - /* No results */ - case 0: - meta.textContent = translation("search.result.none") - break - - /* One result */ - case 1: - meta.textContent = translation("search.result.one") - break - - /* Multiple result */ - default: - meta.textContent = translation( - "search.result.other", - round(items.length) - ) - } - } else { - meta.textContent = translation("search.result.placeholder") - } - }) - - /* Update search result list */ - push$ - .pipe( - tap(() => list.innerHTML = ""), - switchMap(({ items }) => merge( - of(...items.slice(0, 10)), - of(...items.slice(10)) - .pipe( - bufferCount(4), - zipWith(boundary$), - switchMap(([chunk]) => chunk) - ) - )) - ) - .subscribe(result => list.appendChild( - renderSearchResultItem(result) - )) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/assets/javascripts/components/search/share/index.ts b/src/assets/javascripts/components/search/share/index.ts @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - finalize, - fromEvent, - map, - tap -} from "rxjs" - -import { getLocation } from "~/browser" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search sharing - */ -export interface SearchShare { - url: URL /* Deep link for sharing */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - query$: Observable<SearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search sharing - * - * @param _el - Search sharing element - * @param options - Options - * - * @returns Search sharing observable - */ -export function watchSearchShare( - _el: HTMLElement, { query$ }: WatchOptions -): Observable<SearchShare> { - return query$ - .pipe( - map(({ value }) => { - const url = getLocation() - url.hash = "" - url.searchParams.delete("h") - url.searchParams.set("q", value) - return { url } - }) - ) -} - -/** - * Mount search sharing - * - * @param el - Search sharing element - * @param options - Options - * - * @returns Search sharing component observable - */ -export function mountSearchShare( - el: HTMLAnchorElement, options: MountOptions -): Observable<Component<SearchShare>> { - const push$ = new Subject<SearchShare>() - push$.subscribe(({ url }) => { - el.setAttribute("data-clipboard-text", el.href) - el.href = `${url}` - }) - - /* Prevent following of link */ - fromEvent(el, "click") - .subscribe(ev => ev.preventDefault()) - - /* Create and return component */ - return watchSearchShare(el, options) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/assets/javascripts/components/search/suggest/index.ts b/src/assets/javascripts/components/search/suggest/index.ts @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - asyncScheduler, - combineLatestWith, - distinctUntilChanged, - filter, - finalize, - fromEvent, - map, - merge, - observeOn, - tap -} from "rxjs" - -import { Keyboard } from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchResultMessage -} from "~/integrations" - -import { Component, getComponentElement } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search suggestions - */ -export interface SearchSuggest {} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - keyboard$: Observable<Keyboard> /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search suggestions - * - * This function will perform a lazy rendering of the search results, depending - * on the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchSuggest( - el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions -): Observable<Component<SearchSuggest>> { - const push$ = new Subject<SearchResult>() - - /* Retrieve query component and track all changes */ - const query = getComponentElement("search-query") - const query$ = merge( - fromEvent(query, "keydown"), - fromEvent(query, "focus") - ) - .pipe( - observeOn(asyncScheduler), - map(() => query.value), - distinctUntilChanged(), - ) - - /* Update search suggestions */ - push$ - .pipe( - combineLatestWith(query$), - map(([{ suggestions }, value]) => { - const words = value.split(/([\s-]+)/) - if (suggestions?.length && words[words.length - 1]) { - const last = suggestions[suggestions.length - 1] - if (last.startsWith(words[words.length - 1])) - words[words.length - 1] = last - } else { - words.length = 0 - } - return words - }) - ) - .subscribe(words => el.innerHTML = words - .join("") - .replace(/\s/g, "&nbsp;") - ) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - switch (key.type) { - - /* Right arrow: accept current suggestion */ - case "ArrowRight": - if ( - el.innerText.length && - query.selectionStart === query.value.length - ) - query.value = el.innerText - break - } - }) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(() => ({ ref: el })) - ) -} diff --git a/src/assets/javascripts/components/sidebar/index.ts b/src/assets/javascripts/components/sidebar/index.ts @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - animationFrameScheduler, - auditTime, - combineLatest, - defer, - distinctUntilChanged, - finalize, - map, - tap, - withLatestFrom -} from "rxjs" - -import { - Viewport, - getElement, - getElementOffset -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sidebar - */ -export interface Sidebar { - height: number /* Sidebar height */ - locked: boolean /* Sidebar is locked */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - main$: Observable<Main> /* Main area observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch sidebar - * - * This function returns an observable that computes the visual parameters of - * the sidebar which depends on the vertical viewport offset, as well as the - * height of the main area. When the page is scrolled beyond the header, the - * sidebar is locked and fills the remaining space. - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar observable - */ -export function watchSidebar( - el: HTMLElement, { viewport$, main$ }: WatchOptions -): Observable<Sidebar> { - const parent = el.parentElement! - const adjust = - parent.offsetTop - - parent.parentElement!.offsetTop - - /* Compute the sidebar's available height and if it should be locked */ - return combineLatest([main$, viewport$]) - .pipe( - map(([{ offset, height }, { offset: { y } }]) => { - height = height - + Math.min(adjust, Math.max(0, y - offset)) - - adjust - return { - height, - locked: y >= offset + adjust - } - }), - distinctUntilChanged((a, b) => ( - a.height === b.height && - a.locked === b.locked - )) - ) -} - -/** - * Mount sidebar - * - * This function doesn't set the height of the actual sidebar, but of its first - * child – the `.md-sidebar__scrollwrap` element in order to mitigiate jittery - * sidebars when the footer is scrolled into view. At some point we switched - * from `absolute` / `fixed` positioning to `sticky` positioning, significantly - * reducing jitter in some browsers (respectively Firefox and Safari) when - * scrolling from the top. However, top-aligned sticky positioning means that - * the sidebar snaps to the bottom when the end of the container is reached. - * This is what leads to the mentioned jitter, as the sidebar's height may be - * updated too slowly. - * - * This behaviour can be mitigiated by setting the height of the sidebar to `0` - * while preserving the padding, and the height on its first element. - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar component observable - */ -export function mountSidebar( - el: HTMLElement, { header$, ...options }: MountOptions -): Observable<Component<Sidebar>> { - const inner = getElement(".md-sidebar__scrollwrap", el) - const { y } = getElementOffset(inner) - return defer(() => { - const push$ = new Subject<Sidebar>() - push$ - .pipe( - auditTime(0, animationFrameScheduler), - withLatestFrom(header$) - ) - .subscribe({ - - /* Handle emission */ - next([{ height }, { height: offset }]) { - inner.style.height = `${height - 2 * y}px` - el.style.top = `${offset}px` - }, - - /* Handle complete */ - complete() { - inner.style.height = "" - el.style.top = "" - } - }) - - /* Create and return component */ - return watchSidebar(el, options) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/source/_/index.ts b/src/assets/javascripts/components/source/_/index.ts @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - Subject, - catchError, - defer, - filter, - finalize, - map, - of, - shareReplay, - tap -} from "rxjs" - -import { getElement } from "~/browser" -import { renderSourceFacts } from "~/templates" - -import { Component } from "../../_" -import { - SourceFacts, - fetchSourceFacts -} from "../facts" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository information - */ -export interface Source { - facts: SourceFacts /* Repository facts */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Repository information observable - */ -let fetch$: Observable<Source> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch repository information - * - * This function tries to read the repository facts from session storage, and - * if unsuccessful, fetches them from the underlying provider. - * - * @param el - Repository information element - * - * @returns Repository information observable - */ -export function watchSource( - el: HTMLAnchorElement -): Observable<Source> { - return fetch$ ||= defer(() => { - const cached = __md_get<SourceFacts>("__source", sessionStorage) - if (cached) - return of(cached) - else - return fetchSourceFacts(el.href) - .pipe( - tap(facts => __md_set("__source", facts, sessionStorage)) - ) - }) - .pipe( - catchError(() => EMPTY), - filter(facts => Object.keys(facts).length > 0), - map(facts => ({ facts })), - shareReplay(1) - ) -} - -/** - * Mount repository information - * - * @param el - Repository information element - * - * @returns Repository information component observable - */ -export function mountSource( - el: HTMLAnchorElement -): Observable<Component<Source>> { - const inner = getElement(":scope > :last-child", el) - return defer(() => { - const push$ = new Subject<Source>() - push$.subscribe(({ facts }) => { - inner.appendChild(renderSourceFacts(facts)) - inner.classList.add("md-source__repository--active") - }) - - /* Create and return component */ - return watchSource(el) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/source/facts/_/index.ts b/src/assets/javascripts/components/source/facts/_/index.ts @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { EMPTY, Observable } from "rxjs" - -import { fetchSourceFactsFromGitHub } from "../github" -import { fetchSourceFactsFromGitLab } from "../gitlab" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository facts for repositories - */ -export interface RepositoryFacts { - stars?: number /* Number of stars */ - forks?: number /* Number of forks */ - version?: string /* Latest version */ -} - -/** - * Repository facts for organizations - */ -export interface OrganizationFacts { - repositories?: number /* Number of repositories */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Repository facts - */ -export type SourceFacts = - | RepositoryFacts - | OrganizationFacts - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch repository facts - * - * @param url - Repository URL - * - * @returns Repository facts observable - */ -export function fetchSourceFacts( - url: string -): Observable<SourceFacts> { - const [type] = url.match(/(git(?:hub|lab))/i) || [] - switch (type.toLowerCase()) { - - /* GitHub repository */ - case "github": - const [, user, repo] = url.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i)! - return fetchSourceFactsFromGitHub(user, repo) - - /* GitLab repository */ - case "gitlab": - const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i)! - return fetchSourceFactsFromGitLab(base, slug) - - /* Everything else */ - default: - return EMPTY - } -} diff --git a/src/assets/javascripts/components/source/facts/github/index.ts b/src/assets/javascripts/components/source/facts/github/index.ts @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Repo, User } from "github-types" -import { - EMPTY, - Observable, - catchError, - defaultIfEmpty, - map, - zip -} from "rxjs" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * GitHub release (partial) - */ -interface Release { - tag_name: string /* Tag name */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitHub repository facts - * - * @param user - GitHub user or organization - * @param repo - GitHub repository - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitHub( - user: string, repo?: string -): Observable<SourceFacts> { - if (typeof repo !== "undefined") { - const url = `https://api.github.com/repos/${user}/${repo}` - return zip( - - /* Fetch version */ - requestJSON<Release>(`${url}/releases/latest`) - .pipe( - catchError(() => EMPTY), // @todo refactor instant loading - map(release => ({ - version: release.tag_name - })), - defaultIfEmpty({}) - ), - - /* Fetch stars and forks */ - requestJSON<Repo>(url) - .pipe( - catchError(() => EMPTY), // @todo refactor instant loading - map(info => ({ - stars: info.stargazers_count, - forks: info.forks_count - })), - defaultIfEmpty({}) - ) - ) - .pipe( - map(([release, info]) => ({ ...release, ...info })) - ) - - /* User or organization */ - } else { - const url = `https://api.github.com/users/${user}` - return requestJSON<User>(url) - .pipe( - map(info => ({ - repositories: info.public_repos - })), - defaultIfEmpty({}) - ) - } -} diff --git a/src/assets/javascripts/components/source/facts/gitlab/index.ts b/src/assets/javascripts/components/source/facts/gitlab/index.ts @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { ProjectSchema } from "gitlab" -import { - EMPTY, - Observable, - catchError, - defaultIfEmpty, - map -} from "rxjs" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitLab repository facts - * - * @param base - GitLab base - * @param project - GitLab project - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitLab( - base: string, project: string -): Observable<SourceFacts> { - const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}` - return requestJSON<ProjectSchema>(url) - .pipe( - catchError(() => EMPTY), // @todo refactor instant loading - map(({ star_count, forks_count }) => ({ - stars: star_count, - forks: forks_count - })), - defaultIfEmpty({}) - ) -} diff --git a/src/assets/javascripts/components/source/facts/index.ts b/src/assets/javascripts/components/source/facts/index.ts @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./github" -export * from "./gitlab" diff --git a/src/assets/javascripts/components/source/index.ts b/src/assets/javascripts/components/source/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./facts" diff --git a/src/assets/javascripts/components/tabs/index.ts b/src/assets/javascripts/components/tabs/index.ts @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - defer, - distinctUntilKeyChanged, - finalize, - map, - of, - switchMap, - tap -} from "rxjs" - -import { feature } from "~/_" -import { - Viewport, - watchElementSize, - watchViewportAt -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Navigation tabs - */ -export interface Tabs { - hidden: boolean /* Navigation tabs are hidden */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch navigation tabs - * - * @param el - Navigation tabs element - * @param options - Options - * - * @returns Navigation tabs observable - */ -export function watchTabs( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<Tabs> { - return watchElementSize(document.body) - .pipe( - switchMap(() => watchViewportAt(el, { header$, viewport$ })), - map(({ offset: { y } }) => { - return { - hidden: y >= 10 - } - }), - distinctUntilKeyChanged("hidden") - ) -} - -/** - * 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 - * - * @returns Navigation tabs component observable - */ -export function mountTabs( - el: HTMLElement, options: MountOptions -): Observable<Component<Tabs>> { - return defer(() => { - const push$ = new Subject<Tabs>() - push$.subscribe({ - - /* Handle emission */ - next({ hidden }) { - el.hidden = hidden - }, - - /* Handle complete */ - complete() { - el.hidden = false - } - }) - - /* Create and return component */ - return ( - feature("navigation.tabs.sticky") - ? of({ hidden: false }) - : watchTabs(el, options) - ) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/toc/index.ts b/src/assets/javascripts/components/toc/index.ts @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - bufferCount, - combineLatestWith, - debounceTime, - defer, - distinctUntilChanged, - distinctUntilKeyChanged, - finalize, - map, - of, - repeat, - scan, - share, - skip, - startWith, - switchMap, - takeLast, - takeUntil, - tap, - withLatestFrom -} from "rxjs" - -import { feature } from "~/_" -import { - Viewport, - getElement, - getElements, - getLocation, - getOptionalElement, - watchElementSize -} from "~/browser" - -import { - Component, - getComponentElement -} from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Table of contents - */ -export interface TableOfContents { - prev: HTMLAnchorElement[][] /* Anchors (previous) */ - next: HTMLAnchorElement[][] /* Anchors (next) */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - target$: Observable<HTMLElement> /* Location target observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch table of contents - * - * This is effectively a scroll spy implementation which will account for the - * fixed header and automatically re-calculate anchor offsets when the viewport - * is resized. The returned observable will only emit if the table of contents - * needs to be repainted. - * - * This implementation tracks an anchor element's entire path starting from its - * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the - * Material theme currently doesn't make use of this information, it enables - * the styling of the entire hierarchy through customization. - * - * Note that the current anchor is the last item of the `prev` anchor list. - * - * @param el - Table of contents element - * @param options - Options - * - * @returns Table of contents observable - */ -export function watchTableOfContents( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable<TableOfContents> { - const table = new Map<HTMLAnchorElement, HTMLElement>() - - /* Compute anchor-to-target mapping */ - const anchors = getElements<HTMLAnchorElement>("[href^=\\#]", el) - for (const anchor of anchors) { - const id = decodeURIComponent(anchor.hash.substring(1)) - const target = getOptionalElement(`[id="${id}"]`) - if (typeof target !== "undefined") - table.set(anchor, target) - } - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - distinctUntilKeyChanged("height"), - map(({ height }) => { - const main = getComponentElement("main") - const grid = getElement(":scope > :first-child", main) - return height + 0.8 * ( - grid.offsetTop - - main.offsetTop - ) - }), - share() - ) - - /* Compute partition of previous and next anchors */ - const partition$ = watchElementSize(document.body) - .pipe( - distinctUntilKeyChanged("height"), - - /* Build index to map anchor paths to vertical offsets */ - switchMap(body => defer(() => { - let path: HTMLAnchorElement[] = [] - return of([...table].reduce((index, [anchor, target]) => { - while (path.length) { - const last = table.get(path[path.length - 1])! - if (last.tagName >= target.tagName) { - path.pop() - } else { - break - } - } - - /* If the current anchor is hidden, continue with its parent */ - let offset = target.offsetTop - while (!offset && target.parentElement) { - target = target.parentElement - offset = target.offsetTop - } - - /* Map reversed anchor path to vertical offset */ - return index.set( - [...path = [...path, anchor]].reverse(), - offset - ) - }, new Map<HTMLAnchorElement[], number>())) - }) - .pipe( - - /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */ - map(index => new Map([...index].sort(([, a], [, b]) => a - b))), - combineLatestWith(adjust$), - - /* Re-compute partition when viewport offset changes */ - switchMap(([index, adjust]) => viewport$ - .pipe( - scan(([prev, next], { offset: { y }, size }) => { - const last = y + size.height >= Math.floor(body.height) - - /* Look forward */ - while (next.length) { - const [, offset] = next[0] - if (offset - adjust < y || last) { - prev = [...prev, next.shift()!] - } else { - break - } - } - - /* Look backward */ - while (prev.length) { - const [, offset] = prev[prev.length - 1] - if (offset - adjust >= y && !last) { - next = [prev.pop()!, ...next] - } else { - break - } - } - - /* Return partition */ - return [prev, next] - }, [[], [...index]]), - distinctUntilChanged((a, b) => ( - a[0] === b[0] && - a[1] === b[1] - )) - ) - ) - ) - ) - ) - - /* Compute and return anchor list migrations */ - return partition$ - .pipe( - map(([prev, next]) => ({ - prev: prev.map(([path]) => path), - next: next.map(([path]) => path) - })), - - /* Extract anchor list migrations */ - startWith({ prev: [], next: [] }), - bufferCount(2, 1), - map(([a, b]) => { - - /* Moving down */ - if (a.prev.length < b.prev.length) { - return { - prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length), - next: [] - } - - /* Moving up */ - } else { - return { - prev: b.prev.slice(-1), - next: b.next.slice(0, b.next.length - a.next.length) - } - } - }) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount table of contents - * - * @param el - Table of contents element - * @param options - Options - * - * @returns Table of contents component observable - */ -export function mountTableOfContents( - el: HTMLElement, { viewport$, header$, target$ }: MountOptions -): Observable<Component<TableOfContents>> { - return defer(() => { - const push$ = new Subject<TableOfContents>() - const done$ = push$.pipe(takeLast(1)) - push$.subscribe(({ prev, next }) => { - - /* Look forward */ - for (const [anchor] of next) { - anchor.classList.remove("md-nav__link--passed") - anchor.classList.remove("md-nav__link--active") - } - - /* Look backward */ - for (const [index, [anchor]] of prev.entries()) { - anchor.classList.add("md-nav__link--passed") - anchor.classList.toggle( - "md-nav__link--active", - index === prev.length - 1 - ) - } - }) - - /* Set up anchor tracking, if enabled */ - if (feature("navigation.tracking")) - viewport$ - .pipe( - takeUntil(done$), - distinctUntilKeyChanged("offset"), - debounceTime(250), - skip(1), - takeUntil(target$.pipe(skip(1))), - repeat({ delay: 250 }), - withLatestFrom(push$) - ) - .subscribe(([, { prev }]) => { - const url = getLocation() - - /* Set hash fragment to active anchor */ - const anchor = prev[prev.length - 1] - if (anchor && anchor.length) { - const [active] = anchor - const { hash } = new URL(active.href) - if (url.hash !== hash) { - url.hash = hash - history.replaceState({}, "", `${url}`) - } - - /* Reset anchor when at the top */ - } else { - url.hash = "" - history.replaceState({}, "", `${url}`) - } - }) - - /* Create and return component */ - return watchTableOfContents(el, { viewport$, header$ }) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) - }) -} diff --git a/src/assets/javascripts/components/top/index.ts b/src/assets/javascripts/components/top/index.ts @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - Subject, - bufferCount, - combineLatest, - distinctUntilChanged, - distinctUntilKeyChanged, - endWith, - finalize, - map, - repeat, - skip, - takeLast, - takeUntil, - tap -} from "rxjs" - -import { Viewport } from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Back-to-top button - */ -export interface BackToTop { - hidden: boolean /* Back-to-top button is hidden */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - main$: Observable<Main> /* Main area observable */ - target$: Observable<HTMLElement> /* Location target observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - header$: Observable<Header> /* Header observable */ - main$: Observable<Main> /* Main area observable */ - target$: Observable<HTMLElement> /* Location target observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch back-to-top - * - * @param _el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top observable - */ -export function watchBackToTop( - _el: HTMLElement, { viewport$, main$, target$ }: WatchOptions -): Observable<BackToTop> { - - /* Compute direction */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => a > b && b > 0), - distinctUntilChanged() - ) - - /* Compute whether main area is active */ - const active$ = main$ - .pipe( - map(({ active }) => active) - ) - - /* Compute threshold for hiding */ - return combineLatest([active$, direction$]) - .pipe( - map(([active, direction]) => !(active && direction)), - distinctUntilChanged(), - takeUntil(target$.pipe(skip(1))), - endWith(true), - repeat({ delay: 250 }), - map(hidden => ({ hidden })) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount back-to-top - * - * @param el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top component observable - */ -export function mountBackToTop( - el: HTMLElement, { viewport$, header$, main$, target$ }: MountOptions -): Observable<Component<BackToTop>> { - const push$ = new Subject<BackToTop>() - const done$ = push$.pipe(takeLast(1)) - push$.subscribe({ - - /* Handle emission */ - next({ hidden }) { - el.hidden = hidden - if (hidden) { - el.setAttribute("tabindex", "-1") - el.blur() - } else { - el.removeAttribute("tabindex") - } - }, - - /* Handle complete */ - complete() { - el.style.top = "" - el.hidden = true - el.removeAttribute("tabindex") - } - }) - - /* Watch header height */ - header$ - .pipe( - takeUntil(done$), - distinctUntilKeyChanged("height") - ) - .subscribe(({ height }) => { - el.style.top = `${height + 16}px` - }) - - /* Create and return component */ - return watchBackToTop(el, { viewport$, main$, target$ }) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/assets/javascripts/integrations/clipboard/index.ts b/src/assets/javascripts/integrations/clipboard/index.ts @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 ClipboardJS from "clipboard" -import { - Observable, - Subject, - map, - tap -} from "rxjs" - -import { translation } from "~/_" -import { getElement } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - alert$: Subject<string> /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Extract text to copy - * - * @param el - HTML element - * - * @returns Extracted text - */ -function extract(el: HTMLElement): string { - el.setAttribute("data-md-copying", "") - const text = el.innerText - el.removeAttribute("data-md-copying") - return text -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up Clipboard.js integration - * - * @param options - Options - */ -export function setupClipboardJS( - { alert$ }: SetupOptions -): void { - if (ClipboardJS.isSupported()) { - new Observable<ClipboardJS.Event>(subscriber => { - new ClipboardJS("[data-clipboard-target], [data-clipboard-text]", { - text: el => ( - el.getAttribute("data-clipboard-text")! || - extract(getElement( - el.getAttribute("data-clipboard-target")! - )) - ) - }) - .on("success", ev => subscriber.next(ev)) - }) - .pipe( - tap(ev => { - const trigger = ev.trigger as HTMLElement - trigger.focus() - }), - map(() => translation("clipboard.copied")) - ) - .subscribe(alert$) - } -} diff --git a/src/assets/javascripts/integrations/index.ts b/src/assets/javascripts/integrations/index.ts @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./clipboard" -export * from "./instant" -export * from "./search" -export * from "./sitemap" -export * from "./version" diff --git a/src/assets/javascripts/integrations/instant/.eslintrc b/src/assets/javascripts/integrations/instant/.eslintrc @@ -1,6 +0,0 @@ -{ - "rules": { - "no-self-assign": "off", - "no-null/no-null": "off" - } -} diff --git a/src/assets/javascripts/integrations/instant/index.ts b/src/assets/javascripts/integrations/instant/index.ts @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - NEVER, - Observable, - Subject, - bufferCount, - catchError, - concatMap, - debounceTime, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - fromEvent, - map, - merge, - of, - sample, - share, - skip, - skipUntil, - switchMap -} from "rxjs" - -import { configuration, feature } from "~/_" -import { - Viewport, - ViewportOffset, - getElements, - getOptionalElement, - request, - setLocation, - setLocationHash -} from "~/browser" -import { getComponentElement } from "~/components" -import { h } from "~/utilities" - -import { fetchSitemap } from "../sitemap" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * History state - */ -export interface HistoryState { - url: URL /* State URL */ - offset?: ViewportOffset /* State viewport offset */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - document$: Subject<Document> /* Document subject */ - location$: Subject<URL> /* Location subject */ - viewport$: Observable<Viewport> /* Viewport observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up instant loading - * - * When fetching, theoretically, we could use `responseType: "document"`, but - * since all MkDocs links are relative, we need to make sure that the current - * location matches the document we just loaded. Otherwise any relative links - * in the document could use the old location. - * - * This is the reason why we need to synchronize history events and the process - * of fetching the document for navigation changes (except `popstate` events): - * - * 1. Fetch document via `XMLHTTPRequest` - * 2. Set new location via `history.pushState` - * 3. Parse and emit fetched document - * - * For `popstate` events, we must not use `history.pushState`, or the forward - * history will be irreversibly overwritten. In case the request fails, the - * location change is dispatched regularly. - * - * @param options - Options - */ -export function setupInstantLoading( - { document$, location$, viewport$ }: SetupOptions -): void { - const config = configuration() - if (location.protocol === "file:") - return - - /* Disable automatic scroll restoration */ - if ("scrollRestoration" in history) { - history.scrollRestoration = "manual" - - /* Hack: ensure that reloads restore viewport offset */ - fromEvent(window, "beforeunload") - .subscribe(() => { - history.scrollRestoration = "auto" - }) - } - - /* Hack: ensure absolute favicon link to omit 404s when switching */ - const favicon = getOptionalElement<HTMLLinkElement>("link[rel=icon]") - if (typeof favicon !== "undefined") - favicon.href = favicon.href - - /* Intercept internal navigation */ - const push$ = fetchSitemap() - .pipe( - map(paths => paths.map(path => `${new URL(path, config.base)}`)), - switchMap(urls => fromEvent<MouseEvent>(document.body, "click") - .pipe( - filter(ev => !ev.metaKey && !ev.ctrlKey), - switchMap(ev => { - if (ev.target instanceof Element) { - const el = ev.target.closest("a") - if (el && !el.target) { - const url = new URL(el.href) - - /* Canonicalize URL */ - url.search = "" - url.hash = "" - - /* Check if URL should be intercepted */ - if ( - url.pathname !== location.pathname && - urls.includes(url.toString()) - ) { - ev.preventDefault() - return of({ - url: new URL(el.href) - }) - } - } - } - return NEVER - }) - ) - ), - share<HistoryState>() - ) - - /* Intercept history back and forward */ - const pop$ = fromEvent<PopStateEvent>(window, "popstate") - .pipe( - filter(ev => ev.state !== null), - map(ev => ({ - url: new URL(location.href), - offset: ev.state - })), - share<HistoryState>() - ) - - /* Emit location change */ - merge(push$, pop$) - .pipe( - distinctUntilChanged((a, b) => a.url.href === b.url.href), - map(({ url }) => url) - ) - .subscribe(location$) - - /* Fetch document via `XMLHTTPRequest` */ - const response$ = location$ - .pipe( - distinctUntilKeyChanged("pathname"), - switchMap(url => request(url.href) - .pipe( - catchError(() => { - setLocation(url) - return NEVER - }) - ) - ), - share() - ) - - /* Set new location via `history.pushState` */ - push$ - .pipe( - sample(response$) - ) - .subscribe(({ url }) => { - history.pushState({}, "", `${url}`) - }) - - /* Parse and emit fetched document */ - const dom = new DOMParser() - response$ - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/html")) - ) - .subscribe(document$) - - /* Replace meta tags and components */ - document$ - .pipe( - skip(1) - ) - .subscribe(replacement => { - for (const selector of [ - - /* Meta tags */ - "title", - "link[rel=canonical]", - "meta[name=author]", - "meta[name=description]", - - /* Components */ - "[data-md-component=announce]", - "[data-md-component=container]", - "[data-md-component=header-topic]", - "[data-md-component=outdated]", - "[data-md-component=logo]", - "[data-md-component=skip]", - ...feature("navigation.tabs.sticky") - ? ["[data-md-component=tabs]"] - : [] - ]) { - const source = getOptionalElement(selector) - const target = getOptionalElement(selector, replacement) - if ( - typeof source !== "undefined" && - typeof target !== "undefined" - ) { - source.replaceWith(target) - } - } - }) - - /* Re-evaluate scripts */ - document$ - .pipe( - skip(1), - map(() => getComponentElement("container")), - switchMap(el => getElements("script", el)), - concatMap(el => { - const script = h("script") - if (el.src) { - for (const name of el.getAttributeNames()) - script.setAttribute(name, el.getAttribute(name)!) - el.replaceWith(script) - - /* Complete when script is loaded */ - return new Observable(observer => { - script.onload = () => observer.complete() - }) - - /* Complete immediately */ - } else { - script.textContent = el.textContent - el.replaceWith(script) - return EMPTY - } - }) - ) - .subscribe() - - /* Emit history state change */ - merge(push$, pop$) - .pipe( - sample(document$) - ) - .subscribe(({ url, offset }) => { - if (url.hash && !offset) { - setLocationHash(url.hash) - } else { - window.scrollTo(0, offset?.y || 0) - } - }) - - /* Debounce update of viewport offset */ - viewport$ - .pipe( - skipUntil(push$), - debounceTime(250), - distinctUntilKeyChanged("offset") - ) - .subscribe(({ offset }) => { - history.replaceState(offset, "") - }) - - /* Set viewport offset from history */ - merge(push$, pop$) - .pipe( - bufferCount(2, 1), - filter(([a, b]) => a.url.pathname === b.url.pathname), - map(([, state]) => state) - ) - .subscribe(({ offset }) => { - window.scrollTo(0, offset?.y || 0) - }) -} diff --git a/src/assets/javascripts/integrations/search/_/.eslintrc b/src/assets/javascripts/integrations/search/_/.eslintrc @@ -1,6 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "no-console": "off" - } -} diff --git a/src/assets/javascripts/integrations/search/_/index.ts b/src/assets/javascripts/integrations/search/_/index.ts @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - SearchDocument, - SearchDocumentMap, - setupSearchDocumentMap -} from "../document" -import { - SearchHighlightFactoryFn, - setupSearchHighlighter -} from "../highlighter" -import { SearchOptions } from "../options" -import { - SearchQueryTerms, - getSearchQueryTerms, - parseSearchQuery -} from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search index configuration - */ -export interface SearchIndexConfig { - lang: string[] /* Search languages */ - separator: string /* Search separator */ -} - -/** - * Search index document - */ -export interface SearchIndexDocument { - location: string /* Document location */ - title: string /* Document title */ - text: string /* Document text */ - tags?: string[] /* Document tags */ - boost?: number /* Document boost */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search index - * - * This interfaces describes the format of the `search_index.json` file which - * is automatically built by the MkDocs search plugin. - */ -export interface SearchIndex { - config: SearchIndexConfig /* Search index configuration */ - docs: SearchIndexDocument[] /* Search index documents */ - options: SearchOptions /* Search options */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search metadata - */ -export interface SearchMetadata { - score: number /* Score (relevance) */ - terms: SearchQueryTerms /* Search query terms */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search result document - */ -export type SearchResultDocument = SearchDocument & SearchMetadata - -/** - * Search result item - */ -export type SearchResultItem = SearchResultDocument[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search result - */ -export interface SearchResult { - items: SearchResultItem[] /* Search result items */ - suggestions?: string[] /* Search suggestions */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Compute the difference of two lists of strings - * - * @param a - 1st list of strings - * @param b - 2nd list of strings - * - * @returns Difference - */ -function difference(a: string[], b: string[]): string[] { - const [x, y] = [new Set(a), new Set(b)] - return [ - ...new Set([...x].filter(value => !y.has(value))) - ] -} - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -export class Search { - - /** - * Search document mapping - * - * A mapping of URLs (including hash fragments) to the actual articles and - * sections of the documentation. The search document mapping must be created - * regardless of whether the index was prebuilt or not, as Lunr.js itself - * only stores the actual index. - */ - protected documents: SearchDocumentMap - - /** - * Search highlight factory function - */ - protected highlight: SearchHighlightFactoryFn - - /** - * The underlying Lunr.js search index - */ - protected index: lunr.Index - - /** - * Search options - */ - protected options: SearchOptions - - /** - * Create the search integration - * - * @param data - Search index - */ - public constructor({ config, docs, options }: SearchIndex) { - this.options = options - - /* Set up document map and highlighter factory */ - this.documents = setupSearchDocumentMap(docs) - this.highlight = setupSearchHighlighter(config, false) - - /* Set separator for tokenizer */ - lunr.tokenizer.separator = new RegExp(config.separator) - - /* Create search index */ - this.index = lunr(function () { - - /* Set up multi-language support */ - if (config.lang.length === 1 && config.lang[0] !== "en") { - this.use((lunr as any)[config.lang[0]]) - } else if (config.lang.length > 1) { - this.use((lunr as any).multiLanguage(...config.lang)) - } - - /* Compute functions to be removed from the pipeline */ - const fns = difference([ - "trimmer", "stopWordFilter", "stemmer" - ], options.pipeline) - - /* Remove functions from the pipeline for registered languages */ - for (const lang of config.lang.map(language => ( - language === "en" ? lunr : (lunr as any)[language] - ))) { - for (const fn of fns) { - this.pipeline.remove(lang[fn]) - this.searchPipeline.remove(lang[fn]) - } - } - - /* Set up reference */ - this.ref("location") - - /* Set up fields */ - this.field("title", { boost: 1e3 }) - this.field("text") - this.field("tags", { boost: 1e6, extractor: doc => { - const { tags = [] } = doc as SearchDocument - return tags.reduce((list, tag) => [ - ...list, - ...lunr.tokenizer(tag) - ], [] as lunr.Token[]) - } }) - - /* Index documents */ - for (const doc of docs) - this.add(doc, { boost: doc.boost }) - }) - } - - /** - * Search for matching documents - * - * The search index which MkDocs provides is divided up into articles, which - * contain the whole content of the individual pages, and sections, which only - * contain the contents of the subsections obtained by breaking the individual - * pages up at `h1` ... `h6`. As there may be many sections on different pages - * with identical titles (for example within this very project, e.g. "Usage" - * or "Installation"), they need to be put into the context of the containing - * page. For this reason, section results are grouped within their respective - * articles which are the top-level results that are returned. - * - * @param query - Query value - * - * @returns Search results - */ - public search(query: string): SearchResult { - if (query) { - try { - const highlight = this.highlight(query) - - /* Parse query to extract clauses for analysis */ - const clauses = parseSearchQuery(query) - .filter(clause => ( - clause.presence !== lunr.Query.presence.PROHIBITED - )) - - /* Perform search and post-process results */ - const groups = this.index.search(`${query}*`) - - /* Apply post-query boosts based on title and search query terms */ - .reduce<SearchResultItem>((item, { ref, score, matchData }) => { - const document = this.documents.get(ref) - if (typeof document !== "undefined") { - const { location, title, text, tags, parent } = document - - /* Compute and analyze search query terms */ - const terms = getSearchQueryTerms( - clauses, - Object.keys(matchData.metadata) - ) - - /* Highlight title and text and apply post-query boosts */ - const boost = +!parent + +Object.values(terms).every(t => t) - item.push({ - location, - title: highlight(title), - text: highlight(text), - ...tags && { tags: tags.map(highlight) }, - score: score * (1 + boost), - terms - }) - } - return item - }, []) - - /* Sort search results again after applying boosts */ - .sort((a, b) => b.score - a.score) - - /* Group search results by page */ - .reduce((items, result) => { - const document = this.documents.get(result.location) - if (typeof document !== "undefined") { - const ref = "parent" in document - ? document.parent!.location - : document.location - items.set(ref, [...items.get(ref) || [], result]) - } - return items - }, new Map<string, SearchResultItem>()) - - /* Generate search suggestions, if desired */ - let suggestions: string[] | undefined - if (this.options.suggestions) { - const titles = this.index.query(builder => { - for (const clause of clauses) - builder.term(clause.term, { - fields: ["title"], - presence: lunr.Query.presence.REQUIRED, - wildcard: lunr.Query.wildcard.TRAILING - }) - }) - - /* Retrieve suggestions for best match */ - suggestions = titles.length - ? Object.keys(titles[0].matchData.metadata) - : [] - } - - /* Return items and suggestions */ - return { - items: [...groups.values()], - ...typeof suggestions !== "undefined" && { suggestions } - } - - /* Log errors to console (for now) */ - } catch { - console.warn(`Invalid query: ${query} – see https://bit.ly/2s3ChXG`) - } - } - - /* Return nothing in case of error or empty query */ - return { items: [] } - } -} diff --git a/src/assets/javascripts/integrations/search/document/index.ts b/src/assets/javascripts/integrations/search/document/index.ts @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 escapeHTML from "escape-html" - -import { SearchIndexDocument } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search document - */ -export interface SearchDocument extends SearchIndexDocument { - parent?: SearchIndexDocument /* Parent article */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search document mapping - */ -export type SearchDocumentMap = Map<string, SearchDocument> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search document mapping - * - * @param docs - Search index documents - * - * @returns Search document map - */ -export function setupSearchDocumentMap( - docs: SearchIndexDocument[] -): SearchDocumentMap { - const documents = new Map<string, SearchDocument>() - const parents = new Set<SearchDocument>() - for (const doc of docs) { - const [path, hash] = doc.location.split("#") - - /* Extract location, title and tags */ - const location = doc.location - const title = doc.title - const tags = doc.tags - - /* Escape and cleanup text */ - const text = escapeHTML(doc.text) - .replace(/\s+(?=[,.:;!?])/g, "") - .replace(/\s+/g, " ") - - /* Handle section */ - if (hash) { - const parent = documents.get(path)! - - /* Ignore first section, override article */ - if (!parents.has(parent)) { - parent.title = doc.title - parent.text = text - - /* Remember that we processed the article */ - parents.add(parent) - - /* Add subsequent section */ - } else { - documents.set(location, { - location, - title, - text, - parent - }) - } - - /* Add article */ - } else { - documents.set(location, { - location, - title, - text, - ...tags && { tags } - }) - } - } - return documents -} diff --git a/src/assets/javascripts/integrations/search/highlighter/index.ts b/src/assets/javascripts/integrations/search/highlighter/index.ts @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 escapeHTML from "escape-html" - -import { SearchIndexConfig } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlight function - * - * @param value - Value - * - * @returns Highlighted value - */ -export type SearchHighlightFn = (value: string) => string - -/** - * Search highlight factory function - * - * @param query - Query value - * - * @returns Search highlight function - */ -export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search highlighter - * - * @param config - Search index configuration - * @param escape - Whether to escape HTML - * - * @returns Search highlight factory function - */ -export function setupSearchHighlighter( - config: SearchIndexConfig, escape: boolean -): SearchHighlightFactoryFn { - const separator = new RegExp(config.separator, "img") - const highlight = (_: unknown, data: string, term: string) => { - return `${data}<mark data-md-highlight>${term}</mark>` - } - - /* Return factory function */ - return (query: string) => { - query = query - .replace(/[\s*+\-:~^]+/g, " ") - .trim() - - /* Create search term match expression */ - const match = new RegExp(`(^|${config.separator})(${ - query - .replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&") - .replace(separator, "|") - })`, "img") - - /* Highlight string value */ - return value => ( - escape - ? escapeHTML(value) - : value - ) - .replace(match, highlight) - .replace(/<\/mark>(\s+)<mark[^>]*>/img, "$1") - } -} diff --git a/src/assets/javascripts/integrations/search/index.ts b/src/assets/javascripts/integrations/search/index.ts @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./document" -export * from "./highlighter" -export * from "./options" -export * from "./query" -export * from "./worker" diff --git a/src/assets/javascripts/integrations/search/options/index.ts b/src/assets/javascripts/integrations/search/options/index.ts @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search pipeline function - */ -export type SearchPipelineFn = - | "trimmer" /* Trimmer */ - | "stopWordFilter" /* Stop word filter */ - | "stemmer" /* Stemmer */ - -/** - * Search pipeline - */ -export type SearchPipeline = SearchPipelineFn[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search options - */ -export interface SearchOptions { - pipeline: SearchPipeline /* Search pipeline */ - suggestions: boolean /* Search suggestions */ -} diff --git a/src/assets/javascripts/integrations/search/query/_/.eslintrc b/src/assets/javascripts/integrations/search/query/_/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off" - } -} diff --git a/src/assets/javascripts/integrations/search/query/_/index.ts b/src/assets/javascripts/integrations/search/query/_/index.ts @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query clause - */ -export interface SearchQueryClause { - presence: lunr.Query.presence /* Clause presence */ - term: string /* Clause term */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search query terms - */ -export type SearchQueryTerms = Record<string, boolean> - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Parse a search query for analysis - * - * @param value - Query value - * - * @returns Search query clauses - */ -export function parseSearchQuery( - value: string -): SearchQueryClause[] { - const query = new (lunr as any).Query(["title", "text"]) - const parser = new (lunr as any).QueryParser(value, query) - - /* Parse and return query clauses */ - parser.parse() - return query.clauses -} - -/** - * Analyze the search query clauses in regard to the search terms found - * - * @param query - Search query clauses - * @param terms - Search terms - * - * @returns Search query terms - */ -export function getSearchQueryTerms( - query: SearchQueryClause[], terms: string[] -): SearchQueryTerms { - const clauses = new Set<SearchQueryClause>(query) - - /* Match query clauses against terms */ - const result: SearchQueryTerms = {} - for (let t = 0; t < terms.length; t++) - for (const clause of clauses) - if (terms[t].startsWith(clause.term)) { - result[clause.term] = true - clauses.delete(clause) - } - - /* Annotate unmatched non-stopword query clauses */ - for (const clause of clauses) - if (lunr.stopWordFilter?.(clause.term as any)) - result[clause.term] = false - - /* Return query terms */ - return result -} diff --git a/src/assets/javascripts/integrations/search/query/index.ts b/src/assets/javascripts/integrations/search/query/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./transform" diff --git a/src/assets/javascripts/integrations/search/query/transform/.eslintrc b/src/assets/javascripts/integrations/search/query/transform/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "no-control-regex": "off" - } -} diff --git a/src/assets/javascripts/integrations/search/query/transform/index.ts b/src/assets/javascripts/integrations/search/query/transform/index.ts @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search transformation function - * - * @param value - Query value - * - * @returns Transformed query value - */ -export type SearchTransformFn = (value: string) => string - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Default transformation function - * - * 1. Search for terms in quotation marks and prepend a `+` modifier to denote - * that the resulting document must contain all terms, converting the query - * to an `AND` query (as opposed to the default `OR` behavior). While users - * may expect terms enclosed in quotation marks to map to span queries, i.e. - * for which order is important, Lunr.js doesn't support them, so the best - * we can do is to convert the terms to an `AND` query. - * - * 2. Replace control characters which are not located at the beginning of the - * query or preceded by white space, or are not followed by a non-whitespace - * character or are at the end of the query string. Furthermore, filter - * unmatched quotation marks. - * - * 3. Trim excess whitespace from left and right. - * - * @param query - Query value - * - * @returns Transformed query value - */ -export function defaultTransform(query: string): string { - return query - .split(/"([^"]+)"/g) /* => 1 */ - .map((terms, index) => index & 1 - ? terms.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g, " +") - : terms - ) - .join("") - .replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g, "") /* => 2 */ - .trim() /* => 3 */ -} diff --git a/src/assets/javascripts/integrations/search/worker/_/index.ts b/src/assets/javascripts/integrations/search/worker/_/index.ts @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 RTICULAR 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 { - ObservableInput, - Subject, - from, - map, - share -} from "rxjs" - -import { configuration, feature, translation } from "~/_" -import { WorkerHandler, watchWorker } from "~/browser" - -import { SearchIndex } from "../../_" -import { - SearchOptions, - SearchPipeline -} from "../../options" -import { - SearchMessage, - SearchMessageType, - SearchSetupMessage, - isSearchResultMessage -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search worker - */ -export type SearchWorker = WorkerHandler<SearchMessage> - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search index - * - * @param data - Search index - * - * @returns Search index - */ -function setupSearchIndex({ config, docs }: SearchIndex): SearchIndex { - - /* Override default language with value from translation */ - if (config.lang.length === 1 && config.lang[0] === "en") - config.lang = [ - translation("search.config.lang") - ] - - /* Override default separator with value from translation */ - if (config.separator === "[\\s\\-]+") - config.separator = translation("search.config.separator") - - /* Set pipeline from translation */ - const pipeline = translation("search.config.pipeline") - .split(/\s*,\s*/) - .filter(Boolean) as SearchPipeline - - /* Determine search options */ - const options: SearchOptions = { - pipeline, - suggestions: feature("search.suggest") - } - - /* Return search index after defaulting */ - return { config, docs, options } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search worker - * - * This function creates a web worker to set up and query the search index, - * which is done using Lunr.js. The index must be passed as an observable to - * enable hacks like _localsearch_ via search index embedding as JSON. - * - * @param url - Worker URL - * @param index - Search index observable input - * - * @returns Search worker - */ -export function setupSearchWorker( - url: string, index: ObservableInput<SearchIndex> -): SearchWorker { - const config = configuration() - const worker = new Worker(url) - - /* Create communication channels and resolve relative links */ - const tx$ = new Subject<SearchMessage>() - const rx$ = watchWorker(worker, { tx$ }) - .pipe( - map(message => { - if (isSearchResultMessage(message)) { - for (const result of message.data.items) - for (const document of result) - document.location = `${new URL(document.location, config.base)}` - } - return message - }), - share() - ) - - /* Set up search index */ - from(index) - .pipe( - map(data => ({ - type: SearchMessageType.SETUP, - data: setupSearchIndex(data) - } as SearchSetupMessage)) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Return search worker */ - return { tx$, rx$ } -} diff --git a/src/assets/javascripts/integrations/search/worker/index.ts b/src/assets/javascripts/integrations/search/worker/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./message" diff --git a/src/assets/javascripts/integrations/search/worker/main/.eslintrc b/src/assets/javascripts/integrations/search/worker/main/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-misused-promises": "off" - } -} diff --git a/src/assets/javascripts/integrations/search/worker/main/index.ts b/src/assets/javascripts/integrations/search/worker/main/index.ts @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 RTICULAR 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 lunr from "lunr" - -import "~/polyfills" - -import { Search, SearchIndexConfig } from "../../_" -import { - SearchMessage, - SearchMessageType -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Add support for usage with `iframe-worker` polyfill - * - * While `importScripts` is synchronous when executed inside of a web worker, - * it's not possible to provide a synchronous polyfilled implementation. The - * cool thing is that awaiting a non-Promise is a noop, so extending the type - * definition to return a `Promise` shouldn't break anything. - * - * @see https://bit.ly/2PjDnXi - GitHub comment - */ -declare global { - function importScripts(...urls: string[]): Promise<void> | void -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -let index: Search - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch (= import) multi-language support through `lunr-languages` - * - * This function automatically imports the stemmers necessary to process the - * languages, which are defined through the search index configuration. - * - * If the worker runs inside of an `iframe` (when using `iframe-worker` as - * a shim), the base URL for the stemmers to be loaded must be determined by - * searching for the first `script` element with a `src` attribute, which will - * contain the contents of this script. - * - * @param config - Search index configuration - * - * @returns Promise resolving with no result - */ -async function setupSearchLanguages( - config: SearchIndexConfig -): Promise<void> { - let base = "../lunr" - - /* Detect `iframe-worker` and fix base URL */ - if (typeof parent !== "undefined" && "IFrameWorker" in parent) { - const worker = document.querySelector<HTMLScriptElement>("script[src]")! - const [path] = worker.src.split("/worker") - - /* Prefix base with path */ - base = base.replace("..", path) - } - - /* Add scripts for languages */ - const scripts = [] - for (const lang of config.lang) { - switch (lang) { - - /* Add segmenter for Japanese */ - case "ja": - scripts.push(`${base}/tinyseg.js`) - break - - /* Add segmenter for Hindi and Thai */ - case "hi": - case "th": - scripts.push(`${base}/wordcut.js`) - break - } - - /* Add language support */ - if (lang !== "en") - scripts.push(`${base}/min/lunr.${lang}.min.js`) - } - - /* Add multi-language support */ - if (config.lang.length > 1) - scripts.push(`${base}/min/lunr.multi.min.js`) - - /* Load scripts synchronously */ - if (scripts.length) - await importScripts( - `${base}/min/lunr.stemmer.support.min.js`, - ...scripts - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Message handler - * - * @param message - Source message - * - * @returns Target message - */ -export async function handler( - message: SearchMessage -): Promise<SearchMessage> { - switch (message.type) { - - /* Search setup message */ - case SearchMessageType.SETUP: - await setupSearchLanguages(message.data.config) - index = new Search(message.data) - return { - type: SearchMessageType.READY - } - - /* Search query message */ - case SearchMessageType.QUERY: - return { - type: SearchMessageType.RESULT, - data: index ? index.search(message.data) : { items: [] } - } - - /* All other messages */ - default: - throw new TypeError("Invalid message type") - } -} - -/* ---------------------------------------------------------------------------- - * Worker - * ------------------------------------------------------------------------- */ - -/* @ts-expect-error - expose Lunr.js in global scope, or stemmers won't work */ -self.lunr = lunr - -/* Handle messages */ -addEventListener("message", async ev => { - postMessage(await handler(ev.data)) -}) diff --git a/src/assets/javascripts/integrations/search/worker/message/index.ts b/src/assets/javascripts/integrations/search/worker/message/index.ts @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 RTICULAR 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 { SearchIndex, SearchResult } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search message type - */ -export const enum SearchMessageType { - SETUP, /* Search index setup */ - READY, /* Search index ready */ - QUERY, /* Search query */ - RESULT /* Search results */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message containing the data necessary to setup the search index - */ -export interface SearchSetupMessage { - type: SearchMessageType.SETUP /* Message type */ - data: SearchIndex /* Message data */ -} - -/** - * Message indicating the search index is ready - */ -export interface SearchReadyMessage { - type: SearchMessageType.READY /* Message type */ -} - -/** - * Message containing a search query - */ -export interface SearchQueryMessage { - type: SearchMessageType.QUERY /* Message type */ - data: string /* Message data */ -} - -/** - * Message containing results for a search query - */ -export interface SearchResultMessage { - type: SearchMessageType.RESULT /* Message type */ - data: SearchResult /* Message data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message exchanged with the search worker - */ -export type SearchMessage = - | SearchSetupMessage - | SearchReadyMessage - | SearchQueryMessage - | SearchResultMessage - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Type guard for search setup messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchSetupMessage( - message: SearchMessage -): message is SearchSetupMessage { - return message.type === SearchMessageType.SETUP -} - -/** - * Type guard for search ready messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchReadyMessage( - message: SearchMessage -): message is SearchReadyMessage { - return message.type === SearchMessageType.READY -} - -/** - * Type guard for search query messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchQueryMessage( - message: SearchMessage -): message is SearchQueryMessage { - return message.type === SearchMessageType.QUERY -} - -/** - * Type guard for search result messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchResultMessage( - message: SearchMessage -): message is SearchResultMessage { - return message.type === SearchMessageType.RESULT -} diff --git a/src/assets/javascripts/integrations/sitemap/index.ts b/src/assets/javascripts/integrations/sitemap/index.ts @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Observable, - catchError, - defaultIfEmpty, - map, - of, - tap -} from "rxjs" - -import { configuration } from "~/_" -import { getElements, requestXML } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sitemap, i.e. a list of URLs - */ -export type Sitemap = string[] - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Preprocess a list of URLs - * - * This function replaces the `site_url` in the sitemap with the actual base - * URL, to allow instant loading to work in occasions like Netlify previews. - * - * @param urls - URLs - * - * @returns URL path parts - */ -function preprocess(urls: Sitemap): Sitemap { - if (urls.length < 2) - return [""] - - /* Take the first two URLs and remove everything after the last slash */ - const [root, next] = [...urls] - .sort((a, b) => a.length - b.length) - .map(url => url.replace(/[^/]+$/, "")) - - /* Compute common prefix */ - let index = 0 - if (root === next) - index = root.length - else - while (root.charCodeAt(index) === next.charCodeAt(index)) - index++ - - /* Remove common prefix and return in original order */ - return urls.map(url => url.replace(root.slice(0, index), "")) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch the sitemap for the given base URL - * - * @param base - Base URL - * - * @returns Sitemap observable - */ -export function fetchSitemap(base?: URL): Observable<Sitemap> { - const cached = __md_get<Sitemap>("__sitemap", sessionStorage, base) - if (cached) { - return of(cached) - } else { - const config = configuration() - return requestXML(new URL("sitemap.xml", base || config.base)) - .pipe( - map(sitemap => preprocess(getElements("loc", sitemap) - .map(node => node.textContent!) - )), - catchError(() => EMPTY), // @todo refactor instant loading - defaultIfEmpty([]), - tap(sitemap => __md_set("__sitemap", sitemap, sessionStorage, base)) - ) - } -} diff --git a/src/assets/javascripts/integrations/version/.eslintrc b/src/assets/javascripts/integrations/version/.eslintrc @@ -1,5 +0,0 @@ -{ - "rules": { - "no-null/no-null": "off" - } -} diff --git a/src/assets/javascripts/integrations/version/index.ts b/src/assets/javascripts/integrations/version/index.ts @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - EMPTY, - Subject, - catchError, - combineLatest, - filter, - fromEvent, - map, - of, - switchMap, - withLatestFrom -} from "rxjs" - -import { configuration } from "~/_" -import { - getElement, - getLocation, - requestJSON, - setLocation -} from "~/browser" -import { getComponentElements } from "~/components" -import { - Version, - renderVersionSelector -} from "~/templates" - -import { fetchSitemap } from "../sitemap" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - document$: Subject<Document> /* Document subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up version selector - * - * @param options - Options - */ -export function setupVersionSelector( - { document$ }: SetupOptions -): void { - const config = configuration() - const versions$ = requestJSON<Version[]>( - new URL("../versions.json", config.base) - ) - .pipe( - catchError(() => EMPTY) // @todo refactor instant loading - ) - - /* Determine current version */ - const current$ = versions$ - .pipe( - map(versions => { - const [, current] = config.base.match(/([^/]+)\/?$/)! - return versions.find(({ version, aliases }) => ( - version === current || aliases.includes(current) - )) || versions[0] - }) - ) - - /* Intercept inter-version navigation */ - versions$ - .pipe( - map(versions => new Map(versions.map(version => [ - `${new URL(`../${version.version}/`, config.base)}`, - version - ]))), - switchMap(urls => fromEvent<MouseEvent>(document.body, "click") - .pipe( - filter(ev => !ev.metaKey && !ev.ctrlKey), - withLatestFrom(current$), - switchMap(([ev, current]) => { - if (ev.target instanceof Element) { - const el = ev.target.closest("a") - if (el && !el.target && urls.has(el.href)) { - const url = el.href - // This is a temporary hack to detect if a version inside the - // version selector or on another part of the site was clicked. - // If we're inside the version selector, we definitely want to - // find the same page, as we might have different deployments - // due to aliases. However, if we're outside the version - // selector, we must abort here, because we might otherwise - // interfere with instant loading. We need to refactor this - // at some point together with instant loading. - // - // See https://github.com/squidfunk/mkdocs-material/issues/4012 - if (!ev.target.closest(".md-version")) { - const version = urls.get(url)! - if (version === current) - return EMPTY - } - ev.preventDefault() - return of(url) - } - } - return EMPTY - }), - switchMap(url => { - const { version } = urls.get(url)! - return fetchSitemap(new URL(url)) - .pipe( - map(sitemap => { - const location = getLocation() - const path = location.href.replace(config.base, "") - return sitemap.includes(path) - ? new URL(`../${version}/${path}`, config.base) - : new URL(url) - }) - ) - }) - ) - ) - ) - .subscribe(url => setLocation(url)) - - /* Render version selector and warning */ - combineLatest([versions$, current$]) - .subscribe(([versions, current]) => { - const topic = getElement(".md-header__topic") - topic.appendChild(renderVersionSelector(versions, current)) - }) - - /* Integrate outdated version banner with instant loading */ - document$.pipe(switchMap(() => current$)) - .subscribe(current => { - - /* Check if version state was already determined */ - let outdated = __md_get("__outdated", sessionStorage) - if (outdated === null) { - const latest = config.version?.default || "latest" - outdated = !current.aliases.includes(latest) - - /* Persist version state in session storage */ - __md_set("__outdated", outdated, sessionStorage) - } - - /* Unhide outdated version banner */ - if (outdated) - for (const warning of getComponentElements("outdated")) - warning.hidden = false - }) -} diff --git a/src/assets/javascripts/patches/indeterminate/index.ts b/src/assets/javascripts/patches/indeterminate/index.ts @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - fromEvent, - map, - mergeMap, - switchMap, - takeWhile, - tap, - withLatestFrom -} from "rxjs" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable<Document> /* Document observable */ - tablet$: Observable<boolean> /* Media tablet observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch indeterminate checkboxes - * - * This function replaces the indeterminate "pseudo state" with the actual - * indeterminate state, which is used to keep navigation always expanded. - * - * @param options - Options - */ -export function patchIndeterminate( - { document$, tablet$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => getElements<HTMLInputElement>( - // @todo `data-md-state` is deprecated and removed in v9 - ".md-toggle--indeterminate, [data-md-state=indeterminate]" - )), - tap(el => { - el.indeterminate = true - el.checked = false - }), - mergeMap(el => fromEvent(el, "change") - .pipe( - takeWhile(() => el.classList.contains("md-toggle--indeterminate")), - map(() => el) - ) - ), - withLatestFrom(tablet$) - ) - .subscribe(([el, tablet]) => { - el.classList.remove("md-toggle--indeterminate") - if (tablet) - el.checked = false - }) -} diff --git a/src/assets/javascripts/patches/index.ts b/src/assets/javascripts/patches/index.ts @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./indeterminate" -export * from "./scrollfix" -export * from "./scrolllock" diff --git a/src/assets/javascripts/patches/scrollfix/index.ts b/src/assets/javascripts/patches/scrollfix/index.ts @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - filter, - fromEvent, - map, - mergeMap, - switchMap, - tap -} from "rxjs" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable<Document> /* Document observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether the given device is an Apple device - * - * @returns Test result - */ -function isAppleDevice(): boolean { - return /(iPad|iPhone|iPod)/.test(navigator.userAgent) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch all elements with `data-md-scrollfix` attributes - * - * This is a year-old patch which ensures that overflow scrolling works at the - * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon - * the start of a touch event. - * - * @see https://bit.ly/2SCtAOO - Original source - * - * @param options - Options - */ -export function patchScrollfix( - { document$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => getElements("[data-md-scrollfix]")), - tap(el => el.removeAttribute("data-md-scrollfix")), - filter(isAppleDevice), - mergeMap(el => fromEvent(el, "touchstart") - .pipe( - map(() => el) - ) - ) - ) - .subscribe(el => { - const top = el.scrollTop - - /* We're at the top of the container */ - if (top === 0) { - el.scrollTop = 1 - - /* We're at the bottom of the container */ - } else if (top + el.offsetHeight === el.scrollHeight) { - el.scrollTop = top - 1 - } - }) -} diff --git a/src/assets/javascripts/patches/scrolllock/index.ts b/src/assets/javascripts/patches/scrolllock/index.ts @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - combineLatest, - delay, - map, - of, - switchMap, - withLatestFrom -} from "rxjs" - -import { - Viewport, - watchToggle -} from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - viewport$: Observable<Viewport> /* Viewport observable */ - tablet$: Observable<boolean> /* Media tablet observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch the document body to lock when search is open - * - * For mobile and tablet viewports, the search is rendered full screen, which - * leads to scroll leaking when at the top or bottom of the search result. This - * function locks the body when the search is in full screen mode, and restores - * the scroll position when leaving. - * - * @param options - Options - */ -export function patchScrolllock( - { viewport$, tablet$ }: PatchOptions -): void { - combineLatest([watchToggle("search"), tablet$]) - .pipe( - map(([active, tablet]) => active && !tablet), - switchMap(active => of(active) - .pipe( - delay(active ? 400 : 100) - ) - ), - withLatestFrom(viewport$) - ) - .subscribe(([active, { offset: { y }}]) => { - if (active) { - document.body.setAttribute("data-md-scrolllock", "") - document.body.style.top = `-${y}px` - } else { - const value = -1 * parseInt(document.body.style.top, 10) - document.body.removeAttribute("data-md-scrolllock") - document.body.style.top = "" - if (value) - window.scrollTo(0, value) - } - }) -} diff --git a/src/assets/javascripts/polyfills/index.ts b/src/assets/javascripts/polyfills/index.ts @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Polyfills - * ------------------------------------------------------------------------- */ - -/* Polyfill `Object.entries` */ -if (!Object.entries) - Object.entries = function (obj: object) { - const data: [string, string][] = [] - for (const key of Object.keys(obj)) - // @ts-expect-error - ignore property access warning - data.push([key, obj[key]]) - - /* Return entries */ - return data - } - -/* Polyfill `Object.values` */ -if (!Object.values) - Object.values = function (obj: object) { - const data: string[] = [] - for (const key of Object.keys(obj)) - // @ts-expect-error - ignore property access warning - data.push(obj[key]) - - /* Return values */ - return data - } - -/* ------------------------------------------------------------------------- */ - -/* Polyfills for `Element` */ -if (typeof Element !== "undefined") { - - /* Polyfill `Element.scrollTo` */ - if (!Element.prototype.scrollTo) - Element.prototype.scrollTo = function ( - x?: ScrollToOptions | number, y?: number - ): void { - if (typeof x === "object") { - this.scrollLeft = x.left! - this.scrollTop = x.top! - } else { - this.scrollLeft = x! - this.scrollTop = y! - } - } - - /* Polyfill `Element.replaceWith` */ - if (!Element.prototype.replaceWith) - Element.prototype.replaceWith = function ( - ...nodes: Array<string | Node> - ): void { - const parent = this.parentNode - if (parent) { - if (nodes.length === 0) - parent.removeChild(this) - - /* Replace children and create text nodes */ - for (let i = nodes.length - 1; i >= 0; i--) { - let node = nodes[i] - if (typeof node !== "object") - node = document.createTextNode(node) - else if (node.parentNode) - node.parentNode.removeChild(node) - - /* Replace child or insert before previous sibling */ - if (!i) - parent.replaceChild(node, this) - else - parent.insertBefore(this.previousSibling!, node) - } - } - } -} diff --git a/src/assets/javascripts/templates/annotation/index.tsx b/src/assets/javascripts/templates/annotation/index.tsx @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render an empty annotation - * - * @param id - Annotation identifier - * - * @returns Element - */ -export function renderAnnotation(id: number): HTMLElement { - return ( - <aside class="md-annotation" tabIndex={0}> - <div class="md-annotation__inner md-tooltip"> - <div class="md-tooltip__inner md-typeset"></div> - </div> - <span class="md-annotation__index"> - <span data-md-annotation-id={id}></span> - </span> - </aside> - ) -} diff --git a/src/assets/javascripts/templates/clipboard/index.tsx b/src/assets/javascripts/templates/clipboard/index.tsx @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a 'copy-to-clipboard' button - * - * @param id - Unique identifier - * - * @returns Element - */ -export function renderClipboardButton(id: string): HTMLElement { - return ( - <button - class="md-clipboard md-icon" - title={translation("clipboard.copy")} - data-clipboard-target={`#${id} > code`} - ></button> - ) -} diff --git a/src/assets/javascripts/templates/index.ts b/src/assets/javascripts/templates/index.ts @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./annotation" -export * from "./clipboard" -export * from "./search" -export * from "./source" -export * from "./tabbed" -export * from "./table" -export * from "./version" diff --git a/src/assets/javascripts/templates/search/index.tsx b/src/assets/javascripts/templates/search/index.tsx @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { ComponentChild } from "preact" - -import { feature, translation } from "~/_" -import { - SearchDocument, - SearchMetadata, - SearchResultItem -} from "~/integrations/search" -import { h, truncate } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Render flag - */ -const enum Flag { - TEASER = 1, /* Render teaser */ - PARENT = 2 /* Render as parent */ -} - -/* ---------------------------------------------------------------------------- - * Helper function - * ------------------------------------------------------------------------- */ - -/** - * Render a search document - * - * @param document - Search document - * @param flag - Render flags - * - * @returns Element - */ -function renderSearchDocument( - document: SearchDocument & SearchMetadata, flag: Flag -): HTMLElement { - const parent = flag & Flag.PARENT - const teaser = flag & Flag.TEASER - - /* Render missing query terms */ - const missing = Object.keys(document.terms) - .filter(key => !document.terms[key]) - .reduce<ComponentChild[]>((list, key) => [ - ...list, <del>{key}</del>, " " - ], []) - .slice(0, -1) - - /* Assemble query string for highlighting */ - const url = new URL(document.location) - if (feature("search.highlight")) - url.searchParams.set("h", Object.entries(document.terms) - .filter(([, match]) => match) - .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), "") - ) - - /* Render article or section, depending on flags */ - return ( - <a href={`${url}`} class="md-search-result__link" tabIndex={-1}> - <article - class={["md-search-result__article", ...parent - ? ["md-search-result__article--document"] - : [] - ].join(" ")} - data-md-score={document.score.toFixed(2)} - > - {parent > 0 && <div class="md-search-result__icon md-icon"></div>} - <h1 class="md-search-result__title">{document.title}</h1> - {teaser > 0 && document.text.length > 0 && - <p class="md-search-result__teaser"> - {truncate(document.text, 320)} - </p> - } - {document.tags && document.tags.map(tag => ( - <span class="md-tag">{tag}</span> - ))} - {teaser > 0 && missing.length > 0 && - <p class="md-search-result__terms"> - {translation("search.result.term.missing")}: {...missing} - </p> - } - </article> - </a> - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a search result - * - * @param result - Search result - * - * @returns Element - */ -export function renderSearchResultItem( - result: SearchResultItem -): HTMLElement { - const threshold = result[0].score - const docs = [...result] - - /* Find and extract parent article */ - const parent = docs.findIndex(doc => !doc.location.includes("#")) - const [article] = docs.splice(parent, 1) - - /* Determine last index above threshold */ - let index = docs.findIndex(doc => doc.score < threshold) - if (index === -1) - index = docs.length - - /* Partition sections */ - const best = docs.slice(0, index) - const more = docs.slice(index) - - /* Render children */ - const children = [ - renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)), - ...best.map(section => renderSearchDocument(section, Flag.TEASER)), - ...more.length ? [ - <details class="md-search-result__more"> - <summary tabIndex={-1}> - {more.length > 0 && more.length === 1 - ? translation("search.result.more.one") - : translation("search.result.more.other", more.length) - } - </summary> - {...more.map(section => renderSearchDocument(section, Flag.TEASER))} - </details> - ] : [] - ] - - /* Render search result */ - return ( - <li class="md-search-result__item"> - {children} - </li> - ) -} diff --git a/src/assets/javascripts/templates/source/index.tsx b/src/assets/javascripts/templates/source/index.tsx @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { SourceFacts } from "~/components" -import { h, round } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render repository facts - * - * @param facts - Repository facts - * - * @returns Element - */ -export function renderSourceFacts(facts: SourceFacts): HTMLElement { - return ( - <ul class="md-source__facts"> - {Object.entries(facts).map(([key, value]) => ( - <li class={`md-source__fact md-source__fact--${key}`}> - {typeof value === "number" ? round(value) : value} - </li> - ))} - </ul> - ) -} diff --git a/src/assets/javascripts/templates/tabbed/index.tsx b/src/assets/javascripts/templates/tabbed/index.tsx @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Tabbed control type - */ -type TabbedControlType = - | "prev" - | "next" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render control for content tabs - * - * @param type - Control type - * - * @returns Element - */ -export function renderTabbedControl( - type: TabbedControlType -): HTMLElement { - const classes = `tabbed-control tabbed-control--${type}` - return ( - <div class={classes} hidden> - <button class="tabbed-button" tabIndex={-1}></button> - </div> - ) -} diff --git a/src/assets/javascripts/templates/table/index.tsx b/src/assets/javascripts/templates/table/index.tsx @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a table inside a wrapper to improve scrolling on mobile - * - * @param table - Table element - * - * @returns Element - */ -export function renderTable(table: HTMLElement): HTMLElement { - return ( - <div class="md-typeset__scrollwrap"> - <div class="md-typeset__table"> - {table} - </div> - </div> - ) -} diff --git a/src/assets/javascripts/templates/version/index.tsx b/src/assets/javascripts/templates/version/index.tsx @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { configuration, translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Version - */ -export interface Version { - version: string /* Version identifier */ - title: string /* Version title */ - aliases: string[] /* Version aliases */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version - * - * @param version - Version - * - * @returns Element - */ -function renderVersion(version: Version): HTMLElement { - const config = configuration() - - /* Ensure trailing slash, see https://bit.ly/3rL5u3f */ - const url = new URL(`../${version.version}/`, config.base) - return ( - <li class="md-version__item"> - <a href={`${url}`} class="md-version__link"> - {version.title} - </a> - </li> - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version selector - * - * @param versions - Versions - * @param active - Active version - * - * @returns Element - */ -export function renderVersionSelector( - versions: Version[], active: Version -): HTMLElement { - return ( - <div class="md-version"> - <button - class="md-version__current" - aria-label={translation("select.version.title")} - > - {active.title} - </button> - <ul class="md-version__list"> - {versions.map(renderVersion)} - </ul> - </div> - ) -} diff --git a/src/assets/javascripts/utilities/h/.eslintrc b/src/assets/javascripts/utilities/h/.eslintrc @@ -1,7 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "jsdoc/require-jsdoc": "off" - } -} diff --git a/src/assets/javascripts/utilities/h/index.ts b/src/assets/javascripts/utilities/h/index.ts @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { JSX as JSXInternal } from "preact" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * HTML attributes - */ -type Attributes = - & JSXInternal.HTMLAttributes - & JSXInternal.SVGAttributes - & Record<string, any> - -/** - * Child element - */ -type Child = - | HTMLElement - | Text - | string - | number - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Append a child node to an element - * - * @param el - Element - * @param child - Child node(s) - */ -function appendChild(el: HTMLElement, child: Child | Child[]): void { - - /* Handle primitive types (including raw HTML) */ - if (typeof child === "string" || typeof child === "number") { - el.innerHTML += child.toString() - - /* Handle nodes */ - } else if (child instanceof Node) { - el.appendChild(child) - - /* Handle nested children */ - } else if (Array.isArray(child)) { - for (const node of child) - appendChild(el, node) - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * JSX factory - * - * @template T - Element type - * - * @param tag - HTML tag - * @param attributes - HTML attributes - * @param children - Child elements - * - * @returns Element - */ -export function h<T extends keyof HTMLElementTagNameMap>( - tag: T, attributes?: Attributes | null, ...children: Child[] -): HTMLElementTagNameMap[T] - -export function h<T extends h.JSX.Element>( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T - -export function h<T extends h.JSX.Element>( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T { - const el = document.createElement(tag) - - /* Set attributes, if any */ - if (attributes) - for (const attr of Object.keys(attributes)) { - if (typeof attributes[attr] === "undefined") - continue - - /* Set default attribute or boolean */ - if (typeof attributes[attr] !== "boolean") - el.setAttribute(attr, attributes[attr]) - else - el.setAttribute(attr, "") - } - - /* Append child nodes */ - for (const child of children) - appendChild(el, child) - - /* Return element */ - return el as T -} - -/* ---------------------------------------------------------------------------- - * Namespace - * ------------------------------------------------------------------------- */ - -export declare namespace h { - namespace JSX { - type Element = HTMLElement - type IntrinsicElements = JSXInternal.IntrinsicElements - } -} diff --git a/src/assets/javascripts/utilities/index.ts b/src/assets/javascripts/utilities/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./h" -export * from "./string" diff --git a/src/assets/javascripts/utilities/string/index.ts b/src/assets/javascripts/utilities/string/index.ts @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Truncate a string after the given number of characters - * - * This is not a very reasonable approach, since the summaries kind of suck. - * It would be better to create something more intelligent, highlighting the - * search occurrences and making a better summary out of it, but this note was - * written three years ago, so who knows if we'll ever fix it. - * - * @param value - Value to be truncated - * @param n - Number of characters - * - * @returns Truncated value - */ -export function truncate(value: string, n: number): string { - let i = n - if (value.length > i) { - while (value[i] !== " " && --i > 0) { /* keep eating */ } - return `${value.substring(0, i)}...` - } - return value -} - -/** - * Round a number for display with repository facts - * - * This is a reverse-engineered version of GitHub's weird rounding algorithm - * for stars, forks and all other numbers. While all numbers below `1,000` are - * returned as-is, bigger numbers are converted to fixed numbers: - * - * - `1,049` => `1k` - * - `1,050` => `1.1k` - * - `1,949` => `1.9k` - * - `1,950` => `2k` - * - * @param value - Original value - * - * @returns Rounded value - */ -export function round(value: number): string { - if (value > 999) { - const digits = +((value - 950) % 1000 > 99) - return `${((value + 0.000001) / 1000).toFixed(digits)}k` - } else { - return value.toString() - } -} diff --git a/src/assets/javascripts/workers/search.ts b/src/assets/javascripts/workers/search.ts @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 RTICULAR 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 "~/integrations/search/worker/main" diff --git a/src/assets/stylesheets/_config.scss b/src/assets/stylesheets/_config.scss @@ -1,42 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Variables: breakpoints -// ---------------------------------------------------------------------------- - -// Device-specific breakpoints -$break-devices: ( - mobile: ( - portrait: px2em(220px) px2em(479px), - landscape: px2em(480px) px2em(719px) - ), - tablet: ( - portrait: px2em(720px) px2em(959px), - landscape: px2em(960px) px2em(1219px) - ), - screen: ( - small: px2em(1220px) px2em(1599px), - medium: px2em(1600px) px2em(1999px), - large: px2em(2000px) - ) -); diff --git a/src/assets/stylesheets/main.scss b/src/assets/stylesheets/main.scss @@ -1,80 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/resets"; -@import "main/colors"; -@import "main/icons"; -@import "main/typeset"; - -@import "main/layout/banner"; -@import "main/layout/base"; -@import "main/layout/clipboard"; -@import "main/layout/consent"; -@import "main/layout/content"; -@import "main/layout/dialog"; -@import "main/layout/feedback"; -@import "main/layout/footer"; -@import "main/layout/form"; -@import "main/layout/header"; -@import "main/layout/nav"; -@import "main/layout/search"; -@import "main/layout/select"; -@import "main/layout/sidebar"; -@import "main/layout/source"; -@import "main/layout/tabs"; -@import "main/layout/tag"; -@import "main/layout/tooltip"; -@import "main/layout/top"; -@import "main/layout/version"; - -@import "main/extensions/markdown/admonition"; -@import "main/extensions/markdown/footnotes"; -@import "main/extensions/markdown/toc"; - -@import "main/extensions/pymdownx/arithmatex"; -@import "main/extensions/pymdownx/critic"; -@import "main/extensions/pymdownx/details"; -@import "main/extensions/pymdownx/emoji"; -@import "main/extensions/pymdownx/highlight"; -@import "main/extensions/pymdownx/keys"; -@import "main/extensions/pymdownx/tabbed"; -@import "main/extensions/pymdownx/tasklist"; - -@import "main/integrations/mermaid"; - -@import "main/modifiers"; diff --git a/src/assets/stylesheets/main/_colors.scss b/src/assets/stylesheets/main/_colors.scss @@ -1,134 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Color variables -:root { - @extend %root; -} - -// ---------------------------------------------------------------------------- - -// Allow to explicitly use color schemes in nested content -[data-md-color-scheme="default"] { - @extend %root; -} - -// ---------------------------------------------------------------------------- -// Placeholders -// ---------------------------------------------------------------------------- - -// Default theme, i.e. light mode -%root { - - // Default color shades - --md-default-fg-color: hsla(0, 0%, 0%, 0.87); - --md-default-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32); - --md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07); - --md-default-bg-color: hsla(0, 0%, 100%, 1); - --md-default-bg-color--light: hsla(0, 0%, 100%, 0.7); - --md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12); - - // Primary color shades - --md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - --md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1); - --md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Accent color shades - --md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1); - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Code color shades - --md-code-fg-color: hsla(200, 18%, 26%, 1); - --md-code-bg-color: hsla(0, 0%, 96%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - --md-code-hl-number-color: hsla(0, 67%, 50%, 1); - --md-code-hl-special-color: hsla(340, 83%, 47%, 1); - --md-code-hl-function-color: hsla(291, 45%, 50%, 1); - --md-code-hl-constant-color: hsla(250, 63%, 60%, 1); - --md-code-hl-keyword-color: hsla(219, 54%, 51%, 1); - --md-code-hl-string-color: hsla(150, 63%, 30%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - - // Typeset `del` and `ins` color shades - --md-typeset-del-color: hsla(6, 90%, 60%, 0.15); - --md-typeset-ins-color: hsla(150, 90%, 44%, 0.15); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(0, 0%, 98%, 1); - --md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1); - --md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(0, 0%, 0%, 0.12); - - // Admonition color shades - --md-admonition-fg-color: var(--md-default-fg-color); - --md-admonition-bg-color: var(--md-default-bg-color); - - // Footer color shades - --md-footer-fg-color: hsla(0, 0%, 100%, 1); - --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-footer-bg-color: hsla(0, 0%, 0%, 0.87); - --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32); - - // Shadow depth 1 - --md-shadow-z1: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.05), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.1); - - // Shadow depth 2 - --md-shadow-z2: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.1), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.25); - - // Shadow depth 3 - --md-shadow-z3: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.2), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.35); -} diff --git a/src/assets/stylesheets/main/_icons.scss b/src/assets/stylesheets/main/_icons.scss @@ -1,37 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon -.md-icon { - - // SVG defaults - svg { - display: block; - width: px2rem(24px); - height: px2rem(24px); - fill: currentcolor; - } -} diff --git a/src/assets/stylesheets/main/_modifiers.scss b/src/assets/stylesheets/main/_modifiers.scss @@ -1,58 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // [tablet +]: Allow for rendering content as sidebars - @include break-from-device(tablet) { - - // Modifier to float block elements - .inline { - float: left; - width: px2rem(234px); - margin-top: 0; - margin-inline-end: px2rem(16px); - margin-bottom: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: right; - } - - // Modifier to move to end (ltr: right, rtl: left) - &.end { - float: right; - margin-inline: px2rem(16px) 0; - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - } - } - } -} diff --git a/src/assets/stylesheets/main/_resets.scss b/src/assets/stylesheets/main/_resets.scss @@ -1,118 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Enforce correct box model and prevent adjustments of font size after -// orientation changes in IE and iOS -html { - box-sizing: border-box; - text-size-adjust: none; -} - -// All elements shall inherit the document default -*, -*::before, -*::after { - box-sizing: inherit; - - // [reduced motion]: Disable all transitions - @media (prefers-reduced-motion) { - transition: none !important; // stylelint-disable-line - } -} - -// Remove margin in all browsers -body { - margin: 0; -} - -// Reset tap outlines on iOS and Android -a, -button, -label, -input { - -webkit-tap-highlight-color: transparent; -} - -// Reset link styles -a { - color: inherit; - text-decoration: none; -} - -// Normalize horizontal separator styles -hr { - display: block; - box-sizing: content-box; - height: px2rem(1px); - padding: 0; - overflow: visible; - border: 0; -} - -// Normalize font-size in all browsers -small { - font-size: 80%; -} - -// Prevent subscript and superscript from affecting line-height -sub, -sup { - line-height: 1em; -} - -// Remove border on image -img { - border-style: none; -} - -// Reset table styles -table { - border-collapse: separate; - border-spacing: 0; -} - -// Reset table cell styles -td, -th { - font-weight: 400; - vertical-align: top; -} - -// Reset button styles -button { - margin: 0; - padding: 0; - font-size: inherit; - font-family: inherit; - background: transparent; - border: 0; -} - -// Reset input styles -input { - border: 0; - outline: none; -} diff --git a/src/assets/stylesheets/main/_typeset.scss b/src/assets/stylesheets/main/_typeset.scss @@ -1,619 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules: font definitions -// ---------------------------------------------------------------------------- - -// Enable font-smoothing in Webkit and FF -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - // Font with fallback for body copy - --md-text-font-family: - var(--md-text-font, _), - -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; - - // Font with fallback for code - --md-code-font-family: - var(--md-code-font, _), - SFMono-Regular, Consolas, Menlo, monospace; -} - -// Define default fonts -body, -input { - color: var(--md-typeset-color); - font-feature-settings: "kern", "liga"; - font-family: var(--md-text-font-family); -} - -// Define monospaced fonts -code, -pre, -kbd { - color: var(--md-typeset-color); - font-feature-settings: "kern"; - font-family: var(--md-code-font-family); -} - -// ---------------------------------------------------------------------------- -// Rules: typesetted content -// ---------------------------------------------------------------------------- - -// General variables -:root { - --md-typeset-table-sort-icon: svg-load("material/sort.svg"); - --md-typeset-table-sort-icon--asc: svg-load("material/sort-ascending.svg"); - --md-typeset-table-sort-icon--desc: svg-load("material/sort-descending.svg"); -} - -// ---------------------------------------------------------------------------- - -// Content that is typeset - if possible, all margins, paddings and font sizes -// should be set in ems, so nested blocks (e.g. admonitions) render correctly. -.md-typeset { - font-size: px2rem(16px); - line-height: 1.6; - color-adjust: exact; - - // [print]: We'll use a smaller `font-size` for printing, so code examples - // don't break too early, and `16px` looks too big anyway. - @media print { - font-size: px2rem(13.6px); - } - - // Default spacing - ul, - ol, - dl, - figure, - blockquote, - pre { - margin-block: 1em; - } - - // Headline on level 1 - h1 { - margin: 0 0 px2em(40px, 32px); - color: var(--md-default-fg-color--light); - font-weight: 300; - font-size: px2em(32px); - line-height: 1.3; - letter-spacing: -0.01em; - } - - // Headline on level 2 - h2 { - margin: px2em(40px, 25px) 0 px2em(16px, 25px); - font-weight: 300; - font-size: px2em(25px); - line-height: 1.4; - letter-spacing: -0.01em; - } - - // Headline on level 3 - h3 { - margin: px2em(32px, 20px) 0 px2em(16px, 20px); - font-weight: 400; - font-size: px2em(20px); - line-height: 1.5; - letter-spacing: -0.01em; - } - - // Headline on level 3 following level 2 - h2 + h3 { - margin-top: px2em(16px, 20px); - } - - // Headline on level 4 - h4 { - margin: px2em(16px) 0; - font-weight: 700; - letter-spacing: -0.01em; - } - - // Headline on level 5-6 - h5, - h6 { - margin: px2em(16px, 12.8px) 0; - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2em(12.8px); - letter-spacing: -0.01em; - } - - // Headline on level 5 - h5 { - text-transform: uppercase; - } - - // Horizontal separator - hr { - display: flow-root; - margin: 1.5em 0; - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - } - - // Text link - a { - color: var(--md-typeset-a-color); - word-break: break-word; - - // Also enable color transition on pseudo elements - &, - &::before { - transition: color 125ms; - } - - // Text link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - - // Inline code block - code { - background-color: var(--md-accent-fg-color--transparent); - } - } - - // Inline code block - code { - color: currentcolor; - transition: background-color 125ms; - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - } - - // Code block - code, - pre, - kbd { - color: var(--md-code-fg-color); - direction: ltr; - - // [print]: Wrap text and hide scollbars - @media print { - white-space: pre-wrap; - } - } - - // Inline code block - code { - padding: 0 px2em(4px, 13.6px); - font-size: px2em(13.6px); - word-break: break-word; - background-color: var(--md-code-bg-color); - border-radius: px2rem(2px); - box-decoration-break: clone; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - } - - // Unformatted content - pre { - position: relative; - display: flow-root; - line-height: 1.4; - - // Code block - > code { - display: block; - margin: 0; - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - overflow: auto; - word-break: normal; - outline-color: var(--md-accent-fg-color); - box-shadow: none; - box-decoration-break: slice; - touch-action: auto; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Code block on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } - - // Keyboard key - kbd { - display: inline-block; - padding: 0 px2em(8px, 12px); - color: var(--md-default-fg-color); - font-size: px2em(12px); - vertical-align: text-top; - word-break: break-word; - background-color: var(--md-typeset-kbd-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(2px) 0 px2rem(1px) var(--md-typeset-kbd-border-color), - 0 px2rem(2px) 0 var(--md-typeset-kbd-border-color), - 0 px2rem(-2px) px2rem(4px) var(--md-typeset-kbd-accent-color) inset; - } - - // Text highlighting marker - mark { - color: inherit; - word-break: break-word; - background-color: var(--md-typeset-mark-color); - box-decoration-break: clone; - } - - // Abbreviation - abbr { - text-decoration: none; - border-bottom: px2rem(1px) dotted var(--md-default-fg-color--light); - cursor: help; - - // Show tooltip for touch devices - @media (hover: none) { - position: relative; - - // Tooltip - &[title]:is(:focus, :hover)::after { - position: absolute; - inset-inline-start: 0; - display: inline-block; - width: auto; - min-width: max-content; - max-width: 80%; - margin-top: 2em; - padding: px2rem(4px) px2rem(6px); - color: var(--md-default-bg-color); - font-size: px2rem(14px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z3); - content: attr(title); - } - } - } - - // Small text - small { - opacity: 0.75; - } - - // Superscript and subscript - sup, - sub { - margin-inline-start: px2em(1px, 12.8px); - } - - // Blockquotes, possibly nested - blockquote { - padding-inline-start: px2rem(12px); - margin-inline: 0; - color: var(--md-default-fg-color--light); - border-inline-start: px2rem(4px) solid var(--md-default-fg-color--lighter); - } - - // Unordered list - ul { - list-style-type: disc; - } - - // Unordered and ordered list - ul, - ol { - margin-inline-start: px2em(10px); - padding: 0; - - // Adjust display mode if not hidden - &:not([hidden]) { - display: flow-root; - } - - // Nested ordered list - ol { - list-style-type: lower-alpha; - - // Triply nested ordered list - ol { - list-style-type: lower-roman; - } - } - - // List element - li { - margin-bottom: 0.5em; - margin-inline-start: px2em(20px); - - // Adjust spacing - p, - blockquote { - margin: 0.5em 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Nested list - :is(ul, ol) { - margin-block: 0.5em; - margin-inline-start: px2em(10px); - } - } - } - - // Definition list - dd { - margin-block: 1em 1.5em; - margin-inline-start: px2em(30px); - } - - // Image or video - img, - svg, - video { - max-width: 100%; - height: auto; - } - - // Image - img { - - // Adjust spacing when left-aligned - &[align="left"] { - margin: 1em; - margin-left: 0; - } - - // Adjust spacing when right-aligned - &[align="right"] { - margin: 1em; - margin-right: 0; - } - - // Adjust spacing when sole children - &[align]:only-child { - margin-top: 0; - } - - // Hide images for dark mode - &[src$="#only-dark"], - &[src$="#gh-dark-mode-only"] { - display: none; - } - } - - // Figure - figure { - display: flow-root; - width: fit-content; - max-width: 100%; - margin: 1em auto; - text-align: center; - - // Figure images - img { - display: block; - } - } - - // Figure caption - figcaption { - max-width: px2rem(480px); - margin: 1em auto; - font-style: italic; - } - - // Limit width to container - iframe { - max-width: 100%; - } - - // Data table - table:not([class]) { - display: inline-block; - max-width: 100%; - overflow: auto; - font-size: px2rem(12.8px); - background-color: var(--md-default-bg-color); - border: px2rem(1px) solid var(--md-typeset-table-color); - border-radius: px2rem(2px); - touch-action: auto; - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: table; - } - - // Due to margin collapse because of the necessary inline-block hack, we - // cannot increase the bottom margin on the table, so we just increase the - // top margin on the following element - + * { - margin-top: 1.5em; - } - - // Elements in table heading and cell - :is(th, td) > * { - - // Adjust spacing on first child - &:first-child { - margin-top: 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - } - - // Table heading and cell - :is(th, td):not([align]) { - text-align: left; - - // Adjust for right-to-left languages - [dir="rtl"] & { - text-align: right; - } - } - - // Table heading - th { - min-width: px2rem(100px); - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - font-weight: 700; - vertical-align: top; - - // Links in table headings - a { - color: inherit; - } - } - - // Table cell - td { - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - vertical-align: top; - border-top: px2rem(1px) solid var(--md-typeset-table-color); - } - - // Table body row - tbody tr { - transition: background-color 125ms; - - // Table row on hover - &:hover { - background-color: rgba(0, 0, 0, 0.035); - box-shadow: 0 px2rem(1px) 0 var(--md-default-bg-color) inset; - } - } - - // Text link in table - a { - word-break: normal; - } - } - - // Sortable table - table th[role="columnheader"] { - cursor: pointer; - - // Sort icon - &::after { - display: inline-block; - width: 1.2em; - height: 1.2em; - margin-inline-start: 0.5em; - vertical-align: text-bottom; - mask-image: var(--md-typeset-table-sort-icon); - mask-repeat: no-repeat; - mask-size: contain; - transition: background-color 125ms; - content: ""; - } - - // Show sort icon on hover - &:hover::after { - background-color: var(--md-default-fg-color--lighter); - } - - // Sort ascending icon - &[aria-sort="ascending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--asc); - } - - // Sort descending icon - &[aria-sort="descending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--desc); - } - } - - // Data table scroll wrapper - &__scrollwrap { - margin: 1em px2rem(-16px); - overflow-x: auto; - touch-action: auto; - } - - // Data table wrapper - &__table { - display: inline-block; - margin-bottom: 0.5em; - padding: 0 px2rem(16px); - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: block; - } - - // Data table - html & table { - display: table; - width: 100%; - margin: 0; - overflow: hidden; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: top-level -// ---------------------------------------------------------------------------- - -// [mobile -]: Align with body copy -@include break-to-device(mobile) { - - // Top-level unformatted content - .md-content__inner > pre { - margin: 1em px2rem(-16px); - - // Code block - code { - border-radius: 0; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/markdown/_admonition.scss b/src/assets/stylesheets/main/extensions/markdown/_admonition.scss @@ -1,183 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -@use "sass:color"; -@use "sass:list"; - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// Admonition flavours -$admonitions: ( - note: pencil $clr-blue-a200, - abstract summary tldr: clipboard-text $clr-light-blue-a400, - info todo: information $clr-cyan-a700, - tip hint important: fire $clr-teal-a700, - success check done: check-bold $clr-green-a700, - question help faq: help-circle $clr-light-green-a700, - warning caution attention: alert $clr-orange-a400, - failure fail missing: close-thick $clr-red-a200, - danger error: lightning-bolt $clr-red-a400, - bug: bug $clr-pink-a400, - example: format-list-numbered $clr-deep-purple-a200, - quote cite: format-quote-close $clr-grey -) !default; - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Admonition variables -:root { - @each $names, $props in $admonitions { - --md-admonition-icon--#{nth($names, 1)}: - svg-load("material/#{nth($props, 1)}.svg"); - } -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Admonition - note that all styles also apply to details tags, which are - // rendered as collapsible admonitions with summary elements as titles. - :is(.admonition, details) { - display: flow-root; - margin: px2em(20px, 12.8px) 0; - padding: 0 px2rem(12px); - color: var(--md-admonition-fg-color); - font-size: px2rem(12.8px); - page-break-inside: avoid; - background-color: var(--md-admonition-bg-color); - border: 0 solid $clr-blue-a200; - border-inline-start-width: px2rem(4px); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z1); - - // [print]: Omit shadow as it may lead to rendering errors - @media print { - box-shadow: none; - } - - // Hack: Chrome exhibits a weird issue where it will set nested elements to - // content-box. Doesn't happen in other browsers, so looks like a bug. - > * { - box-sizing: border-box; - } - - // Adjust vertical spacing for nested admonitions - :is(.admonition, details) { - margin-top: 1em; - margin-bottom: 1em; - } - - // Adjust spacing for contained table wrappers - .md-typeset__scrollwrap { - margin: 1em px2rem(-12px); - } - - // Adjust spacing for contained tables - .md-typeset__table { - padding: 0 px2rem(12px); - } - - // Adjust spacing for single-child tabbed block container - > .tabbed-set:only-child { - margin-top: 0; - } - - // Adjust spacing on last child - html & > :last-child { - margin-bottom: px2rem(12px); - } - } - - // Admonition title - :is(.admonition-title, summary) { - position: relative; - margin-block: 0; - margin-inline: px2rem(-16px) px2rem(-12px); - padding-block: px2rem(8px); - padding-inline: px2rem(44px) px2rem(12px); - font-weight: 700; - background-color: color.adjust($clr-blue-a200, $alpha: -0.9); - border: none; - border-inline-start-width: px2rem(4px); - border-start-start-radius: px2rem(2px); - border-start-end-radius: px2rem(2px); - - // Adjust spacing for title-only admonitions - html &:last-child { - margin-bottom: 0; - } - - // Admonition icon - &::before { - position: absolute; - top: px2em(10px); - inset-inline-start: px2rem(16px); - width: px2rem(20px); - height: px2rem(20px); - background-color: $clr-blue-a200; - mask-image: var(--md-admonition-icon--note); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: flavours -// ---------------------------------------------------------------------------- - -// Define admonition flavors -@each $names, $props in $admonitions { - $name: list.nth($names, 1); - $tint: list.nth($props, 2); - - // Admonition flavour selectors - $flavours: (); - @each $name in $names { - $flavours: list.join($flavours, ".#{$name}", $separator: comma); - } - - // Admonition flavour - .md-typeset :is(.admonition, details):is(#{$flavours}) { - border-color: $tint; - } - - // Admonition flavour title - .md-typeset :is(#{$flavours}) > :is(.admonition-title, summary) { - background-color: color.adjust($tint, $alpha: -0.9); - - // Admonition icon - &::before { - background-color: $tint; - mask-image: var(--md-admonition-icon--#{$name}); - mask-repeat: no-repeat; - mask-size: contain; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss b/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss @@ -1,145 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Footnotes variables -:root { - --md-footnotes-icon: svg-load("material/keyboard-return.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Footnote container - .footnote { - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - - // Footnote list - omit left indentation - > ol { - margin-inline-start: 0; - - // Footnote item - footnote items can contain lists, so we need to scope - // the spacing adjustments to the top-level footnote item. - > li { - transition: color 125ms; - - // Darken color on target - &:target { - color: var(--md-default-fg-color); - } - - // Show backreferences on footnote focus without transition - &:focus-within .footnote-backref { - transform: translateX(0); - opacity: 1; - transition: none; - } - - // Show backreferences on footnote hover/target - &:is(:hover, :target) .footnote-backref { - transform: translateX(0); - opacity: 1; - } - - // Adjust spacing on first child - > :first-child { - margin-top: 0; - } - } - } - } - - // Footnote reference - .footnote-ref { - font-weight: 700; - font-size: px2em(12px, 16px); - - // Hack: increase specificity to override default - html & { - outline-offset: px2rem(2px); - } - } - - // Show outline for all devices - [id^="fnref:"]:target > .footnote-ref { - outline: auto; - } - - // Footnote backreference - .footnote-backref { - display: inline-block; - color: var(--md-typeset-a-color); - // Hack: omit Unicode arrow for replacement with icon - font-size: 0; - vertical-align: text-bottom; - transform: translateX(px2rem(5px)); - opacity: 0; - transition: - color 250ms, - transform 250ms 250ms, - opacity 125ms 250ms; - - // [print]: Show footnote backreferences - @media print { - color: var(--md-typeset-a-color); - transform: translateX(0); - opacity: 1; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-5px)); - } - - // Adjust color on hover - &:hover { - color: var(--md-accent-fg-color); - } - - // Footnote backreference icon - &::before { - display: inline-block; - width: px2rem(16px); - height: px2rem(16px); - background-color: currentcolor; - mask-image: var(--md-footnotes-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - } -} diff --git a/src/assets/stylesheets/main/extensions/markdown/_toc.scss b/src/assets/stylesheets/main/extensions/markdown/_toc.scss @@ -1,92 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Headerlink - .headerlink { - display: inline-block; - margin-inline-start: px2rem(10px); - color: var(--md-default-fg-color--lighter); - opacity: 0; - transition: - color 250ms, - opacity 125ms; - - // [print]: Hide headerlinks - @media print { - display: none; - } - } - - // Show headerlinks on parent hover - :is(:hover, :target) > .headerlink, - .headerlink:focus { - opacity: 1; - transition: - color 250ms, - opacity 125ms; - } - - // Adjust color on parent target or focus/hover - :target > .headerlink, - .headerlink:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - - // Adjust scroll margin for all elements with `id` attributes - :target { - --md-scroll-margin: #{px2rem(48px + 24px)}; - --md-scroll-offset: #{px2rem(0px)}; - // Scroll margin is finally ready for prime time - before, we used a hack - // for anchor correction based on pseudo elements but those times are gone. - scroll-margin-top: - calc( - var(--md-scroll-margin) - - var(--md-scroll-offset) - ); - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll margin for sticky navigation tabs - .md-header--lifted ~ .md-container & { - --md-scroll-margin: #{px2rem(96px + 24px)}; - } - } - } - - // Adjust scroll offset for headlines of level 1-3 - :is(h1, h2, h3):target { - --md-scroll-offset: #{px2rem(4px)}; - } - - // Adjust scroll offset for headlines of level 4 - h4:target { - --md-scroll-offset: #{px2rem(3px)}; - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss b/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss @@ -1,52 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Arithmatex container - div.arithmatex { - overflow: auto; - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - margin: 0 px2rem(-16px); - } - - // Arithmatex content - > * { - width: min-content; - margin-inline: auto !important; // stylelint-disable-line - padding: 0 px2rem(16px); - touch-action: auto; - - // MathJax container - see https://bit.ly/3HR8YJ5 - mjx-container { - margin: 0 !important; // stylelint-disable-line - } - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss b/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss @@ -1,78 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Deletion, addition or comment - :is(del, ins, .comment).critic { - box-decoration-break: clone; - } - - // Deletion - del.critic { - background-color: var(--md-typeset-del-color); - } - - // Addition - ins.critic { - background-color: var(--md-typeset-ins-color); - } - - // Comment - .critic.comment { - color: var(--md-code-hl-comment-color); - - // Comment opening mark - &::before { - content: "/* "; - } - - // Comment closing mark - &::after { - content: " */"; - } - } - - // Critic block - .critic.block { - display: block; - margin: 1em 0; - padding-inline: px2rem(16px); - overflow: auto; - box-shadow: none; - - // Adjust spacing on first child - > :first-child { - margin-top: 0.5em; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0.5em; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_details.scss b/src/assets/stylesheets/main/extensions/pymdownx/_details.scss @@ -1,116 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Details variables -:root { - --md-details-icon: svg-load("material/chevron-right.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Details - details { - display: flow-root; - padding-top: 0; - overflow: visible; - - // Details title icon - rotate icon on transition to open state - &[open] > summary::after { - transform: rotate(90deg); - } - - // Adjust spacing for details in closed state - &:not([open]) { - padding-bottom: 0; - box-shadow: none; - - // Hack: we cannot set `overflow: hidden` on the `details` element (which - // is why we set it to `overflow: visible`, as the outline would not be - // visible when focusing. Therefore, we must set the border radius on the - // summary explicitly. - > summary { - border-radius: px2rem(2px); - } - } - } - - // Details title - summary { - display: block; - min-height: px2rem(20px); - padding-inline-end: px2rem(36px); - border-start-start-radius: px2rem(2px); - border-start-end-radius: px2rem(2px); - cursor: pointer; - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Details marker - &::after { - position: absolute; - top: px2em(10px); - inset-inline-end: px2rem(8px); - width: px2rem(20px); - height: px2rem(20px); - background-color: currentcolor; - mask-image: var(--md-details-icon); - mask-repeat: no-repeat; - mask-size: contain; - transform: rotate(0deg); - transition: transform 250ms; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: rotate(180deg); - } - } - - // Hide native details marker - modern - &::marker { - display: none; - } - - // Hide native details marker - legacy, must be split into a seprate rule, - // so older browsers don't consider the selector list as invalid - &::-webkit-details-marker { - display: none; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss b/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss @@ -1,43 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Emoji and icon container - :is(.emojione, .twemoji, .gemoji) { - display: inline-flex; - height: px2em(18px); - vertical-align: text-top; - - // Icon - inlined via mkdocs-material-extensions - svg { - width: px2em(18px); - max-height: 100%; - fill: currentcolor; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss b/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss @@ -1,381 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules: syntax highlighting -// ---------------------------------------------------------------------------- - -// Code block -.highlight { - - // .o = Operator - // .ow = Operator, word - :is(.o, .ow) { - color: var(--md-code-hl-operator-color); - } - - .p { // Punctuation - color: var(--md-code-hl-punctuation-color); - } - - // .cpf = Comment, preprocessor file - // .l = Literal - // .s = Literal, string - // .sb = Literal, string backticks - // .sc = Literal, string char - // .s2 = Literal, string double - // .si = Literal, string interpol - // .s1 = Literal, string single - // .ss = Literal, string symbol - :is(.cpf, .l, .s, .sb, .sc, .s2, .si, .s1, .ss) { - color: var(--md-code-hl-string-color); - } - - // .cp = Comment, pre-processor - // .se = Literal, string escape - // .sh = Literal, string heredoc - // .sr = Literal, string regex - // .sx = Literal, string other - :is(.cp, .se, .sh, .sr, .sx) { - color: var(--md-code-hl-special-color); - } - - // .m = Number - // .mb = Number, binary - // .mf = Number, float - // .mh = Number, hex - // .mi = Number, integer - // .il = Number, integer long - // .mo = Number, octal - :is(.m, .mb, .mf, .mh, .mi, .il, .mo) { - color: var(--md-code-hl-number-color); - } - - // .k = Keyword, - // .kd = Keyword, declaration - // .kn = Keyword, namespace - // .kp = Keyword, pseudo - // .kr = Keyword, reserved - // .kt = Keyword, type - :is(.k, .kd, .kn, .kp, .kr, .kt) { - color: var(--md-code-hl-keyword-color); - } - - // .kc = Keyword, constant - // .n = Name - :is(.kc, .n) { - color: var(--md-code-hl-name-color); - } - - // .no = Name, constant - // .nb = Name, builtin - // .bp = Name, builtin pseudo - :is(.no, .nb, .bp) { - color: var(--md-code-hl-constant-color); - } - - // .nc = Name, class - // .ne = Name, exception - // .nf = Name, function - // .nn = Name, namespace - :is(.nc, .ne, .nf, .nn) { - color: var(--md-code-hl-function-color); - } - - // .nd = Name, decorator - // .ni = Name, entity - // .nl = Name, label - // .nt = Name, tag - :is(.nd, .ni, .nl, .nt) { - color: var(--md-code-hl-keyword-color); - } - - // .c = Comment - // .cm = Comment, multiline - // .c1 = Comment, single - // .ch = Comment, shebang - // .cs = Comment, special - // .sd = Literal, string doc - :is(.c, .cm, .c1, .ch, .cs, .sd) { - color: var(--md-code-hl-comment-color); - } - - // .na = Name, attribute - // .nv = Variable, - // .vc = Variable, class - // .vg = Variable, global - // .vi = Variable, instance - :is(.na, .nv, .vc, .vg, .vi) { - color: var(--md-code-hl-variable-color); - } - - // .ge = Generic, emph - // .gr = Generic, error - // .gh = Generic, heading - // .go = Generic, output - // .gp = Generic, prompt - // .gs = Generic, strong - // .gu = Generic, subheading - // .gt = Generic, traceback - :is(.ge, .gr, .gh, .go, .gp, .gs, .gu, .gt) { - color: var(--md-code-hl-generic-color); - } - - // .gd = Diff, delete - // .gi = Diff, insert - :is(.gd, .gi) { - margin: 0 px2em(-2px); - padding: 0 px2em(2px); - border-radius: px2rem(2px); - } - - .gd { // Diff, delete - background-color: var(--md-typeset-del-color); - } - - .gi { // Diff, insert - background-color: var(--md-typeset-ins-color); - } - - // Highlighted line - .hll { - display: block; - margin: 0 px2em(-16px, 13.6px); - padding: 0 px2em(16px, 13.6px); - background-color: var(--md-code-hl-color); - } - - // Code block title - span.filename { - position: relative; - display: flow-root; - margin-top: 1em; - padding: px2em(9px, 13.6px) px2em(16px, 13.6px); - font-weight: 700; - font-size: px2em(13.6px); - background-color: var(--md-code-bg-color); - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - border-top-left-radius: px2rem(2px); - border-top-right-radius: px2rem(2px); - - // Adjust spacing for code block - + pre { - margin-top: 0; - - // Remove rounded border on top side - > code { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - } - - // Code block line numbers (pymdownx-inline) - [data-linenos]::before { - position: sticky; - left: px2em(-16px, 13.6px); - // A `z-index` of 3 is necessary for ensuring that code block annotations - // don't overlay line numbers, as active annotations have a `z-index` of 2. - z-index: 3; - float: left; - margin-right: px2em(16px, 13.6px); - margin-left: px2em(-16px, 13.6px); - padding-left: px2em(16px, 13.6px); - color: var(--md-default-fg-color--light); - background-color: var(--md-code-bg-color); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - content: attr(data-linenos); - user-select: none; - } - - // Code block line anchors - Chrome and Safari seem to have a strange bug - // where scroll margin is not applied to anchors inside code blocks. Setting - // positioning to absolute seems to fix the problem. Interestingly, this does - // not happen in Firefox. Furthermore we must set `visibility: hidden` or - // the copy to clipboard functionality will include an empty line between - // each set of lines. - code a[id] { - position: absolute; - visibility: hidden; - } - - // Copying in progress - this class is set before the content is copied and - // removed after copying is done to mitigate whitespace-related issues. - code[data-md-copying] { - - // Temporarily remove highlighted lines - see https://bit.ly/32iVGWh - .hll { - display: contents; - } - - // Temporarily remove annotations - .md-annotation { - display: none; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Code block with line numbers -.highlighttable { - display: flow-root; - - // Set table elements to block layout, because otherwise the whole flexbox - // hacking won't work correctly - :is(tbody, td) { - display: block; - padding: 0; - } - - // We need to use flexbox layout, because otherwise it's not possible to - // make the code container scroll while keeping the line numbers static - tr { - display: flex; - } - - // The pre tags are nested inside a table, so we need to omit the margin - // because it collapses below all the overflows - pre { - margin: 0; - } - - // Code block title container - th.filename { - flex-grow: 1; - padding: 0; - text-align: left; - - // Adjust spacing - span.filename { - margin-top: 0; - } - } - - // Code block line numbers - disable user selection, so code can be easily - // copied without accidentally also copying the line numbers - .linenos { - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - padding-right: 0; - font-size: px2em(13.6px); - background-color: var(--md-code-bg-color); - border-top-left-radius: px2rem(2px); - border-bottom-left-radius: px2rem(2px); - user-select: none; - } - - // Code block line numbers container - .linenodiv { - padding-right: px2em(8px, 13.6px); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - - // Adjust colors and alignment - pre { - color: var(--md-default-fg-color--light); - text-align: right; - } - } - - // Code block container - stretch to remaining space - .code { - flex: 1; - min-width: 0; - } -} - -// Code block line numbers container -.linenodiv a { - color: inherit; -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Code block with line numbers - unfortunately, these selectors need to be - // overly specific so they don't bleed into code blocks in annotations. - .highlighttable { - margin: 1em 0; - direction: ltr; - - // Remove rounded borders on code blocks - > tbody > tr > .code > div > pre > code { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - } - - // Code block result container - .highlight + .result { - margin-top: calc(-1em + #{px2em(-2px)}); - padding: 0 px2em(16px); - overflow: visible; - border: px2rem(1px) solid var(--md-code-bg-color); - border-top-width: px2rem(2px); - border-bottom-right-radius: px2rem(2px); - border-bottom-left-radius: px2rem(2px); - - // Clearfix, because we can't use overflow: auto - &::after { - display: block; - clear: both; - content: ""; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: top-level -// ---------------------------------------------------------------------------- - -// [mobile -]: Align with body copy -@include break-to-device(mobile) { - - // Top-level code block - .md-content__inner > .highlight { - margin: 1em px2rem(-16px); - - // Remove rounded borders - > .filename, - > pre > code { - border-radius: 0; - } - - // Code block with line numbers - unfortunately, these selectors need to be - // overly specific so they don't bleed into code blocks in annotations. - > .highlighttable > tbody > tr > .filename span.filename, - > .highlighttable > tbody > tr > .linenos, - > .highlighttable > tbody > tr > .code > div > pre > code { - border-radius: 0; - } - - // Code block result container - + .result { - margin-inline: px2rem(-16px); - border-inline-width: 0; - border-radius: 0; - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss b/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss @@ -1,115 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Keyboard key - .keys { - - // Keyboard key icon - kbd:is(::before, ::after) { - position: relative; - margin: 0; - color: inherit; - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - } - - // Surrounding text - span { - padding: 0 px2em(3.2px); - color: var(--md-default-fg-color--light); - } - - // Define keyboard keys with left icon - @each $name, $code in ( - - // Modifiers - "alt": "\2387", - "left-alt": "\2387", - "right-alt": "\2387", - "command": "\2318", - "left-command": "\2318", - "right-command": "\2318", - "control": "\2303", - "left-control": "\2303", - "right-control": "\2303", - "meta": "\25C6", - "left-meta": "\25C6", - "right-meta": "\25C6", - "option": "\2325", - "left-option": "\2325", - "right-option": "\2325", - "shift": "\21E7", - "left-shift": "\21E7", - "right-shift": "\21E7", - "super": "\2756", - "left-super": "\2756", - "right-super": "\2756", - "windows": "\229E", - "left-windows": "\229E", - "right-windows": "\229E", - - // Other keys - "arrow-down": "\2193", - "arrow-left": "\2190", - "arrow-right": "\2192", - "arrow-up": "\2191", - "backspace": "\232B", - "backtab": "\21E4", - "caps-lock": "\21EA", - "clear": "\2327", - "context-menu": "\2630", - "delete": "\2326", - "eject": "\23CF", - "end": "\2913", - "escape": "\238B", - "home": "\2912", - "insert": "\2380", - "page-down": "\21DF", - "page-up": "\21DE", - "print-screen": "\2399" - ) { - .key-#{$name}::before { - padding-right: px2em(6.4px); - content: $code; - } - } - - // Define keyboard keys with right icon - @each $name, $code in ( - "tab": "\21E5", - "num-enter": "\2324", - "enter": "\23CE" - ) { - .key-#{$name}::after { - padding-left: px2em(6.4px); - content: $code; - } - } - } -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss b/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss @@ -1,393 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Tabbed variables -:root { - --md-tabbed-icon--prev: svg-load("material/chevron-left.svg"); - --md-tabbed-icon--next: svg-load("material/chevron-right.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tabbed container - .tabbed-set { - position: relative; - display: flex; - flex-flow: column wrap; - margin: 1em 0; - border-radius: px2rem(2px); - - // Tab radio button - the Tabbed extension will generate radio buttons with - // labels, so tabs can be triggered without the necessity for JavaScript. - // This is pretty cool, as it has great accessibility out-of-the box, so - // we just hide the radio button and toggle the label color for indication. - > input { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Adjust scroll margin - &:target { - --md-scroll-offset: #{px2em(10px, 16px)}; - } - - // Tab label states - @for $i from 20 through 1 { - &:nth-child(#{$i}) { - - // Tab is active - &:checked { - - // Tab label - ~ .tabbed-labels > :nth-child(#{$i}) { - @extend %tabbed-label; - } - - // Tab content - ~ .tabbed-content > :nth-child(#{$i}) { - @extend %tabbed-content; - } - } - - // Tab label on keyboard focus - &.focus-visible ~ .tabbed-labels > :nth-child(#{$i}) { - @extend %tabbed-label-focus-visible; - } - } - } - } - } - - // Tabbed labels - .tabbed-labels { - display: flex; - max-width: 100%; - overflow: auto; - box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest) inset; - -ms-overflow-style: none; // IE, Edge - scrollbar-width: none; // Firefox - - // [print]: Move one layer up for ordering - @media print { - display: contents; - } - - // [screen and no reduced motion]: Disable animation - @media screen { - - // [js]: Show animated tab indicator - .js & { - position: relative; - - // Tab indicator - &::before { - position: absolute; - bottom: 0; - left: 0; - display: block; - width: var(--md-indicator-width); - height: 2px; - background: var(--md-accent-fg-color); - transform: translateX(var(--md-indicator-x)); - transition: - width 225ms, - transform 250ms; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - content: ""; - } - } - } - - // Webkit scrollbar - &::-webkit-scrollbar { - display: none; // Chrome, Safari - } - - // Tab label - > label { - flex-shrink: 0; - width: auto; - padding: px2em(10px, 12.8px) 1.25em px2em(8px, 12.8px); - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2rem(12.8px); - white-space: nowrap; - border-bottom: px2rem(2px) solid transparent; - border-radius: px2rem(2px) px2rem(2px) 0 0; - cursor: pointer; - transition: - background-color 250ms, - color 250ms; - scroll-margin-inline-start: px2rem(20px); - - // [print]: Intersperse labels with containers - @media print { - - // Ensure correct order of labels - @for $i from 1 through 20 { - &:nth-child(#{$i}) { - order: $i; - } - } - } - - // Tab label on hover - &:hover { - color: var(--md-accent-fg-color); - } - } - } - - // Tabbed content - .tabbed-content { - width: 100%; - - // [print]: Move one layer up for ordering - @media print { - display: contents; - } - } - - // Tabbed block - .tabbed-block { - display: none; - - // [print]: Intersperse labels with containers - @media print { - display: block; - - // Ensure correct order of containers - @for $i from 1 through 20 { - &:nth-child(#{$i}) { - order: $i; - } - } - } - - // Code block is the first child of a tab - remove margin and mirror - // previous (now deprecated) SuperFences code block grouping behavior - > pre:first-child, - > .highlight:first-child > pre { - margin: 0; - - // Remove rounded borders on code block - > code { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - - // Code block is the first child of a tab - remove margin and mirror - // previous (now deprecated) SuperFences code block grouping behavior - > .highlight:first-child { - - // Code block title - remove spacing and rounded borders - > .filename { - margin: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; - } - - // Code block with line numbers - unfortunately, these selectors need to - // be overly specific so they don't bleed into code blocks in annotations. - > .highlighttable { - margin: 0; - - // Remove rounded borders on line numbers and titles - > tbody > tr > .filename span.filename, - > tbody > tr > .linenos { - margin: 0; - border-top-left-radius: 0; - border-top-right-radius: 0; - } - - // Remove rounded borders on code blocks - > tbody > tr > .code > div > pre > code { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - - // Code block result container - adjust spacing - + .result { - margin-top: px2em(-2px); - } - } - - // Adjust spacing for nested tabbed container - > .tabbed-set { - margin: 0; - } - } - - // Tabbed button - .tabbed-button { - display: block; - align-self: center; - width: px2rem(18px); - height: px2rem(18px); - margin-top: px2rem(2px); - color: var(--md-default-fg-color--light); - border-radius: 100%; - cursor: pointer; - transition: background-color 250ms; - pointer-events: initial; - - // Tabbed button on hover - &:hover { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - - // Tabbed button icon - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentcolor; - transition: - background-color 250ms, - transform 250ms; - mask-image: var(--md-tabbed-icon--prev); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - - // Tabbed control - .tabbed-control { - position: absolute; - display: flex; - justify-content: start; - width: px2rem(24px); - height: px2rem(38px); - background: - linear-gradient( - to right, - var(--md-default-bg-color) 60%, - transparent - ); - transition: opacity 125ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: rotate(180deg); - } - - // Tabbed control is hidden - &[hidden] { - opacity: 0; - } - - // Tabbed control next - &--next { - right: 0; - justify-content: end; - background: - linear-gradient( - to left, - var(--md-default-bg-color) 60%, - transparent - ); - - // Tabbed button icon content - .tabbed-button::after { - mask-image: var(--md-tabbed-icon--next); - } - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: top-level -// ---------------------------------------------------------------------------- - -// [mobile -]: Align with body copy -@include break-to-device(mobile) { - - // Top-level tabbed labels - .md-content__inner > .tabbed-set .tabbed-labels { - max-width: 100vw; - margin: 0 px2rem(-16px); - padding-inline-start: px2rem(16px); - scroll-padding-inline-start: px2rem(16px); - - // Hack: some browsers ignore the right padding on flex containers, - // see https://bit.ly/3lsPS3S - &::after { - padding-inline-end: px2rem(16px); - content: ""; - } - - // Tabbed control previous - ~ .tabbed-control--prev { - width: px2rem(40px); - margin-inline-start: px2rem(-16px); - padding-inline-start: px2rem(16px); - } - - // Tabbed control next - ~ .tabbed-control--next { - width: px2rem(40px); - margin-inline-end: px2rem(-16px); - padding-inline-end: px2rem(16px); - } - } -} - -// ---------------------------------------------------------------------------- -// Placeholders: improve colocation for better compression -// ---------------------------------------------------------------------------- - -// Tab label placeholder -%tabbed-label { - - // [screen]: Show active state - @media screen { - color: var(--md-accent-fg-color); - - // [no-js]: Show border (indicator is animated with JavaScript) - .no-js & { - border-color: var(--md-accent-fg-color); - } - } -} - -// Tab label on keyboard focus placeholder -%tabbed-label-focus-visible { - background-color: var(--md-accent-fg-color--transparent); -} - -// Tab content placeholder -%tabbed-content { - display: block; -} diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss b/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Tasklist variables -:root { - --md-tasklist-icon: - svg-load("octicons/check-circle-fill-24.svg"); - --md-tasklist-icon--checked: - svg-load("octicons/check-circle-fill-24.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tasklist item - .task-list-item { - position: relative; - list-style-type: none; - - // Make checkbox items align with normal list items, but position - // everything in ems for correct layout at smaller font sizes - [type="checkbox"] { - position: absolute; - top: 0.45em; - inset-inline-start: -2em; - } - } - - // Hide native checkbox, when custom classes are enabled - .task-list-control [type="checkbox"] { - z-index: -1; - opacity: 0; - } - - // Tasklist indicator in unchecked state - .task-list-indicator::before { - position: absolute; - top: 0.15em; - inset-inline-start: px2em(-24px); - width: px2em(20px); - height: px2em(20px); - background-color: var(--md-default-fg-color--lightest); - mask-image: var(--md-tasklist-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Tasklist indicator in checked state - [type="checkbox"]:checked + .task-list-indicator::before { - background-color: $clr-green-a400; - mask-image: var(--md-tasklist-icon--checked); - } -} diff --git a/src/assets/stylesheets/main/integrations/_mermaid.scss b/src/assets/stylesheets/main/integrations/_mermaid.scss @@ -1,43 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// All definitions -:root > * { - --md-mermaid-font-family: var(--md-text-font-family), sans-serif; - - // Colors - --md-mermaid-edge-color: var(--md-code-fg-color); - --md-mermaid-node-bg-color: var(--md-accent-fg-color--transparent); - --md-mermaid-node-fg-color: var(--md-accent-fg-color); - --md-mermaid-label-bg-color: var(--md-default-bg-color); - --md-mermaid-label-fg-color: var(--md-code-fg-color); -} - -// Mermaid container -.mermaid { - margin: 1em 0; - line-height: normal; -} diff --git a/src/assets/stylesheets/main/layout/_banner.scss b/src/assets/stylesheets/main/layout/_banner.scss @@ -1,63 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Banner for announcements and warnings -.md-banner { - overflow: auto; - color: var(--md-footer-fg-color); - background-color: var(--md-footer-bg-color); - - // [print]: Hide banner - @media print { - display: none; - } - - // Banner with warning - &--warning { - color: var(--md-default-fg-color); - background: var(--md-typeset-mark-color); - } - - // Banner wrapper - &__inner { - margin: px2rem(12px) auto; - padding: 0 px2rem(16px); - font-size: px2rem(14px); - } - - // Banner button - &__button { - float: right; - color: inherit; - cursor: pointer; - transition: opacity 250ms; - - // Button on hover - &:hover { - opacity: 0.7; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_base.scss b/src/assets/stylesheets/main/layout/_base.scss @@ -1,183 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules: base grid and containers -// ---------------------------------------------------------------------------- - -// Stretch container to viewport and set base `font-size` -html { - height: 100%; - overflow-x: hidden; - // Hack: normally, we would set the base `font-size` to `62.5%`, so we can - // base all calculations on `10px`, but Chromium and Chrome define a minimal - // `font-size` of `12px` if the system language is set to Chinese. For this - // reason we just double the `font-size` and set it to `20px`. - // - // See https://github.com/squidfunk/mkdocs-material/issues/911 - font-size: 125%; - - // [screen medium +]: Set base `font-size` to `11px` - @include break-from-device(screen medium) { - font-size: 137.5%; - } - - // [screen large +]: Set base `font-size` to `12px` - @include break-from-device(screen large) { - font-size: 150%; - } -} - -// Stretch body to container - flexbox is used, so the footer will always be -// aligned to the bottom of the viewport -body { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - min-height: 100%; - // Hack: reset `font-size` to `10px`, so the spacing for all inline elements - // is correct again. Otherwise the spacing would be based on `20px`. - font-size: px2rem(10px); - background-color: var(--md-default-bg-color); - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } - - // Body in locked state - &[data-md-scrolllock] { - - // [tablet portrait -]: Omit scroll bubbling - @include break-to-device(tablet portrait) { - position: fixed; - } - } -} - -// ---------------------------------------------------------------------------- - -// Grid container - this class is applied to wrapper elements within the -// header, content area and footer, and makes sure that their width is limited -// to `1220px`, and they are rendered centered if the screen is larger. -.md-grid { - max-width: px2rem(1220px); - margin-inline: auto; -} - -// Main container -.md-container { - display: flex; - flex-direction: column; - flex-grow: 1; - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } -} - -// Main area - stretch to remaining space of container -.md-main { - flex-grow: 1; - - // Main area wrapper - &__inner { - display: flex; - height: 100%; - margin-top: px2rem(24px + 6px); - } -} - -// Add ellipsis in case of overflowing text -.md-ellipsis { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -// ---------------------------------------------------------------------------- -// Rules: navigational elements -// ---------------------------------------------------------------------------- - -// Toggle - this class is applied to checkbox elements, which are used to -// implement the CSS-only drawer and navigation, as well as the search -.md-toggle { - display: none; -} - -// Option - this class is applied to radio elements, which are used to -// implement the color palette toggle -.md-option { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Option label for checked radio button - &:checked + label:not([hidden]) { - display: block; - } - - // Show outline for keyboard devices - &.focus-visible + label { - outline-style: auto; - outline-color: var(--md-accent-fg-color); - } -} - -// Skip link -.md-skip { - position: fixed; - // Hack: if we don't set the negative `z-index`, the skip link will force the - // creation of new layers when code blocks are near the header on scrolling - z-index: -1; - margin: px2rem(10px); - padding: px2rem(6px) px2rem(10px); - color: var(--md-default-bg-color); - font-size: px2rem(12.8px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - transform: translateY(px2rem(8px)); - opacity: 0; - - // Show skip link on focus - &:focus { - z-index: 10; - transform: translateY(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 175ms 75ms; - } -} - -// ---------------------------------------------------------------------------- -// Rules: print styles -// ---------------------------------------------------------------------------- - -// Add margins to page -@page { - margin: 25mm; -} diff --git a/src/assets/stylesheets/main/layout/_clipboard.scss b/src/assets/stylesheets/main/layout/_clipboard.scss @@ -1,101 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Clipboard button variables -:root { - --md-clipboard-icon: svg-load("material/content-copy.svg"); -} - -// ---------------------------------------------------------------------------- - -// Clipboard button -.md-clipboard { - position: absolute; - top: px2em(8px); - right: px2em(8px); - z-index: 1; - width: px2em(24px); - height: px2em(24px); - color: var(--md-default-fg-color--lightest); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(2px); - cursor: pointer; - transition: color 250ms; - - // [print]: Hide button - @media print { - display: none; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Darken color on code block hover - :hover > & { - color: var(--md-default-fg-color--light); - } - - // Button on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - - // Button icon - the width and height are defined in `em`, so the size is - // automatically adjusted for nested code blocks (e.g. in admonitions) - &::after { - display: block; - width: px2em(18px); - height: px2em(18px); - margin: 0 auto; - background-color: currentcolor; - mask-image: var(--md-clipboard-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Inline clipboard button - &--inline { - cursor: pointer; - - // Code block - code { - transition: - color 250ms, - background-color 250ms; - } - - // Code block on focus/hover - &:is(:focus, :hover) code { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - } -} diff --git a/src/assets/stylesheets/main/layout/_consent.scss b/src/assets/stylesheets/main/layout/_consent.scss @@ -1,127 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Show consent -@keyframes consent { - 0% { - transform: translateY(100%); - opacity: 0; - } - - 100% { - transform: translateY(0); - opacity: 1; - } -} - -// Show consent overlay -@keyframes overlay { - 0% { - opacity: 0; - } - - 100% { - opacity: 1; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Consent -.md-consent { - - // Consent overlay - &__overlay { - position: fixed; - top: 0; - z-index: 5; - width: 100%; - height: 100%; - background-color: hsla(0, 0%, 0%, 0.54); - opacity: 1; - backdrop-filter: blur(px2rem(2px)); - animation: overlay 250ms both; - } - - // Consent wrapper - &__inner { - position: fixed; - bottom: 0; - z-index: 5; - width: 100%; - max-height: 100%; - padding: 0; - overflow: auto; - background-color: var(--md-default-bg-color); - border: 0; - border-radius: px2rem(2px); - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0.1), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2); - animation: consent 500ms cubic-bezier(0.1, 0.7, 0.1, 1) both; - } - - // Consent form - &__form { - padding: px2rem(16px); - } - - // Consent settings - &__settings { - display: none; - margin: 1em 0; - - // Show settings - input:checked + & { - display: block; - } - } - - // Consent controls - &__controls { - margin-bottom: px2rem(16px); - - // Consent control button - .md-typeset & .md-button { - display: inline; - - // [tablet +]: Align buttons horizontally - @include break-to-device(mobile) { - display: block; - width: 100%; - margin-top: px2rem(8px); - text-align: center; - } - } - } - - // Ensure users realize that labels are clickaböe - label { - cursor: pointer; - } -} diff --git a/src/assets/stylesheets/main/layout/_content.scss b/src/assets/stylesheets/main/layout/_content.scss @@ -1,102 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Content area -.md-content { - flex-grow: 1; - // Hack: we must use `min-width: 0`, so the content area is capped by the - // dimensions of its parent. Otherwise, long code blocks might lead to a - // wider content area which will overflow. See https://bit.ly/3bP3f8k - min-width: 0; - - // Content wrapper - &__inner { - margin: 0 px2rem(16px) px2rem(24px); - padding-top: px2rem(12px); - - // [screen +]: Adjust spacing between content area and sidebars - @include break-from-device(screen) { - - // Sidebar with navigation is visible - .md-sidebar--primary:not([hidden]) ~ .md-content > & { - margin-inline-start: px2rem(24px); - } - - // Sidebar with table of contents is visible - .md-sidebar--secondary:not([hidden]) ~ .md-content > & { - margin-inline-end: px2rem(24px); - } - } - - // Hack: add pseudo element for spacing, as the overflow of the content - // container may not be hidden due to an imminent offset error on targets - &::before { - display: block; - height: px2rem(8px); - content: ""; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0; - } - } - - // Button inside of the content area - these buttons are meant for actions on - // a document-level, i.e. linking to related source code files, printing etc. - &__button { - float: right; - margin: px2rem(8px) 0; - margin-inline-start: px2rem(8px); - padding: 0; - - // [print]: Hide buttons - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - - // Adjust default link color for icons - .md-typeset & { - color: var(--md-default-fg-color--lighter); - } - - // Align with body copy located next to icon - svg { - display: inline; - vertical-align: top; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: scaleX(-1); - } - } - } -} diff --git a/src/assets/stylesheets/main/layout/_dialog.scss b/src/assets/stylesheets/main/layout/_dialog.scss @@ -1,65 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Dialog -.md-dialog { - position: fixed; - inset-inline-end: px2rem(16px); - bottom: px2rem(16px); - z-index: 4; - min-width: px2rem(222px); - padding: px2rem(8px) px2rem(12px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z3); - transform: translateY(100%); - opacity: 0; - transition: - transform 0ms 400ms, - opacity 400ms; - pointer-events: none; - - // [print]: Hide dialog - @media print { - display: none; - } - - // Active dialog - &--active { - transform: translateY(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.075, 0.85, 0.175, 1), - opacity 400ms; - pointer-events: initial; - } - - // Dialog wrapper - &__inner { - color: var(--md-default-bg-color); - font-size: px2rem(14px); - } -} diff --git a/src/assets/stylesheets/main/layout/_feedback.scss b/src/assets/stylesheets/main/layout/_feedback.scss @@ -1,110 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Was this page helpful? -.md-feedback { - margin: 2em 0 1em; - text-align: center; - - // Feedback fieldset - fieldset { - margin: 0; - padding: 0; - border: none; - } - - // Feedback title - &__title { - margin: 1em auto; - font-weight: 700; - } - - // Feedback wrapper - &__inner { - position: relative; - } - - // Feedback list - &__list { - position: relative; - display: flex; - flex-wrap: wrap; - align-content: baseline; - justify-content: center; - - // Feedback icon on hover - &:hover .md-icon:not(:disabled) { - color: var(--md-default-fg-color--lighter); - } - - // Adjust height after submission - :disabled & { - min-height: px2rem(36px); - } - } - - // Feedback icon - &__icon { - flex-shrink: 0; - margin: 0 px2rem(2px); - color: var(--md-default-fg-color--light); - cursor: pointer; - transition: color 125ms; - - // Feedback icon on hover - &:not(:disabled).md-icon:hover { - color: var(--md-accent-fg-color); - } - - // Feedback icon after submit - &:disabled { - color: var(--md-default-fg-color--lightest); - pointer-events: none; - } - } - - // Feedback note - &__note { - position: relative; - transform: translateY(px2rem(8px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Feedback note value - > * { - max-width: px2rem(320px); - margin: 0 auto; - } - - // Show after submission - :disabled & { - transform: translateY(0); - opacity: 1; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_footer.scss b/src/assets/stylesheets/main/layout/_footer.scss @@ -1,202 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Footer -.md-footer { - color: var(--md-footer-fg-color); - background-color: var(--md-footer-bg-color); - - // [print]: Hide footer - @media print { - display: none; - } - - // Footer wrapper - &__inner { - justify-content: space-between; - padding: px2rem(4px); - overflow: auto; - - // Footer is visible - &:not([hidden]) { - display: flex; - } - } - - // Footer link to previous and next page - &__link { - display: flex; - // Hack: some browsers induce ellipsis on flex children that are set to - // `overflow: hidden` and `text-overflow: ellipsis`. Enforcing growth by - // a tiny factor seems to get rid of the ellipsis and renders the text as - // it should - see https://bit.ly/2ZUCXQ8 - flex-grow: 0.01; - padding-top: px2rem(28px); - padding-bottom: px2rem(8px); - overflow: hidden; - outline-color: var(--md-accent-fg-color); - transition: opacity 250ms; - - // Footer link on focus/hover - &:is(:focus, :hover) { - opacity: 0.7; - } - - // Adjust for right-to-left languages - [dir="rtl"] & svg { - transform: scaleX(-1); - } - - // Footer link to previous page - &--prev { - - // [mobile -]: Adjust width to 25/75 and hide title - @include break-to-device(mobile) { - - // Hide footer title - .md-footer__title { - display: none; - } - } - } - - // Footer link to next page - &--next { - margin-inline-start: auto; - text-align: right; - - // Adjust for right-to-left languages - [dir="rtl"] & { - text-align: left; - } - } - } - - // Footer title - &__title { - position: relative; - flex-grow: 1; - max-width: calc(100% - #{px2rem(48px)}); - padding: 0 px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - white-space: nowrap; - } - - // Footer link button - &__button { - margin: px2rem(4px); - padding: px2rem(8px); - } - - // Footer link direction (i.e. prev and next) - &__direction { - position: absolute; - inset-inline: 0; - margin-top: px2rem(-20px); - padding: 0 px2rem(20px); - font-size: px2rem(12.8px); - opacity: 0.7; - } -} - -// Footer metadata -.md-footer-meta { - background-color: var(--md-footer-bg-color--dark); - - // Footer metadata wrapper - &__inner { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - padding: px2rem(4px); - } - - // Lighten color for non-hovered text links - html &.md-typeset a { - color: var(--md-footer-fg-color--light); - - // Text link on focus/hover - &:is(:focus, :hover) { - color: var(--md-footer-fg-color); - } - } -} - -// ---------------------------------------------------------------------------- - -// Copyright and theme information -.md-copyright { - width: 100%; - margin: auto px2rem(12px); - padding: px2rem(8px) 0; - color: var(--md-footer-fg-color--lighter); - font-size: px2rem(12.8px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - width: auto; - } - - // Footer copyright highlight - this is the upper part of the copyright and - // theme information, which will include a darker color than the theme link - &__highlight { - color: var(--md-footer-fg-color--light); - } -} - -// ---------------------------------------------------------------------------- - -// Social links -.md-social { - margin: 0 px2rem(8px); - padding: px2rem(4px) 0 px2rem(12px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - padding: px2rem(12px) 0; - } - - // Footer social link - &__link { - display: inline-block; - width: px2rem(32px); - height: px2rem(32px); - text-align: center; - - // Adjust line-height to match height for correct alignment - &::before { - line-height: 1.9; - } - - // Fill icon with current color - svg { - max-height: px2rem(16px); - vertical-align: -25%; - fill: currentcolor; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_form.scss b/src/assets/stylesheets/main/layout/_form.scss @@ -1,83 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Form button - .md-button { - display: inline-block; - padding: px2em(10px) px2em(32px); - color: var(--md-primary-fg-color); - font-weight: 700; - border: px2rem(2px) solid currentcolor; - border-radius: px2rem(2px); - cursor: pointer; - transition: - color 125ms, - background-color 125ms, - border-color 125ms; - - // Primary button - &--primary { - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - border-color: var(--md-primary-fg-color); - } - - // Button on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - } - - // Form input - .md-input { - height: px2rem(36px); - padding: 0 px2rem(12px); - font-size: px2rem(16px); - border-bottom: px2rem(2px) solid var(--md-default-fg-color--lighter); - border-start-start-radius: px2rem(2px); - border-start-end-radius: px2rem(2px); - box-shadow: var(--md-shadow-z1); - transition: - border 250ms, - box-shadow 250ms; - - // Input on focus/hover - &:is(:focus, :hover) { - border-bottom-color: var(--md-accent-fg-color); - box-shadow: var(--md-shadow-z2); - } - - // Stretch to full width - &--stretch { - width: 100%; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_header.scss b/src/assets/stylesheets/main/layout/_header.scss @@ -1,262 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Header - by default, the header will be sticky and stay always on top of the -// viewport. If this behavior is not desired, just set `position: static`. -.md-header { - position: sticky; - top: 0; - inset-inline: 0; - z-index: 4; - display: block; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - // Hack: reduce jitter by adding a transparent box shadow of the same size - // so the size of the layer doesn't change during animation - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0); - - // [print]: Hide header - @media print { - display: none; - } - - // Header is hidden - &[hidden] { - transform: translateY(-100%); - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - box-shadow 250ms; - } - - // Header in shadow state, i.e. shadow is visible - &--shadow { - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0.1), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2); - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - box-shadow 250ms; - } - - // Header wrapper - &__inner { - display: flex; - align-items: center; - padding: 0 px2rem(4px); - } - - // Header button - &__button { - position: relative; - z-index: 1; - margin: px2rem(4px); - padding: px2rem(8px); - color: currentcolor; - vertical-align: middle; - outline-color: var(--md-accent-fg-color); - cursor: pointer; - transition: opacity 250ms; - - // Button on hover - &:hover { - opacity: 0.7; - } - - // Header button is visible - &:not([hidden]) { - display: inline-block; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - margin: px2rem(4px); - padding: px2rem(8px); - - // [tablet -]: Hide button - @include break-to-device(tablet) { - display: none; - } - - // Image or icon - :is(img, svg) { - display: block; - width: auto; - height: px2rem(24px); - fill: currentcolor; - } - } - - // Button for search - &[for="__search"] { - - // [tablet landscape +]: Hide button - @include break-from-device(tablet landscape) { - display: none; - } - - // [no-js]: Hide button - .no-js & { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & svg { - transform: scaleX(-1); - } - } - - // Button for drawer - &[for="__drawer"] { - - // [screen +]: Hide button - @include break-from-device(screen) { - display: none; - } - } - } - - // Header topic - &__topic { - position: absolute; - display: flex; - max-width: 100%; - white-space: nowrap; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Second header topic - title of the current page - & + & { - z-index: -1; - transform: translateX(px2rem(25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-25px)); - } - } - - // Adjust font weight of site title - &:first-child { - font-weight: 700; - } - } - - // Header title - &__title { - flex-grow: 1; - height: px2rem(48px); - margin-inline-end: px2rem(8px); - margin-inline-start: px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - - // Header title in active state, i.e. page title is visible - &--active .md-header__topic { - z-index: -1; - transform: translateX(px2rem(-25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(25px)); - } - - // Second header topic - title of the current page - + .md-header__topic { - z-index: 0; - transform: translateX(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - pointer-events: initial; - } - } - - // Add ellipsis in case of overflowing text - > .md-header__ellipsis { - position: relative; - width: 100%; - height: 100%; - } - } - - // Header option - &__option { - display: flex; - flex-shrink: 0; - max-width: 100%; - white-space: nowrap; - transition: - max-width 0ms 250ms, - opacity 250ms 250ms; - - // Hide toggle when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-width: 0; - opacity: 0; - transition: - max-width 0ms, - opacity 0ms; - } - } - - // Repository information container - &__source { - display: none; - - // [tablet landscape +]: Show repository information - @include break-from-device(tablet landscape) { - display: block; - width: px2rem(234px); - max-width: px2rem(234px); - margin-inline-start: px2rem(20px); - } - - // [screen +]: Adjust spacing of search bar - @include break-from-device(screen) { - margin-inline-start: px2rem(28px); - } - } -} diff --git a/src/assets/stylesheets/main/layout/_nav.scss b/src/assets/stylesheets/main/layout/_nav.scss @@ -1,642 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Navigation variables -:root { - --md-nav-icon--prev: svg-load("material/arrow-left.svg"); - --md-nav-icon--next: svg-load("material/chevron-right.svg"); - --md-toc-icon: svg-load("material/table-of-contents.svg"); -} - -// ---------------------------------------------------------------------------- - -// Navigation -.md-nav { - font-size: px2rem(14px); - line-height: 1.3; - - // Navigation title - &__title { - display: block; - padding: 0 px2rem(12px); - overflow: hidden; - font-weight: 700; - text-overflow: ellipsis; - - // Navigaton button - .md-nav__button { - display: none; - - // Stretch images based on height, as it's the smaller dimension - img { - width: auto; - height: 100%; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - - // Image or icon - :is(img, svg) { - display: block; - width: auto; - max-width: 100%; - height: px2rem(48px); - object-fit: contain; - fill: currentcolor; - } - } - } - } - - // Navigation list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Navigation item - &__item { - padding: 0 px2rem(12px); - - // Navigation item on level 2 - & & { - padding-inline-end: 0; - } - } - - // Navigation link - &__link { - display: flex; - align-items: center; - justify-content: space-between; - margin-top: 0.625em; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - transition: color 125ms; - scroll-snap-align: start; - - // Navigation link that was passed - &--passed { - color: var(--md-default-fg-color--light); - } - - // Active link - .md-nav__item &--active { - color: var(--md-typeset-a-color); - } - - // Stretch section index link to full width - .md-nav__item &--index [href] { - width: 100%; - } - - // Navigation link on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Navigation link for table of contents - .md-nav--primary &[for="__toc"] { - display: none; - - // Table of contents icon - .md-icon::after { - display: block; - width: 100%; - height: 100%; - mask-image: var(--md-toc-icon); - background-color: currentcolor; - } - - // Hide table of contents - ~ .md-nav { - display: none; - } - } - - // Navigation link children (for section indexes) - > * { - display: flex; - cursor: pointer; - } - } - - // Navigation icon - &__icon { - flex-shrink: 0; - } - - // Repository information container - &__source { - display: none; - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Primary and nested navigation - &--primary, - &--primary & { - position: absolute; - top: 0; - inset-inline: 0; - z-index: 1; - display: flex; - flex-direction: column; - height: 100%; - background-color: var(--md-default-bg-color); - } - - // Primary navigation - &--primary { - - // Navigation title and item - :is(.md-nav__title, .md-nav__item) { - font-size: px2rem(16px); - line-height: 1.5; - } - - // Navigation title - .md-nav__title { - position: relative; - height: px2rem(112px); - padding: px2rem(60px) px2rem(16px) px2rem(4px); - color: var(--md-default-fg-color--light); - line-height: px2rem(48px); - white-space: nowrap; - background-color: var(--md-default-fg-color--lightest); - cursor: pointer; - - // Navigation icon - .md-nav__icon { - position: absolute; - top: px2rem(8px); - inset-inline-start: px2rem(8px); - display: block; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(4px); - - // Navigation icon in link to previous level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentcolor; - mask-image: var(--md-nav-icon--prev); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - - // Navigation list - ~ .md-nav__list { - overflow-y: auto; - background-color: var(--md-default-bg-color); - box-shadow: - 0 px2rem(1px) 0 var(--md-default-fg-color--lightest) inset; - scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Omit border on first child - > :first-child { - border-top: 0; - } - } - - // Top-level navigation title - &[for="__drawer"] { - color: var(--md-primary-bg-color); - font-weight: 700; - background-color: var(--md-primary-fg-color); - } - - // Button with logo, pointing to `config.site_url` - .md-logo { - position: absolute; - top: px2rem(4px); - inset-inline: px2rem(4px); - display: block; - margin: px2rem(4px); - padding: px2rem(8px); - } - } - - // Navigation list - .md-nav__list { - flex: 1; - } - - // Navigation item - .md-nav__item { - padding: 0; - border-top: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Navigation link in active navigation - &--active > .md-nav__link { - color: var(--md-typeset-a-color); - - // Navigation link on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - } - } - - // Navigation link - .md-nav__link { - margin-top: 0; - padding: px2rem(12px) px2rem(16px); - - // Navigation icon - .md-nav__icon { - width: px2rem(24px); - height: px2rem(24px); - margin-inline-end: px2rem(-4px); - font-size: px2rem(24px); - - // Navigation icon in link to next level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentcolor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - } - - // Flip icon vertically - .md-nav__icon { - - // Adjust for right-to-left languages - [dir="rtl"] &::after { - transform: scale(-1); - } - } - - // Table of contents contained in primary navigation - .md-nav--secondary { - - // Navigation on level 2-6 - .md-nav { - position: static; - background-color: transparent; - - // Navigation link on level 3 - .md-nav__link { - padding-inline-start: px2rem(28px); - } - - // Navigation link on level 4 - .md-nav .md-nav__link { - padding-inline-start: px2rem(40px); - } - - // Navigation link on level 5 - .md-nav .md-nav .md-nav__link { - padding-inline-start: px2rem(52px); - } - - // Navigation link on level 6 - .md-nav .md-nav .md-nav .md-nav__link { - padding-inline-start: px2rem(64px); - } - } - } - } - - // Table of contents - &--secondary { - background-color: transparent; - } - - // Toggle for nested navigation - &__toggle ~ & { - display: flex; - transform: translateX(100%); - opacity: 0; - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - opacity 125ms 50ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(-100%); - } - } - - // Show nested navigation when toggle is active - &__toggle:checked ~ & { - transform: translateX(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms 125ms; - - // Navigation list - > .md-nav__list { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - } - } - } - - // [tablet portrait -]: Layered navigation with table of contents - @include break-to-device(tablet portrait) { - - // Show link to table of contents - &--primary &__link[for="__toc"] { - display: flex; - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - - // Repository information container - &__source { - display: block; - padding: 0 px2rem(4px); - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color--dark); - } - } - - // [tablet landscape]: Layered navigation with table of contents - @include break-at-device(tablet landscape) { - - // Show link to integrated table of contents - &--integrated &__link[for="__toc"] { - display: flex; - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - } - - // [tablet landscape +]: Tree-like table of contents - @include break-from-device(tablet landscape) { - - // Navigation title - &--secondary &__title { - - // Adjust snapping behavior - &[for="__toc"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - } - - // [screen +]: Tree-like navigation - @include break-from-device(screen) { - transition: max-height 250ms cubic-bezier(0.86, 0, 0.07, 1); - - // Navigation title - &--primary &__title { - - // Adjust snapping behavior - &[for="__drawer"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - - // Hide toggle for nested navigation - &__toggle ~ & { - display: none; - } - - // Show nested navigation when toggle is active or indeterminate - &__toggle:is(:checked, :indeterminate) ~ & { - display: block; - } - - // Hide navigation title in nested navigation - &__item--nested > & > &__title { - display: none; - } - - // Navigation section - &__item--section { - display: block; - margin: 1.25em 0; - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Show navigation link as title - > .md-nav__link { - font-weight: 700; - pointer-events: none; - - // Make navigation link clickable - &--index [href] { - pointer-events: initial; - } - - // Hide naviation icon - .md-nav__icon { - display: none; - } - } - - // Navigation - > .md-nav { - display: block; - - // Adjust spacing on next level item - > .md-nav__list > .md-nav__item { - padding: 0; - } - } - } - - // Navigation icon - &__icon { - float: right; - width: px2rem(18px); - height: px2rem(18px); - border-radius: 100%; - transition: - background-color 250ms, - transform 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - transform: rotate(180deg); - } - - // Navigation icon on hover - &:hover { - background-color: var(--md-accent-fg-color--transparent); - } - - // Navigation icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - vertical-align: px2rem(-2px); - background-color: currentcolor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Navigation icon - rotate icon when toggle is active or indeterminate - .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link &, - .md-nav__item--nested .md-nav__toggle:indeterminate ~ .md-nav__link & { - transform: rotate(90deg); - } - } - - // Modifier for when navigation tabs are rendered - &--lifted { - - // Hide nested level 0 navigation items and site title - > .md-nav__list > .md-nav__item--nested, - > .md-nav__title { - display: none; - } - - // Hide level 0 navigation items - > .md-nav__list > .md-nav__item { - display: none; - - // Active parent navigation item - &--active { - display: block; - padding: 0; - - // Show navigation link as title - > .md-nav__link { - margin-top: 0; - padding: 0 px2rem(12px); - font-weight: 700; - pointer-events: none; - - // Make navigation link clickable - &--index [href] { - pointer-events: initial; - } - - // Hide naviation icon - .md-nav__icon { - display: none; - } - } - } - } - - // Hack: Always show active navigation tab on breakpoint screen, despite - // of checkbox being checked or not. Fixes #1655. - .md-nav[data-md-level="1"] { - display: block; - - // Adjust spacing for level 1 navigation items - > .md-nav__list > .md-nav__item { - padding-inline-end: px2rem(12px); - } - } - } - - // Modifier for when table of contents is rendered in primary navigation - &--integrated > .md-nav__list > .md-nav__item--active { - - // Add spacing to container for non-nested navigation items - &:not(.md-nav__item--nested) { - padding: 0 px2rem(12px); - - // Remove padding as it's given by container - > .md-nav__link { - padding: 0; - } - } - - // Show integrated table of contents - .md-nav--secondary { - display: block; - margin-bottom: 1.25em; - border-inline-start: px2rem(1px) solid var(--md-primary-fg-color); - - // Hide table of contents title - > .md-nav__title { - display: none; - } - } - } - } -} diff --git a/src/assets/stylesheets/main/layout/_search.scss b/src/assets/stylesheets/main/layout/_search.scss @@ -1,713 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Search variables -:root { - --md-search-result-icon: svg-load("material/file-search-outline.svg"); -} - -// ---------------------------------------------------------------------------- - -// Search -.md-search { - position: relative; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding: px2rem(4px) 0; - } - - // [no-js]: Hide search - .no-js & { - display: none; - } - - // Search overlay - &__overlay { - z-index: 1; - opacity: 0; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: absolute; - top: px2rem(-20px); - inset-inline-start: px2rem(-44px); - width: px2rem(40px); - height: px2rem(40px); - overflow: hidden; - background-color: var(--md-default-bg-color); - border-radius: px2rem(20px); - transform-origin: center; - transition: - transform 300ms 100ms, - opacity 200ms 200ms; - pointer-events: none; - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: - transform 400ms, - opacity 100ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: fixed; - top: 0; - inset-inline-start: 0; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - cursor: pointer; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - // Hack: when the header is translated upon scrolling, a new layer is - // induced, which means that the height will now refer to the height of - // the header, albeit positioning is fixed. This should be mitigated - // in all cases when setting the height to 2x the viewport. - height: 200vh; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [mobile portrait -]: Scale up 45 times - @include break-to-device(mobile portrait) { - transform: scale(45); - } - - // [mobile landscape]: Scale up 60 times - @include break-at-device(mobile landscape) { - transform: scale(60); - } - - // [tablet portrait]: Scale up 75 times - @include break-at-device(tablet portrait) { - transform: scale(75); - } - } - } - - // Search wrapper - &__inner { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: fixed; - top: 0; - inset-inline-start: 0; - z-index: 2; - width: 0; - height: 0; - overflow: hidden; - transform: translateX(5%); - opacity: 0; - transition: - width 0ms 300ms, - height 0ms 300ms, - transform 150ms 150ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 150ms 150ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(-5%); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - height: 100%; - transform: translateX(0); - opacity: 1; - transition: - width 0ms 0ms, - height 0ms 0ms, - transform 150ms 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms 150ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: relative; - float: right; - width: px2rem(234px); - padding: px2rem(2px) 0; - transition: width 250ms cubic-bezier(0.1, 0.7, 0.1, 1); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [tablet landscape]: Omit overlaying header title - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Match width of content area - @include break-from-device(screen) { - width: px2rem(688px); - } - } - } - - // Search form - &__form { - position: relative; - z-index: 2; - height: px2rem(48px); - background-color: var(--md-default-bg-color); - box-shadow: 0 0 px2rem(12px) transparent; - transition: - color 250ms, - background-color 250ms; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - height: px2rem(36px); - background-color: hsla(0, 0%, 0%, 0.26); - border-radius: px2rem(2px); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.12); - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px) px2rem(2px) 0 0; - box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07); - } - } - - // Search input - &__input { - position: relative; - z-index: 2; - width: 100%; - height: 100%; - padding-inline: px2rem(72px) px2rem(44px); - font-size: px2rem(18px); - text-overflow: ellipsis; - background: transparent; - - // Search placeholder - &::placeholder { - transition: color 250ms; - } - - // Search icon and placeholder - ~ .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - - // Remove the "x" rendered by Internet Explorer - &::-ms-clear { - display: none; - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - width: 100%; - height: px2rem(48px); - font-size: px2rem(18px); - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-inline-start: px2rem(44px); - color: inherit; - font-size: px2rem(16px); - - // Search placeholder - &::placeholder { - color: var(--md-primary-bg-color--light); - } - - // Search icon - + .md-search__icon { - color: var(--md-primary-bg-color); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - text-overflow: clip; - - // Search icon and placeholder - + .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - } - } - } - - // Search icon - &__icon { - display: inline-block; - width: px2rem(24px); - height: px2rem(24px); - cursor: pointer; - transition: - color 250ms, - opacity 250ms; - - // Search icon on hover - &:hover { - opacity: 0.7; - } - - // Search focus button - &[for="__search"] { - position: absolute; - top: px2rem(6px); - inset-inline-start: px2rem(10px); - z-index: 2; - - // Adjust for right-to-left languages - [dir="rtl"] & svg { - transform: scaleX(-1); - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - inset-inline-start: px2rem(16px); - - // Hide the magnifying glass - svg:first-child { - display: none; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - pointer-events: none; - - // Hide the back arrow - svg:last-child { - display: none; - } - } - } - } - - // Search options - &__options { - position: absolute; - top: px2rem(6px); - inset-inline-end: px2rem(10px); - z-index: 2; - pointer-events: none; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - inset-inline-end: px2rem(16px); - } - - // Search option buttons - > * { - margin-inline-start: px2rem(4px); - color: var(--md-default-fg-color--light); - transform: scale(0.75); - opacity: 0; - transition: - transform 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Show reset button when search is active and input non-empty - [data-md-toggle="search"]:checked ~ .md-header - .md-search__input:valid ~ & { - transform: scale(1); - opacity: 1; - pointer-events: initial; - - // Search focus icon - &:hover { - opacity: 0.7; - } - } - } - } - - // Search suggestions - &__suggest { - position: absolute; - top: 0; - display: flex; - align-items: center; - width: 100%; - height: 100%; - padding-inline: px2rem(72px) px2rem(44px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(18px); - white-space: nowrap; - opacity: 0; - transition: opacity 50ms; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-inline-start: px2rem(44px); - font-size: px2rem(16px); - } - - // Show suggestions when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: opacity 300ms 100ms; - } - } - - // Search output - &__output { - position: absolute; - z-index: 1; - width: 100%; - overflow: hidden; - border-end-start-radius: px2rem(2px); - border-end-end-radius: px2rem(2px); - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(48px); - bottom: 0; - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - top: px2rem(38px); - opacity: 0; - transition: opacity 400ms; - - // Show output when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - box-shadow: var(--md-shadow-z3); - opacity: 1; - } - } - } - - // Search scroll wrapper - &__scrollwrap { - height: 100%; - overflow-y: auto; - background-color: var(--md-default-bg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 88+ has weird overscroll behavior. Overall, scroll snapping - // seems to be something that is not ready for prime time on some browsers. - // scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Mitigiate excessive repaints on non-retina devices - @media (max-resolution: 1dppx) { - transform: translateZ(0); - } - - // [tablet landscape]: Set fixed width to omit unnecessary reflow - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Set fixed width to omit unnecessary reflow - @include break-from-device(screen) { - width: px2rem(688px); - } - - // [tablet landscape +]: Limit height to viewport - @include break-from-device(tablet landscape) { - max-height: 0; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Show scroll wrapper when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-height: 75vh; - } - - // Search scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } -} - -// Search result -.md-search-result { - color: var(--md-default-fg-color); - word-break: break-word; - - // Search result metadata - &__meta { - padding: 0 px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: px2rem(36px); - background-color: var(--md-default-fg-color--lightest); - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-inline-start: px2rem(44px); - } - } - - // Search result list - &__list { - margin: 0; - padding: 0; - list-style: none; - // Hack: omit accidental text selection on fast toggle of more button - user-select: none; - } - - // Search result item - &__item { - box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest); - - // Omit border on first child - &:first-child { - box-shadow: none; - } - } - - // Search result link - &__link { - display: block; - outline: none; - transition: background-color 250ms; - scroll-snap-align: start; - - // Search result link on focus/hover - &:is(:focus, :hover) { - background-color: var(--md-accent-fg-color--transparent); - } - - // Adjust spacing on last child of last link - &:last-child p:last-child { - margin-bottom: px2rem(12px); - } - } - - // Search result more link - &__more summary { - display: block; - padding: px2em(12px) px2rem(16px); - color: var(--md-typeset-a-color); - font-size: px2rem(12.8px); - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-inline-start: px2rem(44px); - } - - // Search result more link on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - - // Hide native details marker - modern - &::marker { - display: none; - } - - // Hide native details marker - legacy, must be split into a seprate rule, - // so older browsers don't consider the selector list as invalid - &::-webkit-details-marker { - display: none; - } - - // Adjust transparency of less relevant results - ~ * > * { - opacity: 0.65; - } - } - - // Search result article - &__article { - position: relative; - padding: 0 px2rem(16px); - overflow: hidden; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-inline-start: px2rem(44px); - } - - // Search result article document - &--document { - - // Search result title - .md-search-result__title { - margin: px2rem(11px) 0; - font-weight: 400; - font-size: px2rem(16px); - line-height: 1.4; - } - } - } - - // Search result icon - &__icon { - position: absolute; - inset-inline-start: 0; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(10px); - color: var(--md-default-fg-color--light); - - // [tablet portrait -]: Hide icon - @include break-to-device(tablet portrait) { - display: none; - } - - // Search result icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - background-color: currentcolor; - mask-image: var(--md-search-result-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: scaleX(-1); - } - } - } - - // Search result title - &__title { - margin: 0.5em 0; - font-weight: 700; - font-size: px2rem(12.8px); - line-height: 1.6; - } - - // Search result teaser - &__teaser { - display: -webkit-box; - max-height: px2rem(40px); - margin: 0.5em 0; - overflow: hidden; - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: 1.6; - text-overflow: ellipsis; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - - // [mobile -]: Adjust number of lines - @include break-to-device(mobile) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // [tablet landscape]: Adjust number of lines - @include break-at-device(tablet landscape) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // Search term highlighting - mark { - text-decoration: underline; - background-color: transparent; - } - } - - // Search result terms - &__terms { - margin: 0.5em 0; - font-size: px2rem(12.8px); - font-style: italic; - } - - // Search term highlighting - mark { - color: var(--md-accent-fg-color); - background-color: transparent; - } -} diff --git a/src/assets/stylesheets/main/layout/_select.scss b/src/assets/stylesheets/main/layout/_select.scss @@ -1,115 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Selection -.md-select { - position: relative; - z-index: 1; - - // Selection tooltip - &__inner { - position: absolute; - top: calc(100% - #{px2rem(4px)}); - left: 50%; - max-height: 0; - margin-top: px2rem(4px); - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z2); - transform: translate3d(-50%, px2rem(6px), 0); - opacity: 0; - transition: - transform 250ms 375ms, - opacity 250ms 250ms, - max-height 0ms 500ms; - - // Selection bubble on parent focus/hover - .md-select:is(:focus-within, :hover) & { - max-height: px2rem(200px); - transform: translate3d(-50%, 0, 0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms, - max-height 0ms; - } - - // Selection bubble handle - &::after { - position: absolute; - top: 0; - left: 50%; - width: 0; - height: 0; - margin-top: px2rem(-4px); - margin-left: px2rem(-4px); - border: px2rem(4px) solid transparent; - border-top: 0; - border-bottom-color: var(--md-default-bg-color); - content: ""; - } - } - - // Selection list - &__list { - max-height: inherit; - margin: 0; - padding: 0; - overflow: auto; - font-size: px2rem(16px); - list-style-type: none; - border-radius: px2rem(2px); - } - - // Selection item - &__item { - line-height: px2rem(36px); - } - - // Selection link - &__link { - display: block; - width: 100%; - padding-inline: px2rem(12px) px2rem(24px); - outline: none; - cursor: pointer; - transition: - background-color 250ms, - color 250ms; - scroll-snap-align: start; - - // Link on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/src/assets/stylesheets/main/layout/_sidebar.scss b/src/assets/stylesheets/main/layout/_sidebar.scss @@ -1,181 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Sidebar -.md-sidebar { - position: sticky; - top: px2rem(48px); - flex-shrink: 0; - align-self: flex-start; - width: px2rem(242px); - padding: px2rem(24px) 0; - - // [print]: Hide sidebar - @media print { - display: none; - } - - // [tablet -]: Show navigation as drawer - @include break-to-device(tablet) { - - // Primary sidebar with navigation - &--primary { - position: fixed; - top: 0; - inset-inline-start: px2rem(-242px); - z-index: 5; - display: block; - width: px2rem(242px); - height: 100%; - background-color: var(--md-default-bg-color); - transform: translateX(0); - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - box-shadow 250ms; - - // Show sidebar when drawer is active - [data-md-toggle="drawer"]:checked ~ .md-container & { - box-shadow: var(--md-shadow-z3); - transform: translateX(px2rem(242px)); - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-242px)); - } - } - - // Stretch scroll wrapper for primary sidebar - .md-sidebar__scrollwrap { - position: absolute; - inset: 0; - margin: 0; - scroll-snap-type: none; - overflow: hidden; - } - } - } - - // [screen +]: Show navigation as sidebar - @include break-from-device(screen) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - } - - // Secondary sidebar with table of contents - &--secondary { - display: none; - order: 2; - - // [tablet landscape +]: Show table of contents as sidebar - @include break-from-device(tablet landscape) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - - // Sidebar is visible - &:not([hidden]) { - display: block; - } - - // Ensure smooth scrolling on iOS - .md-sidebar__scrollwrap { - touch-action: pan-y; - } - } - } - - // Sidebar scroll wrapper - &__scrollwrap { - margin: 0 px2rem(4px); - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 81+ exhibits a strange bug, where it scrolls the container - // to the bottom if `scroll-snap-type` is set on the initial render. For - // this reason, we disable scroll snapping until this is resolved (#1667). - // scroll-snap-type: y mandatory; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Sidebar scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } -} - -// [tablet -]: Show overlay on active drawer -@include break-to-device(tablet) { - - // Drawer overlay - .md-overlay { - position: fixed; - top: 0; - z-index: 5; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - opacity: 0; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Show overlay when drawer is active - [data-md-toggle="drawer"]:checked ~ & { - width: 100%; - height: 100%; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_source.scss b/src/assets/stylesheets/main/layout/_source.scss @@ -1,181 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Show repository facts -@keyframes facts { - 0% { - height: 0; - } - - 100% { - height: px2rem(13px); - } -} - -// Show repository fact -@keyframes fact { - 0% { - transform: translateY(100%); - opacity: 0; - } - - 50% { - opacity: 0; - } - - 100% { - transform: translateY(0%); - opacity: 1; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Repository information variables -:root { - --md-source-forks-icon: svg-load("octicons/repo-forked-16.svg"); - --md-source-repositories-icon: svg-load("octicons/repo-16.svg"); - --md-source-stars-icon: svg-load("octicons/star-16.svg"); - --md-source-version-icon: svg-load("octicons/tag-16.svg"); -} - -// ---------------------------------------------------------------------------- - -// Repository information -.md-source { - display: block; - font-size: px2rem(13px); - line-height: 1.2; - white-space: nowrap; - outline-color: var(--md-accent-fg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - transition: opacity 250ms; - - // Repository information on hover - &:hover { - opacity: 0.7; - } - - // Repository icon - &__icon { - display: inline-block; - width: px2rem(40px); - height: px2rem(48px); - vertical-align: middle; - - // Align with margin only (as opposed to normal button alignment) - svg { - margin-top: px2rem(12px); - margin-inline-start: px2rem(12px); - } - - // Adjust spacing if icon is present - + .md-source__repository { - margin-inline-start: px2rem(-40px); - padding-inline-start: px2rem(40px); - } - } - - // Repository name - &__repository { - display: inline-block; - max-width: calc(100% - #{px2rem(24px)}); - margin-inline-start: px2rem(12px); - overflow: hidden; - text-overflow: ellipsis; - vertical-align: middle; - } - - // Repository facts - &__facts { - display: flex; - gap: px2rem(8px); - width: 100%; - margin: px2rem(2px) 0 0; - padding: 0; - overflow: hidden; - font-size: px2rem(11px); - list-style-type: none; - opacity: 0.75; - - // Show after the data was loaded - .md-source__repository--active & { - animation: facts 250ms ease-in; - } - } - - // Repository fact - &__fact { - overflow: hidden; - text-overflow: ellipsis; - - // Show after the data was loaded - .md-source__repository--active & { - animation: fact 400ms ease-out; - } - - // Repository fact icon - &::before { - display: inline-block; - width: px2rem(12px); - height: px2rem(12px); - margin-inline-end: px2rem(2px); - vertical-align: text-top; - background-color: currentcolor; - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Adjust spacing for 2nd+ fact - &:nth-child(1n+2) { - flex-shrink: 0; - } - - // Repository fact: version - &--version::before { - mask-image: var(--md-source-version-icon); - } - - // Repository fact: stars - &--stars::before { - mask-image: var(--md-source-stars-icon); - } - - // Repository fact: forks - &--forks::before { - mask-image: var(--md-source-forks-icon); - } - - // Repository fact: repositories - &--repositories::before { - mask-image: var(--md-source-repositories-icon); - } - } -} diff --git a/src/assets/stylesheets/main/layout/_tabs.scss b/src/assets/stylesheets/main/layout/_tabs.scss @@ -1,110 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Navigation tabs -.md-tabs { - // Must be higher than the z-index of the back-to-top button, or the button - // will overlay the navigation tabs bar when scrolling up fast. - z-index: 3; - display: block; - width: 100%; - overflow: auto; - color: var(--md-primary-bg-color); - line-height: 1.3; - background-color: var(--md-primary-fg-color); - - // [print]: Hide tabs - @media print { - display: none; - } - - // [tablet -]: Hide tabs - @include break-to-device(tablet) { - display: none; - } - - // Navigation tabs are hidden - &[hidden] { - pointer-events: none; - } - - // Navigation tabs list - &__list { - margin: 0; - margin-inline-start: px2rem(4px); - padding: 0; - white-space: nowrap; - list-style: none; - contain: content; - } - - // Navigation tabs item - &__item { - display: inline-block; - height: px2rem(48px); - padding-inline: px2rem(12px); - } - - // Navigation tabs link - could be defined as block elements and aligned via - // line height, but this would imply more repaints when scrolling - &__link { - display: block; - margin-top: px2rem(16px); - font-size: px2rem(14px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - // Hack: save a repaint when tabs are appearing on scrolling up - backface-visibility: hidden; - opacity: 0.7; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms; - - // Active link and link on focus/hover - &--active, - &:is(:focus, :hover) { - color: inherit; - opacity: 1; - } - - // Delay transitions by a small amount - @for $i from 2 through 16 { - .md-tabs__item:nth-child(#{$i}) & { - transition-delay: 20ms * ($i - 1); - } - } - - // Hide tabs upon scrolling - disable transition to minimizes repaints - // while scrolling down, while scrolling up seems to be okay - .md-tabs[hidden] & { - transform: translateY(50%); - opacity: 0; - transition: - transform 0ms 100ms, - opacity 100ms; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_tag.scss b/src/assets/stylesheets/main/layout/_tag.scss @@ -1,65 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Tag list -.md-tags { - margin-bottom: px2em(12px); -} - -// Tag -.md-tag { - display: inline-block; - margin-inline-end: 0.5em; - margin-bottom: 0.5em; - padding: px2em(4px, 12.8px) px2em(12px, 12.8px); - font-weight: 700; - font-size: px2rem(12.8px); - line-height: 1.6; - background: var(--md-default-fg-color--lightest); - border-radius: px2rem(8px); - - // Linked tag - &[href] { - color: inherit; - outline: none; - -webkit-tap-highlight-color: transparent; - transition: - color 125ms, - background-color 125ms; - - // Linked tag on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - } - } - - // Tag inside headline - [id] > & { - vertical-align: text-top; - } -} diff --git a/src/assets/stylesheets/main/layout/_tooltip.scss b/src/assets/stylesheets/main/layout/_tooltip.scss @@ -1,253 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Continuous pulse animation -@keyframes pulse { - 0% { - box-shadow: 0 0 0 0 var(--md-default-fg-color--lightest); - transform: scale(0.95); - } - - 75% { - box-shadow: 0 0 0 px2em(10px) transparent; - transform: scale(1); - } - - 100% { - box-shadow: 0 0 0 0 transparent; - transform: scale(0.95); - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Tooltip variables -:root { - --md-tooltip-width: #{px2rem(400px)}; -} - -// ---------------------------------------------------------------------------- - -// Tooltip -.md-tooltip { - position: absolute; - top: var(--md-tooltip-y); - left: - clamp( - var(--md-tooltip-0, #{px2rem(0px)}) + #{px2rem(16px)}, - var(--md-tooltip-x), - 100vw + - var(--md-tooltip-0, #{px2rem(0px)}) + #{px2rem(16px)} - - var(--md-tooltip-width) - - 2 * #{px2rem(16px)} - ); - // Hack: set an explicit `z-index` so we can transition it to ensure that any - // following elements are not overlaying the tooltip during the transition. - z-index: 0; - width: var(--md-tooltip-width); - max-width: calc(100vw - 2 * #{px2rem(16px)}); - max-height: 0; - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z2); - transform: translateY(px2rem(-8px)); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - opacity: 0; - transition: - transform 0ms 250ms, - opacity 250ms, - max-height 0ms 250ms, - z-index 250ms; - - // Tooltip on parent focus - :focus-within > & { - max-height: 1000%; - transform: translateY(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms, - max-height 250ms, - z-index 0ms; - } - - // Show outline for keyboard devices - .focus-visible > & { - outline: var(--md-accent-fg-color) auto; - } - - // Tooltip wrapper - &__inner { - padding: px2rem(16px); - font-size: px2rem(12.8px); - - // Adjust spacing on first child - &.md-typeset > :first-child { - margin-top: 0; - } - - // Adjust spacing on last child - &.md-typeset > :last-child { - margin-bottom: 0; - } - } -} - -// ---------------------------------------------------------------------------- - -// Annotation -.md-annotation { - white-space: normal; - outline: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - direction: rtl; - } - - // Annotation is not hidden (e.g. when copying) - &:not([hidden]) { - display: inline-block; - // Hack: ensure that the line height doesn't exceed the line height of the - // hosting line, because it will lead to dancing pixels. - line-height: 1.325; - } - - // Promote children to top on focus - &:focus-within > * { - z-index: 2; - } - - // Annotation wrapper (= tooltip) - &__inner { - top: calc(var(--md-tooltip-y) + 1.2ch); - font-family: var(--md-text-font-family); - - // Annotation tooltip when not focused - :not(:focus-within) > & { - user-select: none; - pointer-events: none; - } - } - - // Annotation index - &__index { - position: relative; - z-index: 0; - margin: 0 1ch; - color: hsla(0, 0%, 100%, 1); - cursor: pointer; - transition: z-index 250ms; - user-select: none; - - // Annotation marker – the marker must be positioned absolutely behind - // the index, because it shouldn't impact the rendering of a code block. - // Otherwise, small rounding differences in browsers can sometimes mess up - // alignment of text following an annotation. - &::after { - position: absolute; - left: -0.126em; - z-index: -1; - // Hack: the first property is used as a fallback for older browsers - // which don't support the min/max/clamp math functions. - width: calc(100% + 1.2ch); - width: max(2.2ch, 100% + 1.2ch); - height: 2.2ch; - margin: 0 -0.4ch; - padding: 0 0.4ch; - background-color: var(--md-default-fg-color--lighter); - border-radius: 2ch; - transition: - color 250ms, - background-color 250ms; - content: ""; - - // [reduced motion]: Disable animation - @media not all and (prefers-reduced-motion) { - - // Annotation marker is visible - [data-md-visible] > & { - animation: pulse 2000ms infinite; - } - } - - // Annotation marker on focus/hover - :is(:focus-within, :hover) > & { - background-color: var(--md-accent-fg-color); - } - - // Annotation marker on focus - :focus-within > & { - transition: - color 250ms, - background-color 250ms; - animation: none; - } - } - - // Annotation marker - [data-md-annotation-id] { - display: inline-block; - line-height: 90%; - - // Annotation marker content - &::before { - display: inline-block; - padding-bottom: 0.1em; - vertical-align: 0.065em; - transform: scale(1.15); - transition: transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1); - content: attr(data-md-annotation-id); - - // [not print]: if we're not in print mode, show a `+` sign instead of - // the original numbers, as context is already given by the position. - @media not print { - content: "+"; - - // Annotation marker content on focus - :focus-within > & { - transform: scale(1.25) rotate(45deg); - } - } - } - } - - // Annotation index on focus/hover - :is(:focus-within, :hover) > & { - color: var(--md-accent-bg-color); - } - - // Annotation index on focus - :focus-within > & { - transition: none; - animation: none; - } - } -} diff --git a/src/assets/stylesheets/main/layout/_top.scss b/src/assets/stylesheets/main/layout/_top.scss @@ -1,82 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Back-to-top button -.md-top { - position: fixed; - top: px2rem(48px + 16px); - z-index: 2; - display: block; - margin-inline-start: 50%; - padding: px2rem(8px) px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(14px); - background-color: var(--md-default-bg-color); - border-radius: px2rem(32px); - outline: none; - box-shadow: var(--md-shadow-z2); - transform: translate(-50%, 0); - transition: - color 125ms, - background-color 125ms, - transform 125ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms; - - // [print]: Hide back-to-top button - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translate(50%, 0); - } - - // Back-to-top button is hidden - &[hidden] { - transform: translate(-50%, px2rem(4px)); - opacity: 0; - transition-duration: 0ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translate(50%, px2rem(4px)); - } - } - - // Back-to-top button on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - } - - // Inline icon - svg { - display: inline-block; - vertical-align: -0.5em; - } -} diff --git a/src/assets/stylesheets/main/layout/_version.scss b/src/assets/stylesheets/main/layout/_version.scss @@ -1,149 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// See https://github.com/squidfunk/mkdocs-material/issues/2429 -@keyframes hoverfix { - 0% { - pointer-events: none; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Version selection variables -:root { - --md-version-icon: svg-load("fontawesome/solid/caret-down.svg"); -} - -// ---------------------------------------------------------------------------- - -// Version selection -.md-version { - flex-shrink: 0; - height: px2rem(48px); - font-size: px2rem(16px); - - // Current selection - &__current { - position: relative; - // Hack: in general, we would use `vertical-align` to align the version at - // the bottom with the title, but since the list uses absolute positioning, - // this won't work consistently. Furthermore, we would need to use inline - // positioning to align the links, which looks jagged. - top: px2rem(1px); - margin-inline: px2rem(28px) px2rem(8px); - color: inherit; - outline: none; - cursor: pointer; - - // Version selection icon - &::after { - display: inline-block; - width: px2rem(8px); - height: px2rem(12px); - margin-inline-start: px2rem(8px); - background-color: currentcolor; - mask-image: var(--md-version-icon); - mask-repeat: no-repeat; - content: ""; - } - } - - // Version selection list - &__list { - position: absolute; - top: px2rem(3px); - z-index: 3; - max-height: 0; - margin: px2rem(4px) px2rem(16px); - padding: 0; - overflow: auto; - color: var(--md-default-fg-color); - list-style-type: none; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z2); - opacity: 0; - transition: - max-height 0ms 500ms, - opacity 250ms 250ms; - scroll-snap-type: y mandatory; - - // Version selection list on parent focus/hover - .md-version:is(:focus-within, :hover) & { - max-height: px2rem(200px); - opacity: 1; - transition: - max-height 0ms, - opacity 250ms; - } - - // Fix hover on touch devices - @media (pointer: coarse) { - - // Switch off on hover - .md-version:hover & { - animation: hoverfix 250ms forwards; - } - - // Enable on focus - .md-version:focus-within & { - animation: none; - } - } - } - - // Version selection item - &__item { - line-height: px2rem(36px); - } - - // Version selection link - &__link { - display: block; - width: 100%; - padding-inline: px2rem(12px) px2rem(24px); - white-space: nowrap; - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // Link on focus/hover - &:is(:focus, :hover) { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/src/assets/stylesheets/palette.scss b/src/assets/stylesheets/palette.scss @@ -1,40 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "palette/scheme"; -@import "palette/accent"; -@import "palette/primary"; diff --git a/src/assets/stylesheets/palette/_accent.scss b/src/assets/stylesheets/palette/_accent.scss @@ -1,61 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Define accent colors -@each $name, $color in ( - "red": $clr-red-a400, - "pink": $clr-pink-a400, - "purple": $clr-purple-a200, - "deep-purple": $clr-deep-purple-a200, - "indigo": $clr-indigo-a200, - "blue": $clr-blue-a200, - "light-blue": $clr-light-blue-a700, - "cyan": $clr-cyan-a700, - "teal": $clr-teal-a700, - "green": $clr-green-a700, - "light-green": $clr-light-green-a700, - "lime": $clr-lime-a700, - "yellow": $clr-yellow-a700, - "amber": $clr-amber-a700, - "orange": $clr-orange-a400, - "deep-orange": $clr-deep-orange-a200 -) { - - // Color palette - [data-md-color-accent="#{$name}"] { - --md-accent-fg-color: hsla(#{hex2hsl($color)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($color)}, 0.1); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-accent-bg-color: hsla(0, 0%, 0%, 0.87); - --md-accent-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - } -} diff --git a/src/assets/stylesheets/palette/_primary.scss b/src/assets/stylesheets/palette/_primary.scss @@ -1,193 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -@use "sass:list"; - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Define primary colors -@each $name, $colors in ( - "red": $clr-red-400 $clr-red-300 $clr-red-600, - "pink": $clr-pink-500 $clr-pink-400 $clr-pink-700, - "purple": $clr-purple-400 $clr-purple-300 $clr-purple-600, - "deep-purple": $clr-deep-purple-400 $clr-deep-purple-300 $clr-deep-purple-500, - "indigo": $clr-indigo-500 $clr-indigo-400 $clr-indigo-700, - "blue": $clr-blue-500 $clr-blue-400 $clr-blue-700, - "light-blue": $clr-light-blue-500 $clr-light-blue-400 $clr-light-blue-700, - "cyan": $clr-cyan-500 $clr-cyan-400 $clr-cyan-700, - "teal": $clr-teal-500 $clr-teal-400 $clr-teal-700, - "green": $clr-green-500 $clr-green-400 $clr-green-700, - "light-green": $clr-light-green-500 $clr-light-green-400 $clr-light-green-700, - "lime": $clr-lime-500 $clr-lime-400 $clr-lime-700, - "yellow": $clr-yellow-500 $clr-yellow-400 $clr-yellow-700, - "amber": $clr-amber-500 $clr-amber-400 $clr-amber-700, - "orange": $clr-orange-400 $clr-orange-400 $clr-orange-600, - "deep-orange": $clr-deep-orange-400 $clr-deep-orange-300 $clr-deep-orange-600, - "brown": $clr-brown-500 $clr-brown-400 $clr-brown-700, - "grey": $clr-grey-600 $clr-grey-500 $clr-grey-700, - "blue-grey": $clr-blue-grey-600 $clr-blue-grey-500 $clr-blue-grey-700 -) { - - // Color palette - [data-md-color-primary="#{$name}"] { - --md-primary-fg-color: hsl(#{hex2hsl(list.nth($colors, 1))}); - --md-primary-fg-color--light: hsl(#{hex2hsl(list.nth($colors, 2))}); - --md-primary-fg-color--dark: hsl(#{hex2hsl(list.nth($colors, 3))}); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - - // Typeset color shades - @if index("grey" "blue-grey", $name) { - --md-typeset-a-color: hsl(#{hex2hsl($clr-indigo-500)}); - } - } -} - -// ---------------------------------------------------------------------------- - -// Adjust link colors for light primary colors -@each $name, $color in ( - "light-green": hsl(88, 58%, 43%), - "lime": hsl(66, 88%, 32%), - "yellow": hsl(54, 100%, 36%), - "amber": hsl(45, 100%, 41%), - "orange": hsl(36, 100%, 45%) -) { - [data-md-color-primary="#{$name}"]:not([data-md-color-scheme="slate"]) { - --md-typeset-a-color: #{$color}; - } -} - -// ---------------------------------------------------------------------------- -// Rules: white -// ---------------------------------------------------------------------------- - -// Define primary colors for white -[data-md-color-primary="white"] { - --md-primary-fg-color: hsla(0, 0%, 100%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 0.07); - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - - // Typeset `a` color shades - --md-typeset-a-color: hsl(#{hex2hsl($clr-indigo-500)}); - - // [tablet portrait +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 0%, 0.07); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 0%, 0.32); - } - } - - // Search icon - .md-search__input + .md-search__icon { - color: hsla(0, 0%, 0%, 0.87); - } - } - - // [screen +]: Add bottom border for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - border-bottom: px2rem(1px) solid hsla(0, 0%, 0%, 0.07); - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: black -// ---------------------------------------------------------------------------- - -// Define primary colors for black -[data-md-color-primary="black"] { - --md-primary-fg-color: hsla(0, 0%, 0%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Typeset `a` color shades - --md-typeset-a-color: hsl(#{hex2hsl($clr-indigo-500)}); - - // Header - .md-header { - background-color: hsla(0, 0%, 0%, 1); - } - - // [tablet portrait -]: Layered navigation - @include break-to-device(tablet portrait) { - - // Repository information container - .md-nav__source { - background-color: hsla(0, 0%, 0%, 0.87); - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 100%, 0.12); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.3); - } - } - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Site title in main navigation - html & .md-nav--primary .md-nav__title[for="__drawer"] { - background-color: hsla(0, 0%, 0%, 1); - } - } - - // [screen +]: Set background color for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - background-color: hsla(0, 0%, 0%, 1); - } - } -} diff --git a/src/assets/stylesheets/palette/_scheme.scss b/src/assets/stylesheets/palette/_scheme.scss @@ -1,152 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Only use dark mode on screens -@media screen { - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] { - - // Slate's hue in the range [0,360] - change this variable to alter the tone - // of the theme, e.g. to make it more redish or greenish. This is a slate- - // specific variable, but the same approach may be adapted to custom themes. - --md-hue: 232; - - // Default color shades - --md-default-fg-color: hsla(var(--md-hue), 75%, 95%, 1); - --md-default-fg-color--light: hsla(var(--md-hue), 75%, 90%, 0.62); - --md-default-fg-color--lighter: hsla(var(--md-hue), 75%, 90%, 0.32); - --md-default-fg-color--lightest: hsla(var(--md-hue), 75%, 90%, 0.12); - --md-default-bg-color: hsla(var(--md-hue), 15%, 21%, 1); - --md-default-bg-color--light: hsla(var(--md-hue), 15%, 21%, 0.54); - --md-default-bg-color--lighter: hsla(var(--md-hue), 15%, 21%, 0.26); - --md-default-bg-color--lightest: hsla(var(--md-hue), 15%, 21%, 0.07); - - // Code color shades - --md-code-fg-color: hsla(var(--md-hue), 18%, 86%, 1); - --md-code-bg-color: hsla(var(--md-hue), 15%, 15%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.15); - --md-code-hl-number-color: hsla(6, 74%, 63%, 1); - --md-code-hl-special-color: hsla(340, 83%, 66%, 1); - --md-code-hl-function-color: hsla(291, 57%, 65%, 1); - --md-code-hl-constant-color: hsla(250, 62%, 70%, 1); - --md-code-hl-keyword-color: hsla(219, 66%, 64%, 1); - --md-code-hl-string-color: hsla(150, 58%, 44%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.3); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(var(--md-hue), 15%, 94%, 0.12); - --md-typeset-kbd-accent-color: hsla(var(--md-hue), 15%, 94%, 0.2); - --md-typeset-kbd-border-color: hsla(var(--md-hue), 15%, 14%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(var(--md-hue), 75%, 95%, 0.12); - - // Admonition color shades - --md-admonition-fg-color: var(--md-default-fg-color); - --md-admonition-bg-color: var(--md-default-bg-color); - - // Footer color shades - --md-footer-bg-color: hsla(var(--md-hue), 15%, 12%, 0.87); - --md-footer-bg-color--dark: hsla(var(--md-hue), 15%, 10%, 1); - - // Shadow depth 1 - --md-shadow-z1: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.2), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.1); - - // Shadow depth 2 - --md-shadow-z2: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.3), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.25); - - // Shadow depth 3 - --md-shadow-z3: - 0 #{px2rem(4px)} #{px2rem(10px)} hsla(0, 0%, 0%, 0.4), - 0 0 #{px2rem(1px)} hsla(0, 0%, 0%, 0.35); - - // Hide images for light mode - img[src$="#only-light"], - img[src$="#gh-light-mode-only"] { - display: none; - } - - // Show images for dark mode - img[src$="#only-dark"], - img[src$="#gh-dark-mode-only"] { - display: initial; - } - } - - // -------------------------------------------------------------------------- - - // Adjust link colors for dark primary colors - @each $name, $color in ( - "pink": hsl(340, 81%, 63%), - "purple": hsl(291, 43%, 63%), - "deep-purple": hsl(262, 63%, 70%), - "indigo": hsl(219, 56%, 63%), - "teal": hsl(174, 100%, 40%), - "green": hsl(122, 39%, 60%), - "deep-orange": hsl(14, 100%, 73%), - "brown": hsl(16, 45%, 60%), - - // Set neutral colors to indigo - "grey": hsl(219, 56%, 63%), - "blue-grey": hsl(219, 56%, 63%), - "white": hsl(219, 56%, 63%), - "black": hsl(219, 56%, 63%) - ) { - [data-md-color-scheme="slate"][data-md-color-primary="#{$name}"] { - --md-typeset-a-color: #{$color}; - } - } - - // -------------------------------------------------------------------------- - - // Switching in progress - disable all transitions temporarily - [data-md-color-switching] *, - [data-md-color-switching] *::before, - [data-md-color-switching] *::after { - transition-duration: 0ms !important; // stylelint-disable-line - } -} diff --git a/src/assets/stylesheets/utilities/_break.scss b/src/assets/stylesheets/utilities/_break.scss @@ -1,219 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -@use "sass:list"; -@use "sass:map"; -@use "sass:math"; - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// -/// Device-specific breakpoints -/// -/// @example -/// $break-devices: ( -/// mobile: ( -/// portrait: 220px 479px, -/// landscape: 480px 719px -/// ), -/// tablet: ( -/// portrait: 720px 959px, -/// landscape: 960px 1219px -/// ), -/// screen: ( -/// small: 1220px 1599px, -/// medium: 1600px 1999px, -/// large: 2000px -/// ) -/// ); -/// -$break-devices: () !default; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Choose minimum and maximum device widths -/// -@function break-select-min-max($devices) { - $min: 1000000; - $max: 0; - @each $key, $value in $devices { - @while type-of($value) == map { - $value: break-select-min-max($value); - } - @if type-of($value) == list { - @each $number in $value { - @if type-of($number) == number { - $min: math.min($number, $min); - @if $max { - $max: math.max($number, $max); - } - } @else { - @error "Invalid number: #{$number}"; - } - } - } @else if type-of($value) == number { - $min: math.min($value, $min); - $max: null; - } @else { - @error "Invalid value: #{$value}"; - } - } - @return $min, $max; -} - -/// -/// Select minimum and maximum widths for a device breakpoint -/// -@function break-select-device($device) { - $current: $break-devices; - @for $n from 1 through length($device) { - @if type-of($current) == map { - $current: map.get($current, list.nth($device, $n)); - } @else { - @error "Invalid device map: #{$devices}"; - } - } - @if type-of($current) == list or type-of($current) == number { - $current: (default: $current); - } - @return break-select-min-max($current); -} - -// ---------------------------------------------------------------------------- -// Mixins -// ---------------------------------------------------------------------------- - -/// -/// A minimum-maximum media query breakpoint -/// -@mixin break-at($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (min-width: $breakpoint) { - @content; - } - } @else if type-of($breakpoint) == list { - $min: list.nth($breakpoint, 1); - $max: list.nth($breakpoint, 2); - @if type-of($min) == number and type-of($max) == number { - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// An orientation media query breakpoint -/// -@mixin break-at-orientation($breakpoint) { - @if type-of($breakpoint) == string { - @media screen and (orientation: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A maximum-aspect-ratio media query breakpoint -/// -@mixin break-at-ratio($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (max-aspect-ratio: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A minimum-maximum media query device breakpoint -/// -@mixin break-at-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - @if list.nth($breakpoint, 2) { - $min: list.nth($breakpoint, 1); - $max: list.nth($breakpoint, 2); - - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A minimum media query device breakpoint -/// -@mixin break-from-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $min: list.nth($breakpoint, 1); - - @media screen and (min-width: $min) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A maximum media query device breakpoint -/// -@mixin break-to-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $max: list.nth($breakpoint, 2); - - @media screen and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} diff --git a/src/assets/stylesheets/utilities/_convert.scss b/src/assets/stylesheets/utilities/_convert.scss @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -@use "sass:math"; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Strip units from a number -/// -@function strip-units($number) { - @return math.div($number, ($number * 0 + 1)); -} - -/// -/// Convert color in HEX to HSL -/// -/// Note, that we need to strip the `deg` units from the `hue` value, as they -/// were added in Color Level 4, which not all browsers support. -/// -@function hex2hsl($color) { - @return - round(strip-units(hue($color))), - round(saturation($color)), - round(lightness($color)); -} - -// ---------------------------------------------------------------------------- - -/// -/// Convert font size in px to em -/// -@function px2em($size, $base: 16px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1em; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} - -/// -/// Convert font size in px to rem -/// -@function px2rem($size, $base: 20px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1rem; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} diff --git a/src/base.html b/src/base.html @@ -1,412 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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 "partials/language.html" as lang with context %} - -<!doctype html> -<html lang="{{ lang.t('language') }}" class="no-js"> - <head> - - <!-- Meta tags --> - {% block site_meta %} - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - - <!-- Page description --> - {% if page.meta and page.meta.description %} - <meta name="description" content="{{ page.meta.description }}" /> - {% elif config.site_description %} - <meta name="description" content="{{ config.site_description }}" /> - {% endif %} - - <!-- Page author --> - {% if page.meta and page.meta.author %} - <meta name="author" content="{{ page.meta.author }}" /> - {% elif config.site_author %} - <meta name="author" content="{{ config.site_author }}" /> - {% endif %} - - <!-- Canonical --> - {% if page.canonical_url %} - <link rel="canonical" href="{{ page.canonical_url }}" /> - {% endif %} - - <!-- Favicon --> - <link rel="icon" href="{{ config.theme.favicon | url }}" /> - - <!-- Generator banner --> - <meta - name="generator" - content="mkdocs-{{ mkdocs_version }}, $md-name$-$md-version$" - /> - {% endblock %} - - <!-- Site title --> - {% block htmltitle %} - {% if page.meta and page.meta.title %} - <title>{{ page.meta.title }} - {{ config.site_name }}</title> - {% elif page.title and not page.is_homepage %} - <title>{{ page.title | striptags }} - {{ config.site_name }}</title> - {% else %} - <title>{{ config.site_name }}</title> - {% endif %} - {% endblock %} - - <!-- Theme-related style sheets --> - {% block styles %} - <link rel="stylesheet" href="{{ 'assets/stylesheets/main.css' | url }}" /> - - <!-- Extra color palette --> - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - <link - rel="stylesheet" - href="{{ 'assets/stylesheets/palette.css' | url }}" - /> - - <!-- Theme-color meta tag for Android --> - {% if palette.primary %} - {% import "partials/palette.html" as map %} - {% set primary = map.primary( - palette.primary | replace(" ", "-") | lower - ) %} - <meta name="theme-color" content="{{ primary }}" /> - {% endif %} - {% endif %} - - <!-- Custom icons --> - {% include "partials/icons.html" %} - {% endblock %} - - <!-- JavaScript libraries --> - {% block libs %}{% endblock %} - - <!-- Webfonts --> - {% block fonts %} - - <!-- Load fonts from Google --> - {% if config.theme.font != false %} - {% set text = config.theme.font.text | d("Roboto", true) %} - {% set code = config.theme.font.code | d("Roboto Mono", true) %} - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> - <link - rel="stylesheet" - href="https://fonts.googleapis.com/css?family={{ - text | replace(' ', '+') + ':300,300i,400,400i,700,700i%7C' + - code | replace(' ', '+') + ':400,400i,700,700i' - }}&display=fallback" - /> - <style> - :root { - --md-text-font: "{{ text }}"; - --md-code-font: "{{ code }}"; - } - </style> - {% endif %} - {% endblock %} - - <!-- Custom style sheets --> - {% for path in config["extra_css"] %} - <link rel="stylesheet" href="{{ path | url }}" /> - {% endfor %} - - <!-- Helper functions for inline scripts --> - {% include "partials/javascripts/base.html" %} - - <!-- Analytics --> - {% block analytics %} - {% include "partials/integrations/analytics.html" %} - {% endblock %} - - <!-- Custom front matter --> - {% block extrahead %}{% endblock %} - </head> - - <!-- Set text direction and color palette, if defined --> - {% set direction = config.theme.direction or lang.t('direction') %} - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - {% if not palette is mapping %} - {% set palette = palette | first %} - {% endif %} - {% set scheme = palette.scheme | replace(" ", "-") | lower %} - {% set primary = palette.primary | replace(" ", "-") | lower %} - {% set accent = palette.accent | replace(" ", "-") | lower %} - <body - dir="{{ direction }}" - data-md-color-scheme="{{ scheme }}" - data-md-color-primary="{{ primary }}" - data-md-color-accent="{{ accent }}" - > - {% else %} - <body dir="{{ direction }}"> - {% endif %} - {% set features = config.theme.features or [] %} - - <!-- User preference: color palette --> - {% if not config.theme.palette is mapping %} - {% include "partials/javascripts/palette.html" %} - {% endif %} - - <!-- - State toggles - we need to set autocomplete="off" in order to reset the - drawer on back button invocation in some browsers - --> - <input - class="md-toggle" - data-md-toggle="drawer" - type="checkbox" - id="__drawer" - autocomplete="off" - /> - <input - class="md-toggle" - data-md-toggle="search" - type="checkbox" - id="__search" - autocomplete="off" - /> - - <!-- Overlay for expanded drawer --> - <label class="md-overlay" for="__drawer"></label> - - <!-- Skip to content --> - <div data-md-component="skip"> - {% if page.toc | first is defined %} - {% set skip = page.toc | first %} - <a href="{{ skip.url | url }}" class="md-skip"> - {{ lang.t('skip.link.title') }} - </a> - {% endif %} - </div> - - <!-- Announcement bar --> - <div data-md-component="announce"> - {% if self.announce() %} - <aside class="md-banner"> - <div class="md-banner__inner md-grid md-typeset"> - - <!-- Button to dismiss announcement --> - {% if "announce.dismiss" in features %} - <button - class="md-banner__button md-icon" - aria-label="{{ lang.t('announce.dismiss') }}" - > - {% include ".icons/material/close.svg" %} - </button> - {% endif %} - - <!-- Announcement bar content --> - {% block announce %}{% endblock %} - </div> - {% if "announce.dismiss" in features %} - {% include "partials/javascripts/announce.html" %} - {% endif %} - </aside> - {% endif %} - </div> - - <!-- Version warning --> - {% if config.extra.version %} - <div data-md-component="outdated" hidden> - {% if self.outdated() %} - <aside class="md-banner md-banner--warning"> - <div class="md-banner__inner md-grid md-typeset"> - {% block outdated %}{% endblock %} - </div> - {% include "partials/javascripts/outdated.html" %} - </aside> - {% endif %} - </div> - {% endif %} - - <!-- Header --> - {% block header %} - {% include "partials/header.html" %} - {% endblock %} - - <!-- Container --> - <div class="md-container" data-md-component="container"> - - <!-- Hero teaser --> - {% block hero %}{% endblock %} - - <!-- Navigation tabs (collapsing) --> - {% block tabs %} - {% if not "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} - {% endblock %} - - <!-- Main area --> - <main class="md-main" data-md-component="main"> - <div class="md-main__inner md-grid"> - - <!-- Sidebars --> - {% block site_nav %} - - <!-- Navigation --> - {% if nav %} - {% if page.meta and page.meta.hide %} - {% set hidden = "hidden" if "navigation" in page.meta.hide %} - {% endif %} - <div - class="md-sidebar md-sidebar--primary" - data-md-component="sidebar" - data-md-type="navigation" - {{ hidden }} - > - <div class="md-sidebar__scrollwrap"> - <div class="md-sidebar__inner"> - {% include "partials/nav.html" %} - </div> - </div> - </div> - {% endif %} - - <!-- Table of contents --> - {% if not "toc.integrate" in features %} - {% if page.meta and page.meta.hide %} - {% set hidden = "hidden" if "toc" in page.meta.hide %} - {% endif %} - <div - class="md-sidebar md-sidebar--secondary" - data-md-component="sidebar" - data-md-type="toc" - {{ hidden }} - > - <div class="md-sidebar__scrollwrap"> - <div class="md-sidebar__inner"> - {% include "partials/toc.html" %} - </div> - </div> - </div> - {% endif %} - {% endblock %} - - <!-- Page content --> - <div class="md-content" data-md-component="content"> - <article class="md-content__inner md-typeset"> - {% block content %} - {% include "partials/content.html" %} - {% endblock %} - </article> - - <!-- User preference: content --> - {% include "partials/javascripts/content.html" %} - </div> - </div> - - <!-- Back-to-top button --> - {% if "navigation.top" in features %} - <a - href="#" - class="md-top md-icon" - data-md-component="top" - hidden - > - {% include ".icons/material/arrow-up.svg" %} - {{ lang.t('top.title') }} - </a> - {% endif %} - </main> - - <!-- Footer --> - {% block footer %} - {% include "partials/footer.html" %} - {% endblock %} - </div> - - <!-- Dialog --> - <div class="md-dialog" data-md-component="dialog"> - <div class="md-dialog__inner md-typeset"></div> - </div> - - <!-- Consent --> - {% if config.extra.consent %} - <div class="md-consent" data-md-component="consent" id="__consent" hidden> - <div class="md-consent__overlay"></div> - <aside class="md-consent__inner"> - <form class="md-consent__form md-grid md-typeset" name="consent"> - {% include "partials/consent.html" %} - </form> - </aside> - </div> - - <!-- User preference: consent --> - {% include "partials/javascripts/consent.html" %} - {% endif %} - - <!-- Theme-related configuration --> - {% block config %} - {%- set app = { - "base": base_url, - "features": features, - "translations": {}, - "search": "assets/javascripts/workers/search.js" | url - } -%} - - <!-- Versioning --> - {%- if config.extra.version -%} - {%- set _ = app.update({ "version": config.extra.version }) -%} - {%- endif -%} - - <!-- Translations --> - {%- set translations = app.translations -%} - {%- for key in [ - "clipboard.copy", - "clipboard.copied", - "search.config.lang", - "search.config.pipeline", - "search.config.separator", - "search.placeholder", - "search.result.placeholder", - "search.result.none", - "search.result.one", - "search.result.other", - "search.result.more.one", - "search.result.more.other", - "search.result.term.missing", - "select.version.title" - ] -%} - {%- set _ = translations.update({ key: lang.t(key) }) -%} - {%- endfor -%} - - <!-- Configuration --> - <script id="__config" type="application/json"> - {{- app | tojson -}} - </script> - {% endblock %} - - <!-- Theme-related JavaScript --> - {% block scripts %} - <script src="{{ 'assets/javascripts/bundle.js' | url }}"></script> - - <!-- Custom JavaScript --> - {% for path in config["extra_javascript"] %} - <script src="{{ path | url }}"></script> - {% endfor %} - {% endblock %} - </body> -</html> diff --git a/src/main.html b/src/main.html @@ -1,23 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -{% extends "base.html" %} diff --git a/src/mkdocs_theme.yml b/src/mkdocs_theme.yml @@ -1,68 +0,0 @@ -# Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - -# 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. - -# Language for theme localization -language: en - -# Text direction (can be ltr or rtl), default: ltr -direction: - -# Feature flags for functionality that alters behavior significantly, and thus -# may be a matter of taste -features: [] - -# Sets the primary and accent color palettes as defined in the Material Design -# documentation - possible values can be looked up in the getting started guide -palette: - - # Primary color used for header, sidebar and links, default: indigo - primary: - - # Accent color for highlighting user interaction, default: indigo - accent: - -# Fonts used by Material, automatically loaded from Google Fonts - see the site -# for a list of available fonts -font: - - # Default font for text - text: Roboto - - # Fixed-width font for code listings - code: Roboto Mono - -# From Material 5.x on, icons are inlined into the HTML and CSS as SVGs. Some -# icons that are part of the HTML can be configured and replaced -icon: - -# Favicon to be rendered -favicon: assets/images/favicon.png - -# Material includes the search in the header as a partial, not as a separate -# template, so it's correct that search.html is missing -include_search_page: false - -# Material doesn't use MkDocs search functionality but provides its own. For -# this reason, only the search index needs to be built -search_index_only: true - -# Static pages to build -static_templates: - - 404.html diff --git a/src/overrides/assets/javascripts/bundle.ts b/src/overrides/assets/javascripts/bundle.ts @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { merge, switchMap } from "rxjs" - -import { - getComponentElements, - mountIconSearch, - mountSponsorship -} from "./components" -import { setupAnalytics } from "./integrations" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Set up extra analytics events */ -setupAnalytics() - -/* Set up extra component observables */ -const component$ = document$ - .pipe( - switchMap(() => merge( - - /* Icon search */ - ...getComponentElements("iconsearch") - .map(el => mountIconSearch(el)), - - /* Sponsorship */ - ...getComponentElements("sponsorship") - .map(el => mountSponsorship(el)) - )) - ) - -/* Subscribe to all components */ -component$.subscribe() diff --git a/src/overrides/assets/javascripts/components/_/index.ts b/src/overrides/assets/javascripts/components/_/index.ts @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { getElement, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "iconsearch" /* Icon search */ - | "iconsearch-query" /* Icon search input */ - | "iconsearch-result" /* Icon search results */ - | "sponsorship" /* Sponsorship */ - | "sponsorship-count" /* Sponsorship count */ - | "sponsorship-total" /* Sponsorship total */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "iconsearch": HTMLElement /* Icon search */ - "iconsearch-query": HTMLInputElement /* Icon search input */ - "iconsearch-result": HTMLElement /* Icon search results */ - "sponsorship": HTMLElement /* Sponsorship */ - "sponsorship-count": HTMLElement /* Sponsorship count */ - "sponsorship-total": HTMLElement /* Sponsorship total */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElement(`[data-mdx-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements<T extends ComponentType>( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-mdx-component=${type}]`, node) -} diff --git a/src/overrides/assets/javascripts/components/iconsearch/_/index.ts b/src/overrides/assets/javascripts/components/iconsearch/_/index.ts @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Observable, merge } from "rxjs" - -import { configuration } from "~/_" -import { requestJSON } from "~/browser" - -import { Component, getComponentElement } from "../../_" -import { - IconSearchQuery, - mountIconSearchQuery -} from "../query" -import { - IconSearchResult, - mountIconSearchResult -} from "../result" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon category - */ -export interface IconCategory { - base: string /* Category base URL */ - data: Record<string, string> /* Category data */ -} - -/** - * Icon search index - */ -export interface IconSearchIndex { - icons: IconCategory /* Icons */ - emojis: IconCategory /* Emojis */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Icon search - */ -export type IconSearch = - | IconSearchQuery - | IconSearchResult - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search - * - * @param el - Icon search element - * - * @returns Icon search component observable - */ -export function mountIconSearch( - el: HTMLElement -): Observable<Component<IconSearch>> { - const config = configuration() - const index$ = requestJSON<IconSearchIndex>( - new URL("overrides/assets/javascripts/iconsearch_index.json", config.base) - ) - - /* Retrieve query and result components */ - const query = getComponentElement("iconsearch-query", el) - const result = getComponentElement("iconsearch-result", el) - - /* Create and return component */ - const query$ = mountIconSearchQuery(query) - const result$ = mountIconSearchResult(result, { index$, query$ }) - return merge(query$, result$) -} diff --git a/src/overrides/assets/javascripts/components/iconsearch/index.ts b/src/overrides/assets/javascripts/components/iconsearch/index.ts @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./query" -export * from "./result" diff --git a/src/overrides/assets/javascripts/components/iconsearch/query/index.ts b/src/overrides/assets/javascripts/components/iconsearch/query/index.ts @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { - Observable, - combineLatest, - delay, - distinctUntilChanged, - filter, - fromEvent, - map, - merge, - startWith, - withLatestFrom -} from "rxjs" - -import { watchElementFocus } from "~/browser" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search query - */ -export interface IconSearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search query - * - * @param el - Icon search query element - * - * @returns Icon search query component observable - */ -export function mountIconSearchQuery( - el: HTMLInputElement -): Observable<Component<IconSearchQuery, HTMLInputElement>> { - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => el.value), - startWith(el.value), - distinctUntilChanged(), - ) - - /* Log search on blur */ - focus$ - .pipe( - filter(active => !active), - withLatestFrom(value$) - ) - .subscribe(([, value]) => { - const path = document.location.pathname - if (typeof ga === "function" && value.length) - ga("send", "pageview", `${path}?q=[icon]+${value}`) - }) - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ ref: el, value, focus })), - ) -} diff --git a/src/overrides/assets/javascripts/components/iconsearch/result/index.ts b/src/overrides/assets/javascripts/components/iconsearch/result/index.ts @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { filter as search } from "fuzzaldrin-plus" -import { - Observable, - Subject, - bufferCount, - combineLatest, - distinctUntilKeyChanged, - filter, - finalize, - map, - merge, - of, - switchMap, - tap, - withLatestFrom, - zipWith -} from "rxjs" - -import { - getElement, - watchElementBoundary -} from "~/browser" -import { round } from "~/utilities" - -import { Icon, renderIconSearchResult } from "_/templates" - -import { Component } from "../../_" -import { IconSearchIndex } from "../_" -import { IconSearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search result - */ -export interface IconSearchResult { - data: Icon[] /* Search result data */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - index$: Observable<IconSearchIndex> /* Search index observable */ - query$: Observable<IconSearchQuery> /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result observable - */ -export function watchIconSearchResult( - el: HTMLElement, { index$, query$ }: WatchOptions -): Observable<IconSearchResult> { - switch (el.getAttribute("data-mdx-mode")) { - - case "file": - return combineLatest([ - query$.pipe(distinctUntilKeyChanged("value")), - index$ - .pipe( - map(({ icons }) => Object.values(icons.data) - .map(icon => icon.replace(/\.svg$/, "")) - ) - ) - ]) - .pipe( - map(([{ value }, data]) => search(data, value)), - switchMap(files => index$.pipe( - map(({ icons }) => ({ - data: files.map<Icon>(shortcode => { - return { - shortcode, - url: [ - icons.base, - shortcode, - ".svg" - ].join("") - } - }) - })) - )) - ) - - default: - return combineLatest([ - query$.pipe(distinctUntilKeyChanged("value")), - index$ - .pipe( - map(({ icons, emojis }) => [ - ...Object.keys(icons.data), - ...Object.keys(emojis.data) - ]) - ) - ]) - .pipe( - map(([{ value }, data]) => search(data, value)), - switchMap(shortcodes => index$.pipe( - map(({ icons, emojis }) => ({ - data: shortcodes.map<Icon>(shortcode => { - const category = - shortcode in icons.data - ? icons - : emojis - return { - shortcode, - url: [ - category.base, - category.data[shortcode] - ].join("") - } - }) - })) - )) - ) - } -} - -/** - * Mount icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result component observable - */ -export function mountIconSearchResult( - el: HTMLElement, { index$, query$ }: MountOptions -): Observable<Component<IconSearchResult, HTMLElement>> { - const push$ = new Subject<IconSearchResult>() - const boundary$ = watchElementBoundary(el) - .pipe( - filter(Boolean) - ) - - /* Update search result metadata */ - const meta = getElement(":scope > :first-child", el) - push$ - .pipe( - withLatestFrom(query$) - ) - .subscribe(([{ data }, { value }]) => { - if (value) { - switch (data.length) { - - /* No results */ - case 0: - meta.textContent = "No matches" - break - - /* One result */ - case 1: - meta.textContent = "1 match" - break - - /* Multiple result */ - default: - meta.textContent = `${round(data.length)} matches` - } - } else { - meta.textContent = "Type to start searching" - } - }) - - /* Update icon search result list */ - const file = el.getAttribute("data-mdx-mode") === "file" - const list = getElement(":scope > :last-child", el) - push$ - .pipe( - tap(() => list.innerHTML = ""), - switchMap(({ data }) => merge( - of(...data.slice(0, 10)), - of(...data.slice(10)) - .pipe( - bufferCount(10), - zipWith(boundary$), - switchMap(([chunk]) => chunk) - ) - )), - withLatestFrom(query$) - ) - .subscribe(([result, { value }]) => list.appendChild( - renderIconSearchResult(result, value, file) - )) - - /* Create and return component */ - return watchIconSearchResult(el, { query$, index$ }) - .pipe( - tap(state => push$.next(state)), - finalize(() => push$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/overrides/assets/javascripts/components/index.ts b/src/overrides/assets/javascripts/components/index.ts @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./_" -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/src/overrides/assets/javascripts/components/sponsorship/index.ts b/src/overrides/assets/javascripts/components/sponsorship/index.ts @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { Observable, map } from "rxjs" - -import { getElement, requestJSON } from "~/browser" - -import { renderPrivateSponsor, renderPublicSponsor } from "_/templates" - -import { Component, getComponentElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sponsor type - */ -export type SponsorType = - | "user" /* Sponsor is a user */ - | "organization" /* Sponsor is an organization */ - -/** - * Sponsor visibility - */ -export type SponsorVisibility = - | "public" /* Sponsor is a user */ - | "private" /* Sponsor is an organization */ - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor user - */ -export interface SponsorUser { - type: SponsorType /* Sponsor type */ - name: string /* Sponsor login name */ - image: string /* Sponsor image URL */ - url: string /* Sponsor URL */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Public sponsor - */ -export interface PublicSponsor { - type: "public" /* Sponsor visibility */ - user: SponsorUser /* Sponsor user */ -} - -/** - * Private sponsor - */ -export interface PrivateSponsor { - type: "private" /* Sponsor visibility */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor - */ -export type Sponsor = - | PublicSponsor - | PrivateSponsor - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsorship - */ -export interface Sponsorship { - sponsors: Sponsor[] /* Sponsors */ - total: number /* Total amount */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount sponsorship - * - * @param el - Sponsorship element - * - * @returns Sponsorship component observable - */ -export function mountSponsorship( - el: HTMLElement -): Observable<Component<Sponsorship>> { - const sponsorship$ = requestJSON<Sponsorship>( - "https://3if8u9o552.execute-api.us-east-1.amazonaws.com/_/" - ) - - /* Retrieve adjacent components */ - const count = getComponentElement("sponsorship-count") - const total = getComponentElement("sponsorship-total") - - /* Render sponsorship */ - sponsorship$.subscribe(sponsorship => { - el.removeAttribute("hidden") - - /* Render public sponsors with avatar and links */ - const list = getElement(":scope > :first-child", el) - for (const sponsor of sponsorship.sponsors) - if (sponsor.type === "public") - list.appendChild(renderPublicSponsor(sponsor.user)) - - /* Render combined private sponsors */ - list.appendChild(renderPrivateSponsor( - sponsorship.sponsors.filter(({ type }) => ( - type === "private" - )).length - )) - - /* Render sponsorship count and total */ - count.innerText = `${sponsorship.sponsors.length}` - total.innerText = `$ ${sponsorship.total - .toString() - .replace(/\B(?=(\d{3})+(?!\d))/g, ",") - } a month` - }) - - // /* Create and return component */ - return sponsorship$ - .pipe( - map(state => ({ ref: el, ...state })) - ) -} diff --git a/src/overrides/assets/javascripts/integrations/analytics/index.ts b/src/overrides/assets/javascripts/integrations/analytics/index.ts @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { fromEvent } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up extra analytics events - */ -export function setupAnalytics(): void { - const { origin } = new URL(location.href) - fromEvent(document.body, "click") - .subscribe(ev => { - if (ev.target instanceof HTMLElement) { - const el = ev.target.closest("a") - if (el && el.origin !== origin) - ga("send", "event", "outbound", "click", el.href) - } - }) -} diff --git a/src/overrides/assets/javascripts/integrations/index.ts b/src/overrides/assets/javascripts/integrations/index.ts @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./analytics" diff --git a/src/overrides/assets/javascripts/templates/iconsearch/index.tsx b/src/overrides/assets/javascripts/templates/iconsearch/index.tsx @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { wrap } from "fuzzaldrin-plus" - -import { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon - */ -export interface Icon { - shortcode: string /* Icon shortcode */ - url: string /* Icon URL */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Highlight an icon search result - * - * @param icon - Icon - * @param query - Search query - * - * @returns Highlighted result - */ -function highlight(icon: Icon, query: string): string { - return wrap(icon.shortcode, query, { - wrap: { - tagOpen: "<b>", - tagClose: "</b>" - } - }) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render an icon search result - * - * @param icon - Icon - * @param query - Search query - * @param file - Render as file - * - * @returns Element - */ -export function renderIconSearchResult( - icon: Icon, query: string, file?: boolean -): HTMLElement { - return ( - <li class="mdx-iconsearch-result__item"> - <span class="twemoji"> - <img src={icon.url} /> - </span> - <button - class="md-clipboard--inline" - title={translation("clipboard.copy")} - data-clipboard-text={file ? icon.shortcode : `:${icon.shortcode}:`} - > - <code>{ - file - ? highlight(icon, query) - : `:${highlight(icon, query)}:` - }</code> - </button> - </li> - ) -} diff --git a/src/overrides/assets/javascripts/templates/index.ts b/src/overrides/assets/javascripts/templates/index.ts @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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. - */ - -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/src/overrides/assets/javascripts/templates/sponsorship/index.tsx b/src/overrides/assets/javascripts/templates/sponsorship/index.tsx @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - * - * 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 { h } from "~/utilities" - -import { SponsorUser } from "_/components" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render public sponsor - * - * @param user - Sponsor user - * - * @returns Element - */ -export function renderPublicSponsor( - user: SponsorUser -): HTMLElement { - const title = `@${user.name}` - return ( - <a href={user.url} title={title} class="mdx-sponsorship__item"> - <img src={user.image} /> - </a> - ) -} - -/** - * Render private sponsor - * - * @param count - Number of private sponsors - * - * @returns Element - */ -export function renderPrivateSponsor( - count: number -): HTMLElement { - return ( - <a - href="https://github.com/sponsors/squidfunk" - class="mdx-sponsorship__item mdx-sponsorship__item--private" - > - +{count} - </a> - ) -} diff --git a/src/overrides/assets/stylesheets/main.scss b/src/overrides/assets/stylesheets/main.scss @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/typeset"; - -@import "main/layout/banner"; -@import "main/layout/hero"; -@import "main/layout/iconsearch"; -@import "main/layout/sponsorship"; - -@import "main/shame"; diff --git a/src/overrides/assets/stylesheets/main/_shame.scss b/src/overrides/assets/stylesheets/main/_shame.scss @@ -1,25 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Nothing to see here, move along -// ---------------------------------------------------------------------------- diff --git a/src/overrides/assets/stylesheets/main/_typeset.scss b/src/overrides/assets/stylesheets/main/_typeset.scss @@ -1,165 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Pumping heart animation -@keyframes heart { - 0%, - 40%, - 80%, - 100% { - transform: scale(1); - } - - 20%, - 60% { - transform: scale(1.15); - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Twitter icon - .twitter { - color: #00acee; - } - - // Insiders video - .mdx-video { - width: auto; - - // Insiders video container - &__inner { - position: relative; - width: 100%; - height: 0; - padding-bottom: 56.138%; - } - - // Insiders video iframe - iframe { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - border: none; - } - } - - // Pumping heart - .mdx-heart { - animation: heart 1000ms infinite; - } - - // Insiders color (for links, etc.) - .mdx-insiders { - color: $clr-pink-500; - } - - // Switch buttons - .mdx-switch button { - cursor: pointer; - transition: opacity 250ms; - - // Button on focus/hover - &:focus, - &:hover { - opacity: 0.75; - } - - // Code block - > code { - display: block; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - } - } - - // Deprecation - .mdx-deprecated { - opacity: 0.5; - transition: opacity 250ms; - - // Deprecation on focus/hover - &:focus-within, - &:hover { - opacity: 1; - } - } - - // Two-column layout - .mdx-columns { - - // Column - ol, - ul { - columns: 2; - - // [mobile portrait -]: Reset columns on mobile - @include break-to-device(mobile portrait) { - columns: initial; - } - } - - // Column item - li { - break-inside: avoid; - } - } - - // Blog author - .mdx-author { - display: flex; - font-size: px2rem(13.6px); - - // Blog author image - img { - height: px2rem(40px); - border-radius: 100%; - } - - // Blog author content - p { - - // TODO: refactor, use dedicated classes - &:first-child { - flex-shrink: 0; - margin-right: px2rem(16px); - } - - // Blog metadata - > span { - display: block; - } - } - } -} diff --git a/src/overrides/assets/stylesheets/main/layout/_banner.scss b/src/overrides/assets/stylesheets/main/layout/_banner.scss @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Banner for announcements and warnings -.md-banner { - - // Text link, also on focus/hover - a, - a:focus, - a:hover { - color: currentcolor; - } - - // Don't wrap name of blog article - strong { - white-space: nowrap; - } - - // Twitter icon - .twitter { - margin-inline-start: 0.2em; - } -} diff --git a/src/overrides/assets/stylesheets/main/layout/_hero.scss b/src/overrides/assets/stylesheets/main/layout/_hero.scss @@ -1,124 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Landing page container -.mdx-container { - padding-top: px2rem(20px); - background: - url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(0, 0%, 100%, 1)' /></svg>") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - - // Adjust background for slate theme - [data-md-color-scheme="slate"] & { - background: - url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1123 258'><path d='M1124,2c0,0 0,256 0,256l-1125,0l0,-48c0,0 16,5 55,5c116,0 197,-92 325,-92c121,0 114,46 254,46c140,0 214,-167 572,-166Z' style='fill: hsla(232, 15%, 21%, 1)' /></svg>") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - } -} - -// Landing page hero -.mdx-hero { - margin: 0 px2rem(16px); - color: var(--md-primary-bg-color); - - // Hero headline - h1 { - margin-bottom: px2rem(20px); - color: currentcolor; - font-weight: 700; - - // [mobile portrait -]: Larger hero headline - @include break-to-device(mobile portrait) { - font-size: px2rem(28px); - } - } - - // Hero content - &__content { - padding-bottom: px2rem(120px); - } - - // [tablet landscape +]: Columnar display - @include break-from-device(tablet landscape) { - display: flex; - align-items: stretch; - - // Adjust spacing and set dimensions - &__content { - max-width: px2rem(380px); - margin-top: px2rem(70px); - padding-bottom: 14vw; - } - - // Hero image - &__image { - order: 1; - width: px2rem(760px); - transform: translateX(#{px2rem(80px)}); - } - } - - // [screen +]: Columnar display and adjusted spacing - @include break-from-device(screen) { - - // Hero image - &__image { - transform: translateX(#{px2rem(160px)}); - } - } - - // Button - .md-button { - margin-top: px2rem(10px); - margin-right: px2rem(10px); - color: var(--md-primary-bg-color); - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - - // Primary button - &--primary { - color: hsla(280, 37%, 48%, 1); - background-color: var(--md-primary-bg-color); - border-color: var(--md-primary-bg-color); - } - } -} diff --git a/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss b/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss @@ -1,137 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Icon search - .mdx-iconsearch { - position: relative; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: var(--md-shadow-z1); - transition: box-shadow 125ms; - - // Icon search on focus/hover - &:focus-within, - &:hover { - box-shadow: var(--md-shadow-z2); - } - - // Icon search input - .md-input { - background: var(--md-default-bg-color); - box-shadow: none; - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] & { - background: var(--md-code-bg-color); - } - } - } - - // Icon search result - .mdx-iconsearch-result { - max-height: 50vh; - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - touch-action: pan-y; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Icon search result inside tooltip - .md-tooltip & { - max-height: px2rem(205px); - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - - // Icon search result metadata - &__meta { - position: absolute; - top: px2rem(8px); - right: px2rem(12px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(12.8px); - } - - // Icon search result list - &__list { - margin: 0; - // Hack: necessary because of increased specificity due to the PostCSS - // plugin which prefixes this with `[dir=...]` selectors. - margin-inline-start: 0; - padding: 0; - list-style: none; - } - - // Icon search result item - &__item { - margin: 0; - // Hack: necessary because of increased specificity due to the PostCSS - // plugin which prefixes this with `[dir=...]` selectors. - margin-inline-start: 0; - padding: px2rem(4px) px2rem(12px); - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Omit border on last child - &:last-child { - border-bottom: none; - } - - // Item content - > * { - margin-right: px2rem(12px); - } - - // Set icon dimensions to fit - img { - width: px2rem(18px); - height: px2rem(18px); - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] &[src*="squidfunk"] { - filter: invert(1); /* stylelint-disable-line */ - } - } - } - } -} diff --git a/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss b/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss @@ -1,129 +0,0 @@ -//// -/// Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> -/// -/// 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 -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Premium sponsors - .mdx-premium { - - // Paragraphs - p { - margin: 2em 0; - text-align: center; - } - - // Premium sponsor image - img { - height: px2rem(65px); - } - - // Premium sponsor list - p:last-child { - display: flex; - flex-wrap: wrap; - justify-content: center; - - // Premium sponsor link - > a { - display: block; - flex-shrink: 0; - } - } - } - - // Sponsorship - .mdx-sponsorship { - - // Sponsorship list - &__list { - margin: 2em 0; - - // Clearfix, because we can't use overflow: auto - &::after { - display: block; - clear: both; - content: ""; - } - } - - // Sponsorship item - &__item { - display: block; - float: left; - width: px2rem(32px); - height: px2rem(32px); - margin: px2rem(4px); - overflow: hidden; - border-radius: 100%; - transform: scale(1); - transition: - color 125ms, - transform 125ms; - - // Sponsor item on focus/hover - &:focus, - &:hover { - transform: scale(1.1); - - // Sponsor avatar - img { - filter: grayscale(0%); - } - } - - // Private sponsor - &--private { - color: var(--md-default-fg-color--lighter); - font-weight: 700; - font-size: px2rem(12px); - line-height: px2rem(32px); - text-align: center; - background: var(--md-default-fg-color--lightest); - } - - // Sponsor avatar - img { - display: block; - width: 100%; - height: auto; - filter: grayscale(100%) opacity(75%); - transition: filter 125ms; - } - } - } - - // Sponsorship button - .mdx-sponsorship-button { - font-weight: 400; - } - - // Sponsorship count and total - .mdx-sponsorship-count, - .mdx-sponsorship-total { - font-weight: 700; - } -} diff --git a/src/overrides/blog.html b/src/overrides/blog.html @@ -1,76 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -{% extends "overrides/main.html" %} - -<!-- Content --> -{% block content %} - {{ super() }} - - <!-- Giscus - generated by https://giscus.app --> - <h2 id="__comments">{{ lang.t("meta.comments") }}</h2> - <script - src="https://giscus.app/client.js" - data-repo="squidfunk/mkdocs-material" - data-repo-id="MDEwOlJlcG9zaXRvcnk1MDYxNzQyOA==" - data-category="_" - data-category-id="DIC_kwDOAwRcVM4CAtJY" - data-mapping="pathname" - data-reactions-enabled="1" - data-emit-metadata="1" - data-theme="light" - data-lang="en" - crossorigin="anonymous" - async - > - </script> - - <!-- Synchronize Giscus theme with palette --> - <script> - var giscus = document.querySelector("script[src*=giscus]") - - /* Set palette on initial load */ - var palette = __md_get("__palette") - if (palette && typeof palette.color === "object") { - var theme = palette.color.scheme === "slate" ? "dark" : "light" - giscus.setAttribute("data-theme", theme) - } - - /* Register event handlers after documented loaded */ - document.addEventListener("DOMContentLoaded", function() { - var ref = document.querySelector("[data-md-component=palette]") - ref.addEventListener("change", function() { - var palette = __md_get("__palette") - if (palette && typeof palette.color === "object") { - var theme = palette.color.scheme === "slate" ? "dark" : "light" - - /* Instruct Giscus to change theme */ - var frame = document.querySelector(".giscus-frame") - frame.contentWindow.postMessage( - { giscus: { setConfig: { theme } } }, - "https://giscus.app" - ) - } - }) - }) - </script> -{% endblock %} diff --git a/src/overrides/home.html b/src/overrides/home.html @@ -1,106 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -{% extends "overrides/main.html" %} - -<!-- Render hero under tabs --> -{% block tabs %} - {{ super() }} - - <!-- Additional styles for landing page --> - <style> - - /* Application header should be static for the landing page */ - .md-header { - position: initial; - } - - /* Remove spacing, as we cannot hide it completely */ - .md-main__inner { - margin: 0; - } - - /* Hide main content for now */ - .md-content { - display: none; - } - - /* Hide table of contents */ - @media screen and (min-width: 60em) { - .md-sidebar--secondary { - display: none; - } - } - - /* Hide navigation */ - @media screen and (min-width: 76.25em) { - .md-sidebar--primary { - display: none; - } - } - </style> - - <!-- Hero for landing page --> - <section class="mdx-container"> - <div class="md-grid md-typeset"> - <div class="mdx-hero"> - - <!-- Hero image --> - <div class="mdx-hero__image"> - <img - src="assets/images/illustration.png" - alt="" - width="1659" - height="1200" - draggable="false" - > - </div> - - <!-- Hero content --> - <div class="mdx-hero__content"> - <h1>Technical documentation that just works</h1> - <p>{{ config.site_description }}. Set up in 5 minutes.</p> - <a - href="{{ page.next_page.url | url }}" - title="{{ page.next_page.title | e }}" - class="md-button md-button--primary" - > - Quick start - </a> - <a - href="{{ 'insiders/' | url }}" - title="Material for MkDocs Insiders" - class="md-button" - > - Get Insiders - </a> - </div> - </div> - </div> - </section> -{% endblock %} - -<!-- Content --> -{% block content %}{% endblock %} - -<!-- Application footer --> -{% block footer %}{% endblock %} diff --git a/src/overrides/main.html b/src/overrides/main.html @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -{% extends "base.html" %} - -<!-- Custom front matter --> -{% block extrahead %} - - <!-- Extra style sheets (can't be set in mkdocs.yml due to content hash) --> - <link - rel="stylesheet" - href="{{ 'overrides/assets/stylesheets/main.css' | url }}" - /> -{% endblock %} - -<!-- Announcement bar --> -{% block announce %} - <a href="https://twitter.com/teamseshisma"> - For updates follow <strong>@teamseshisma</strong> on - <span class="twemoji twitter"> - {% include ".icons/fontawesome/brands/twitter.svg" %} - </span> - <strong>Twitter</strong> - </a> -{% endblock %} - -<!-- Content --> -{% block content %} - {% include "overrides/partials/content.html" %} -{% endblock %} - -<!-- Theme-related JavaScript --> -{% block scripts %} - {{ super() }} - - <!-- Extra JavaScript (can't be set in mkdocs.yml due to content hash) --> - <script src="{{ 'overrides/assets/javascripts/bundle.js' | url }}"></script> -{% endblock %} diff --git a/src/overrides/partials/content.html b/src/overrides/partials/content.html @@ -1,68 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Edit and view button --> -{% if page.edit_url %} - {% set edit = "https://github.com/squidfunk/mkdocs-material/edit" %} - {% set view = "https://raw.githubusercontent.com/squidfunk/mkdocs-material" %} - <a - href="{{ page.edit_url }}" - title="{{ lang.t('edit.link.title') }}" - class="md-content__button md-icon" - > - {% include ".icons/material/file-edit-outline.svg" %} - </a> - <a - href="{{ page.edit_url | replace(edit, view) }}" - title="View source of this page" - class="md-content__button md-icon" - > - {% include ".icons/material/file-eye-outline.svg" %} - </a> -{% endif %} - -<!-- Tags --> -{% if "tags" in config.plugins %} - {% include "partials/tags.html" %} -{% endif %} - -<!-- - Hack: check whether the content contains a h1 headline. If it doesn't, the - page title (or respectively site name) is used as the main headline. ---> -{% if not "\x3ch1" in page.content %} - <h1>{{ page.title | d(config.site_name, true)}}</h1> -{% endif %} - -<!-- Markdown content --> -{{ page.content }} - -<!-- Source file information --> -{% if page.meta and ( - page.meta.git_revision_date_localized or - page.meta.revision_date -) %} - {% include "partials/source-file.html" %} -{% endif %} - -<!-- Was this page helpful? --> -{% include "partials/feedback.html" %} diff --git a/src/partials/consent.html b/src/partials/consent.html @@ -1,91 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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 "partials/language.html" as lang with context %} - -<!-- Determine cookies (default to analytics, if present) --> -{% set cookies = config.extra.consent.cookies %} -{% if config.extra.analytics and not cookies %} - {% set cookies = { "analytics": "Google Analytics" } %} -{% endif %} - -<!-- Determine actions --> -{% set actions = config.extra.consent.actions %} -{% if not actions %} - {% set actions = ["accept", "manage"] %} -{% endif %} - -<!-- Consent title --> -<h4>{{ config.extra.consent.title }}</h4> -<p>{{ config.extra.consent.description }}</p> - -<!-- Consent settings --> -<input type="checkbox" class="md-toggle" id="__settings" /> -<div class="md-consent__settings"> - <ul class="task-list"> - {% for type in cookies %} - {% if cookies[type] is string %} - {% set name = cookies[type] %} - {% set checked = "checked" %} - {% else %} - {% set name = cookies[type].name %} - {% if cookies[type].checked %} - {% set checked = "checked" %} - {% endif %} - {% endif %} - <li class="task-list-item"> - <label class="task-list-control"> - <input type="checkbox" name="{{ type }}" {{ checked }}> - <span class="task-list-indicator"></span> - {{ name }} - <label> - </li> - {% endfor %} - </ul> -</div> - -<!-- Consent controls --> -<div class="md-consent__controls"> - {% for action in actions %} - - <!-- Button to accept cookies --> - {% if action == "accept" %} - <button class="md-button md-button--primary"> - {{- lang.t("consent.accept") -}} - </button> - {% endif %} - - <!-- Button to reject cookies --> - {% if action == "reject" %} - <button type="reset" class="md-button md-button--primary"> - {{- lang.t("consent.reject") -}} - </button> - {% endif %} - - <!-- Button to manage settings --> - {% if action == "manage" %} - <label class="md-button" for="__settings"> - {{- lang.t("consent.manage") -}} - </label> - {% endif %} - {% endfor %} -</div> diff --git a/src/partials/content.html b/src/partials/content.html @@ -1,59 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Edit button --> -{% if page.edit_url %} - <a - href="{{ page.edit_url }}" - title="{{ lang.t('edit.link.title') }}" - class="md-content__button md-icon" - > - {% include ".icons/material/pencil.svg" %} - </a> -{% endif %} - -<!-- Tags --> -{% if "tags" in config.plugins %} - {% include "partials/tags.html" %} -{% endif %} - -<!-- - Hack: check whether the content contains a h1 headline. If it doesn't, the - page title (or respectively site name) is used as the main headline. ---> -{% if not "\x3ch1" in page.content %} - <h1>{{ page.title | d(config.site_name, true)}}</h1> -{% endif %} - -<!-- Markdown content --> -{{ page.content }} - -<!-- Source file information --> -{% if page.meta and ( - page.meta.git_revision_date_localized or - page.meta.revision_date -) %} - {% include "partials/source-file.html" %} -{% endif %} - -<!-- Was this page helpful? --> -{% include "partials/feedback.html" %} diff --git a/src/partials/copyright.html b/src/partials/copyright.html @@ -1,33 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Copyright and theme information --> -<div class="md-copyright"> - {% if config.copyright %} - <div class="md-copyright__highlight"> - {{ config.copyright }} - </div> - {% endif %} - {% if not config.extra.generator == false %} - Made for Sound-Engineers around the world - {% endif %} -</div> diff --git a/src/partials/feedback.html b/src/partials/feedback.html @@ -1,85 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine feedback configuration --> -{% if config.extra.analytics %} - {% set feedback = config.extra.analytics.feedback %} -{% endif %} - -<!-- Determine whether to show feedback --> -{% if page and page.meta and page.meta.hide %} - {% if "feedback" in page.meta.hide %} - {% set feedback = None %} - {% endif %} -{% endif %} - -<!-- Was this page helpful? --> -{% if feedback %} - <form class="md-feedback" name="feedback" hidden> - <fieldset> - <legend class="md-feedback__title"> - {{ feedback.title }} - </legend> - <div class="md-feedback__inner"> - - <!-- Feedback ratings --> - <div class="md-feedback__list"> - {% for rating in feedback.ratings %} - <button - class="md-feedback__icon md-icon" - type="submit" - title="{{ rating.name }}" - data-md-value="{{ rating.data }}" - > - {% include ".icons/" ~ rating.icon ~ ".svg" %} - </button> - {% endfor %} - </div> - - <!-- Feedback rating notes (shown after submission) --> - <div class="md-feedback__note"> - {% for rating in feedback.ratings %} - <div data-md-value="{{ rating.data }}" hidden> - {% set url = "/" ~ page.url %} - - <!-- Determine title --> - {% if page and page.meta and page.meta.title %} - {% set title = page.meta.title | urlencode %} - {% else %} - {% set title = page.title | urlencode %} - {% endif %} - - <!-- Legacy, deprecated, removed in next major version --> - {% if "{}" in rating.note %} - {{ rating.note.format(url, title) }} - - <!-- Replace {url} and {title} placeholders in note --> - {% else %} - {{ rating.note.format(url = url, title = title) }} - {% endif %} - </div> - {% endfor %} - </div> - </div> - </fieldset> - </form> -{% endif %} diff --git a/src/partials/footer.html b/src/partials/footer.html @@ -1,96 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Footer --> -<footer class="md-footer"> - - <!-- Link to previous and/or next page --> - {% if page.previous_page or page.next_page %} - {% if page.meta and page.meta.hide %} - {% set hidden = "hidden" if "footer" in page.meta.hide %} - {% endif %} - <nav - class="md-footer__inner md-grid" - aria-label="{{ lang.t('footer.title') }}" - {{ hidden }} - > - - <!-- Link to previous page --> - {% if page.previous_page %} - {% set direction = lang.t("footer.previous") %} - <a - href="{{ page.previous_page.url | url }}" - class="md-footer__link md-footer__link--prev" - aria-label="{{ direction }}: {{ page.previous_page.title | e }}" - rel="prev" - > - <div class="md-footer__button md-icon"> - {% include ".icons/material/arrow-left.svg" %} - </div> - <div class="md-footer__title"> - <div class="md-ellipsis"> - <span class="md-footer__direction"> - {{ direction }} - </span> - {{ page.previous_page.title }} - </div> - </div> - </a> - {% endif %} - - <!-- Link to next page --> - {% if page.next_page %} - {% set direction = lang.t("footer.next") %} - <a - href="{{ page.next_page.url | url }}" - class="md-footer__link md-footer__link--next" - aria-label="{{ direction }}: {{ page.next_page.title | e }}" - rel="next" - > - <div class="md-footer__title"> - <div class="md-ellipsis"> - <span class="md-footer__direction"> - {{ direction }} - </span> - {{ page.next_page.title }} - </div> - </div> - <div class="md-footer__button md-icon"> - {% include ".icons/material/arrow-right.svg" %} - </div> - </a> - {% endif %} - </nav> - {% endif %} - - <!-- Further information --> - <div class="md-footer-meta md-typeset"> - <div class="md-footer-meta__inner md-grid"> - {% include "partials/copyright.html" %} - - <!-- Social links --> - {% if config.extra.social %} - {% include "partials/social.html" %} - {% endif %} - </div> - </div> -</footer> diff --git a/src/partials/header.html b/src/partials/header.html @@ -1,161 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine class according to configuration --> -{% set class = "md-header" %} -{% if "navigation.tabs.sticky" in features %} - {% set class = class ~ " md-header--lifted" %} -{% endif %} - -<!-- Header --> -<header class="{{ class }}" data-md-component="header"> - <nav - class="md-header__inner md-grid" - aria-label="{{ lang.t('header.title') }}" - > - - <!-- Link to home --> - <a - href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}" - title="{{ config.site_name | e }}" - class="md-header__button md-logo" - aria-label="{{ config.site_name }}" - data-md-component="logo" - > - {% include "partials/logo.html" %} - </a> - - <!-- Button to open drawer --> - <label class="md-header__button md-icon" for="__drawer"> - {% include ".icons/material/menu" ~ ".svg" %} - </label> - - <!-- Header title --> - <div class="md-header__title" data-md-component="header-title"> - <div class="md-header__ellipsis"> - <div class="md-header__topic"> - <span class="md-ellipsis"> - {{ config.site_name }} - </span> - </div> - <div class="md-header__topic" data-md-component="header-topic"> - <span class="md-ellipsis"> - {% if page.meta and page.meta.title %} - {{ page.meta.title }} - {% else %} - {{ page.title }} - {% endif %} - </span> - </div> - </div> - </div> - - <!-- Color palette --> - {% if not config.theme.palette is mapping %} - <form class="md-header__option" data-md-component="palette"> - {% for option in config.theme.palette %} - {% set primary = option.primary | replace(" ", "-") | lower %} - {% set accent = option.accent | replace(" ", "-") | lower %} - <input - class="md-option" - data-md-color-media="{{ option.media }}" - data-md-color-scheme="{{ option.scheme }}" - data-md-color-primary="{{ primary }}" - data-md-color-accent="{{ accent }}" - {% if option.toggle %} - aria-label="{{ option.toggle.name }}" - {% else %} - aria-hidden="true" - {% endif %} - type="radio" - name="__palette" - id="__palette_{{ loop.index }}" - /> - {% if option.toggle %} - <label - class="md-header__button md-icon" - title="{{ option.toggle.name }}" - for="__palette_{{ loop.index0 or loop.length }}" - hidden - > - {% include ".icons/" ~ option.toggle.icon ~ ".svg" %} - </label> - {% endif %} - {% endfor %} - </form> - {% endif %} - - <!-- Site language selector --> - {% if config.extra.alternate %} - <div class="md-header__option"></form> - <div class="md-select"> - {% set icon = config.theme.icon.alternate or "material/translate" %} - <button - class="md-header__button md-icon" - aria-label="{{ lang.t('select.language.title') }}" - > - {% include ".icons/" ~ icon ~ ".svg" %} - </button> - <div class="md-select__inner"> - <ul class="md-select__list"> - {% for alt in config.extra.alternate %} - <li class="md-select__item"> - <a - href="{{ alt.link | url }}" - hreflang="{{ alt.lang }}" - class="md-select__link" - > - {{ alt.name }} - </a> - </li> - {% endfor %} - </ul> - </div> - </div> - </div> - {% endif %} - - <!-- Button to open search modal --> - {% if "search" in config["plugins"] %} - <label class="md-header__button md-icon" for="__search"> - {% include ".icons/material/magnify.svg" %} - </label> - - <!-- Search interface --> - {% include "partials/search.html" %} - {% endif %} - - <!-- Repository information --> - {% if config.repo_url %} - <div class="md-header__source"> - {% include "partials/source.html" %} - </div> - {% endif %} - </nav> - - <!-- Navigation tabs (sticky) --> - {% if "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} -</header> diff --git a/src/partials/icons.html b/src/partials/icons.html @@ -1,37 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Custom admonition icons --> -{% if config.theme.icon.admonition %} - {% set style = ["\x3cstyle\x3e:root{"] %} - {% for type, icon in config.theme.icon.admonition.items() %} - {% import ".icons/" ~ icon ~ ".svg" as icon %} - {% set _ = style.append( - "--md-admonition-icon--" ~ type ~ ":" ~ - "url('data:image/svg+xml;charset=utf-8," ~ - icon | replace("\n", "") ~ - "');" - ) %} - {% endfor %} - {% set _ = style.append("}\x3c/style\x3e") %} - {{ style | join }} -{% endif %} diff --git a/src/partials/integrations/analytics.html b/src/partials/integrations/analytics.html @@ -1,49 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine analytics provider --> -{% if config.extra.analytics %} - {% set provider = config.extra.analytics.provider %} -{% endif %} - -<!-- Set up analytics provider --> -{% if provider %} - {% include "partials/integrations/analytics/" ~ provider ~ ".html" %} - - <!-- Consent necessary --> - {% if config.extra.consent %} - <script> - if (typeof __md_analytics !== "undefined") { - var consent = __md_get("__consent") - if (consent && consent.analytics) - __md_analytics() - } - </script> - - <!-- Consent unnecessary --> - {% else %} - <script> - if (typeof __md_analytics !== "undefined") - __md_analytics() - </script> - {% endif %} -{% endif %} diff --git a/src/partials/integrations/analytics/google.html b/src/partials/integrations/analytics/google.html @@ -1,168 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine analytics property --> -{% if config.extra.analytics %} - {% set property = config.extra.analytics.property | d("", true) %} -{% endif %} - -<!-- Google Analytics 4 (G-XXXXXXXXXX) --> -{% if property.startswith("G-") %} - <script id="__analytics"> - function __md_analytics() { - window.dataLayer = window.dataLayer || [] - function gtag() { dataLayer.push(arguments) } - - /* Set up integration and send page view */ - gtag("js", new Date()) - gtag("config", "{{ property }}") - - /* Register event handlers after documented loaded */ - document.addEventListener("DOMContentLoaded", function() { - - /* Set up search tracking */ - if (document.forms.search) { - var query = document.forms.search.query - query.addEventListener("blur", function() { - if (this.value) - gtag("event", "search", { search_term: this.value }) - }) - } - - /* Set up feedback, i.e. "Was this page helpful?" */ - if (document.forms.feedback) { - var feedback = document.forms.feedback - for (var button of feedback.querySelectorAll("[type=submit]")) { - button.addEventListener("click", function(ev) { - ev.preventDefault() - - /* Retrieve and send data */ - var page = document.location.pathname - var data = this.getAttribute("data-md-value") - gtag("event", "feedback", { page, data }) - - /* Disable form and show note, if given */ - feedback.firstElementChild.disabled = true - var note = feedback.querySelector( - ".md-feedback__note [data-md-value='" + data + "']" - ) - if (note) - note.hidden = false - }) - - /* Show feedback */ - feedback.hidden = false - } - } - - /* Send page view on location change */ - if (typeof location$ !== "undefined") - location$.subscribe(function(url) { - gtag("config", "{{ property }}", { - page_path: url.pathname - }) - }) - }) - - /* Create script tag */ - var script = document.createElement("script") - script.async = true - script.src = "https://www.googletagmanager.com/gtag/js?id={{ property }}" - - /* Inject script tag */ - var container = document.getElementById("__analytics") - container.insertAdjacentElement("afterEnd", script) - } - </script> - -<!-- Universal Analytics (UA-XXXXXXXX-X) --> -{% elif property.startswith("UA-") %} - <script id="__analytics"> - function __md_analytics() { - window.ga = window.ga || function() { - (ga.q = ga.q || []).push(arguments) - } - ga.l = +new Date() - - /* Set up integration and send page view */ - ga("create", "{{ property }}", "auto") - ga("set", "anonymizeIp", true) - ga("send", "pageview") - - /* Register event handlers after documented loaded */ - document.addEventListener("DOMContentLoaded", function() { - - /* Set up search tracking */ - if (document.forms.search) { - var query = document.forms.search.query - query.addEventListener("blur", function() { - if (this.value) { - var page = document.location.pathname; - ga("send", "pageview", page + "?q=" + this.value) - } - }) - } - - /* Set up feedback, i.e. "Was this page helpful?" */ - if (document.forms.feedback) { - var feedback = document.forms.feedback - for (var button of feedback.querySelectorAll("[type=submit]")) { - button.addEventListener("click", function(ev) { - ev.preventDefault() - - /* Retrieve and send data */ - var page = document.location.pathname - var data = this.getAttribute("data-md-value") - ga("send", "event", "feedback", "click", page, data) - - /* Disable form and show note, if given */ - feedback.firstElementChild.disabled = true - var note = feedback.querySelector( - ".md-feedback__note [data-md-value='" + data + "']" - ) - if (note) - note.hidden = false - }) - - /* Show feedback */ - feedback.hidden = false - } - } - - /* Send page view on location change */ - if (typeof location$ !== "undefined") - location$.subscribe(function(url) { - ga("send", "pageview", url.pathname) - }) - }) - - /* Create script tag */ - var script = document.createElement("script") - script.async = true - script.src = "https://www.google-analytics.com/analytics.js" - - /* Inject script tag */ - var container = document.getElementById("__analytics") - container.insertAdjacentElement("afterEnd", script) - } - </script> -{% endif %} diff --git a/src/partials/javascripts/announce.html b/src/partials/javascripts/announce.html @@ -1,31 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Announcement bar --> -<script> - var el = document.querySelector("[data-md-component=announce]") - if (el) { - var content = el.querySelector(".md-typeset") - if (__md_hash(content.innerHTML) === __md_get("__announce")) - el.hidden = true - } -</script> diff --git a/src/partials/javascripts/base.html b/src/partials/javascripts/base.html @@ -1,48 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- - A collection of functions used from within some partials to allow the usage - of state saved in local or session storage, e.g. to model preferences. ---> -<script> - - /* Compute base path once to integrate with instant loading */ - __md_scope = new URL("{{ config.extra.scope | d(base_url) }}", location) - - /* Compute hash from the given string - see https://bit.ly/3pvPjXG */ - __md_hash = v => [...v].reduce((h, c) => (h << 5) - h + c.charCodeAt(0), 0) - - /* Fetch the value for a key from the given storage */ - __md_get = (key, storage = localStorage, scope = __md_scope) => ( - JSON.parse(storage.getItem(scope.pathname + "." + key)) - ) - - /* Persist a key-value pair in the given storage */ - __md_set = (key, value, storage = localStorage, scope = __md_scope) => { - try { - storage.setItem(scope.pathname + "." + key, JSON.stringify(value)) - } catch (err) { - /* Uncritical, just swallow */ - } - } -</script> diff --git a/src/partials/javascripts/consent.html b/src/partials/javascripts/consent.html @@ -1,62 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- User-preference: consent --> -<script> - var consent = __md_get("__consent") - if (consent) { - for (var input of document.forms.consent.elements) - if (input.name) - input.checked = consent[input.name] || false - - /* Show consent with a small delay, but not if browsing locally */ - } else if (location.protocol !== "file:") { - setTimeout(function() { - var el = document.querySelector("[data-md-component=consent]") - el.hidden = false - }, 250) - } - - /* Intercept submission of consent form */ - var form = document.forms.consent - for (var action of ["submit", "reset"]) - form.addEventListener(action, function(ev) { - ev.preventDefault() - - /* Reject all cookies */ - if (ev.type === "reset") - for (var input of document.forms.consent.elements) - if (input.name) - input.checked = false - - /* Grab and serialize form data */ - console.log(new FormData(form)) - __md_set("__consent", Object.fromEntries( - Array.from(new FormData(form).keys()) - .map(function(key) { return [key, true] }) - )) - - /* Remove anchor to omit consent from reappearing and reload */ - location.hash = ''; - location.reload() - }) -</script> diff --git a/src/partials/javascripts/content.html b/src/partials/javascripts/content.html @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- User-preference: link content tabs --> -{% if "content.tabs.link" in features %} - <script> - var tabs = __md_get("__tabs") - if (Array.isArray(tabs)) - main: for (var set of document.querySelectorAll(".tabbed-set")) { - var labels = set.querySelector(".tabbed-labels") - for (var tab of tabs) - for (var label of labels.getElementsByTagName("label")) - if (label.innerText.trim() === tab) { - var input = document.getElementById(label.htmlFor) - input.checked = true - continue main - } - } - </script> -{% endif %} diff --git a/src/partials/javascripts/outdated.html b/src/partials/javascripts/outdated.html @@ -1,29 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Version warning --> -<script> - var el = document.querySelector("[data-md-component=outdated]") - var outdated = __md_get("__outdated", sessionStorage) - if (outdated === true && el) - el.hidden = false -</script> diff --git a/src/partials/javascripts/palette.html b/src/partials/javascripts/palette.html @@ -1,29 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- User preference: color palette --> -<script> - var palette = __md_get("__palette") - if (palette && typeof palette.color === "object") - for (var key of Object.keys(palette.color)) - document.body.setAttribute("data-md-color-" + key, palette.color[key]) -</script> diff --git a/src/partials/language.html b/src/partials/language.html @@ -1,28 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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 translations for given language and fallback --> -{% import "partials/languages/" ~ config.theme.language ~ ".html" as lang %} -{% import "partials/languages/en.html" as fallback %} - -<!-- Re-export translations --> -{% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %} diff --git a/src/partials/languages/af.html b/src/partials/languages/af.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Afrikaans --> -{% macro t(key) %}{{ { - "language": "af", - "clipboard.copy": "Kopieer na knipbord", - "clipboard.copied": "gekopieer na knipbord", - "edit.link.title": "Wysig hierdie bladsy", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Kommentaar", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Soek", - "search.result.placeholder": "Tik om te begin soek", - "search.result.none": "Geen ooreenstemmende dokumente", - "search.result.one": "1 ooreenstemmende dokument", - "search.result.other": "# ooreenstemmende dokumente", - "skip.link.title": "Slaan oor na inhoud", - "source.link.title": "Slaan oor na inhoud", - "source.file.date.updated": "Laaste opdatering", - "source.file.date.created": "Geskep", - "toc.title": "Inhoudsopgawe" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ar.html b/src/partials/languages/ar.html @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Arabic --> -{% macro t(key) %}{{ { - "language": "ar", - "direction": "rtl", - "clipboard.copy": "نسخ إلى الحافظة", - "clipboard.copied": "تم النسخ الى الحافظة", - "edit.link.title": "عدل الصفحة", - "footer.previous": "السابقة", - "footer.next": "التالية", - "meta.comments": "التعليقات", - "meta.source": "المصدر", - "search.config.pipeline": " ", - "search.placeholder": "بحث", - "search.result.placeholder": "اكتب لبدء البحث", - "search.result.none": "لا توجد نتائج", - "search.result.one": "نتائج البحث مستند واحد", - "search.result.other": "نتائج البحث # مستندات", - "skip.link.title": "انتقل إلى المحتوى", - "source.link.title": "اذهب إلى المصدر", - "source.file.date.updated": "اخر تحديث", - "source.file.date.created": "خلقت", - "toc.title": "جدول المحتويات" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/bg.html b/src/partials/languages/bg.html @@ -1,51 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Bulgarian --> -{% macro t(key) %}{{ { - "language": "bg", - "clipboard.copy": "Копирай", - "clipboard.copied": "Копирано", - "edit.link.title": "Редактирай тази страница", - "footer.previous": "Предишна", - "footer.next": "Следваща", - "footer.title": "Долен колонтитул", - "header.title": "Горен колонтитул", - "meta.comments": "Коментари", - "meta.source": "Код", - "nav.title": "Навигация", - "search.config.lang": "ru", - "search.placeholder": "Търси", - "search.reset": "Изчисти", - "search.result.placeholder": "Започнете да пишете, за да търсите", - "search.result.none": "Няма резултати", - "search.result.one": "1 резултат", - "search.result.other": "# резултата", - "search.result.more.one": "още 1 на тази страница", - "search.result.more.other": "още # на тази страница", - "skip.link.title": "Към съдържанието", - "source.link.title": "Към хранилището", - "source.file.date.updated": "Последна промяна", - "source.file.date.created": "Създаден", - "tabs.title": "Табове", - "toc.title": "Съдържание" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/bn.html b/src/partials/languages/bn.html @@ -1,49 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Bengali (Bangla) --> -{% macro t(key) %}{{ { - "language": "bn", - "clipboard.copy": "ক্লিপবোর্ডে কপি করুন", - "clipboard.copied": "ক্লিপবোর্ডে কপি হয়েছে", - "edit.link.title": "এই পেজ এডিট করুন", - "footer.previous": "পূর্ববর্তী", - "footer.next": "পরে", - "footer.title": "ফুটার", - "header.title": "হেডার", - "meta.comments": "কমেন্ট", - "meta.source": "সোর্স", - "nav.title": "ন্যাভিগেশন", - "search.config.pipeline": " ", - "search.placeholder": "সার্চ", - "search.reset": "মুছে ফেলুন", - "search.result.placeholder": "সার্চ টাইপ করুন", - "search.result.none": "কিছু পাওয়া যায়নি", - "search.result.one": "১ টা ডকুমেন্ট", - "search.result.other": "# টা ডকুমেন্ট", - "skip.link.title": "কনটেন্টে যান", - "source.link.title": "রিপোজিটরিতে যান", - "source.file.date.updated": "শেষ আপডেট", - "source.file.date.created": "তৈরি হয়েছে", - "tabs.title": "ট্যাব", - "toc.title": "টেবিল অফ কনটেন্ট" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ca.html b/src/partials/languages/ca.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Catalan --> -{% macro t(key) %}{{ { - "language": "ca", - "clipboard.copy": "Còpia al porta-retalls", - "clipboard.copied": "Copiat al porta-retalls", - "edit.link.title": "Edita aquesta pàgina", - "footer.previous": "Anterior", - "footer.next": "Següent", - "meta.comments": "Comentaris", - "meta.source": "Codi font", - "search.placeholder": "Cerca", - "search.result.placeholder": "Escriu per a començar a cercar", - "search.result.none": "Cap document coincideix", - "search.result.one": "1 document coincident", - "search.result.other": "# documents coincidents", - "skip.link.title": "Salta el contingut", - "source.link.title": "Ves al repositori", - "source.file.date.updated": "Darrera actualització", - "source.file.date.created": "Creada", - "toc.title": "Taula de continguts" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/cs.html b/src/partials/languages/cs.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Czech --> -{% macro t(key) %}{{ { - "language": "cs", - "clipboard.copy": "Kopírovat do schránky", - "clipboard.copied": "Zkopírováno do schránky", - "edit.link.title": "Upravit tuto stránku", - "footer.previous": "Předchozí", - "footer.next": "Další", - "meta.comments": "Komentáře", - "meta.source": "Zdroj", - "search.placeholder": "Hledat", - "search.result.placeholder": "Pište co se má vyhledat", - "search.result.none": "Nenalezeny žádné dokumenty", - "search.result.one": "Nalezený dokument: 1", - "search.result.other": "Nalezené dokumenty: #", - "skip.link.title": "Přeskočit obsah", - "source.link.title": "Přejít do repozitáře", - "source.file.date.updated": "Poslední aktualizace", - "source.file.date.created": "Vytvořeno", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/da.html b/src/partials/languages/da.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Danish --> -{% macro t(key) %}{{ { - "language": "da", - "clipboard.copy": "Kopiér til udklipsholderen", - "clipboard.copied": "Kopieret til udklipsholderen", - "edit.link.title": "Redigér denne side", - "footer.previous": "Forrige", - "footer.next": "Næste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "da", - "search.placeholder": "Søg", - "search.result.placeholder": "Indtast søgeord", - "search.result.none": "Ingen resultater fundet", - "search.result.one": "1 resultat", - "search.result.other": "# resultater", - "skip.link.title": "Gå til indholdet", - "source.link.title": "Åbn arkiv", - "source.file.date.updated": "Sidste ændring", - "source.file.date.created": "Oprettet", - "toc.title": "Indholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/de.html b/src/partials/languages/de.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: German --> -{% macro t(key) %}{{ { - "language": "de", - "announce.dismiss": "Nicht mehr anzeigen", - "clipboard.copy": "In Zwischenablage kopieren", - "clipboard.copied": "In Zwischenablage kopiert", - "consent.accept": "Akzeptieren", - "consent.manage": "Einstellungen", - "consent.reject": "Ablehnen", - "edit.link.title": "Seite editieren", - "footer.previous": "Zurück", - "footer.next": "Weiter", - "meta.comments": "Kommentare", - "meta.source": "Quellcode", - "search.config.lang": "de", - "search.placeholder": "Suche", - "search.share": "Teilen", - "search.reset": "Zurücksetzen", - "search.result.initializer": "Suche wird initialisiert", - "search.result.placeholder": "Suchbegriff eingeben", - "search.result.none": "Keine Suchergebnisse", - "search.result.one": "1 Suchergebnis", - "search.result.other": "# Suchergebnisse", - "search.result.more.one": "1 weiteres Suchergebnis auf dieser Seite", - "search.result.more.other": "# weitere Suchergebnisse auf dieser Seite", - "search.result.term.missing": "Es fehlt", - "search.title": "Suche", - "select.language.title": "Sprache wechseln", - "select.version.title": "Version auswählen", - "skip.link.title": "Zum Inhalt", - "source.link.title": "Quellcode", - "source.file.date.updated": "Letztes Update", - "source.file.date.created": "Erstellt", - "toc.title": "Inhaltsverzeichnis", - "top.title": "Zurück zum Seitenanfang" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/el.html b/src/partials/languages/el.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Greek --> -{% macro t(key) %}{{ { - "language": "el", - "clipboard.copy": "Αντιγραφή στο πρόχειρο", - "clipboard.copied": "Αντιγράφηκε στο πρόχειρο", - "edit.link.title": "Επεξεργασία αυτής της σελίδας", - "footer.previous": "Προηγούμενο", - "footer.next": "Επόμενο", - "footer.title": "Υποσέλιδο", - "header.title": "Κεφαλίδα", - "meta.comments": "Σχόλια", - "meta.source": "Πηγή", - "nav.title": "Πλοήγηση", - "search.config.pipeline": "stopWordFilter", - "search.placeholder": "Αναζήτηση", - "search.share": "Διαμοίραση", - "search.reset": "Καθαρισμός", - "search.result.initializer": "Αρχικοποίηση αναζήτησης", - "search.result.placeholder": "Πληκτρολογήστε για να αρχίσει η αναζήτηση", - "search.result.none": "Δεν βρέθηκαν αντίστοιχα αρχεία", - "search.result.one": "1 έγγραφο ταιριάζει", - "search.result.other": "# έγγραφα ταιριάζουν", - "search.result.more.one": "1 ακόμα σε αυτήν τη σελίδα", - "search.result.more.other": "# ακόμα σε αυτήν τη σελίδα", - "search.result.term.missing": "Λείπει", - "search.title": "Αναζήτηση", - "select.language.title": "Επιλογή γλώσσας", - "select.version.title": "Επιλογή έκδοσης", - "skip.link.title": "Μετάβαση στο περιεχόμενο", - "source.link.title": "Μετάβαση στο αποθετήριο", - "source.file.date.updated": "τελευταία ενημέρωση", - "source.file.date.created": "Δημιουργήθηκε", - "tabs.title": "Καρτέλες", - "toc.title": "Πίνακας περιεχομένων", - "top.title": "Επιστροφή στην αρχή" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/en.html b/src/partials/languages/en.html @@ -1,65 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: English --> -{% macro t(key) %}{{ { - "language": "en", - "direction": "ltr", - "announce.dismiss": "Don't show this again", - "clipboard.copy": "Copy to clipboard", - "clipboard.copied": "Copied to clipboard", - "consent.accept": "Accept", - "consent.manage": "Manage settings", - "consent.reject": "Reject", - "edit.link.title": "Edit this page", - "footer.previous": "Previous", - "footer.next": "Next", - "footer.title": "Footer", - "header.title": "Header", - "meta.comments": "Comments", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "en", - "search.config.pipeline": "trimmer, stopWordFilter", - "search.config.separator": "[\\s\\-]+", - "search.placeholder": "Search", - "search.share": "Share", - "search.reset": "Clear", - "search.result.initializer": "Initializing search", - "search.result.placeholder": "Type to start searching", - "search.result.none": "No matching documents", - "search.result.one": "1 matching document", - "search.result.other": "# matching documents", - "search.result.more.one": "1 more on this page", - "search.result.more.other": "# more on this page", - "search.result.term.missing": "Missing", - "search.title": "Search", - "select.language.title": "Select language", - "select.version.title": "Select version", - "skip.link.title": "Skip to content", - "source.link.title": "Go to repository", - "source.file.date.updated": "Last update", - "source.file.date.created": "Created", - "tabs.title": "Tabs", - "toc.title": "Table of contents", - "top.title": "Back to top" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/eo.html b/src/partials/languages/eo.html @@ -1,49 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Esperanto --> -{% macro t(key) %}{{ { - "language": "eo", - "clipboard.copy": "Kopii al tondujo", - "clipboard.copied": "Kopiado al klipo", - "edit.link.title": "Redakti ĉi tiun paĝon", - "footer.previous": "Antaŭa", - "footer.next": "Sekva", - "footer.title": "Piedlinio", - "header.title": "Kaplinio", - "meta.comments": "Komentoj", - "meta.source": "Fontkodo", - "nav.title": "Navigado", - "search.config.lang": "es", - "search.placeholder": "Serĉo", - "search.reset": "Klara", - "search.result.placeholder": "Tajpu por komenci serĉadon", - "search.result.none": "Neniuj kongruaj dokumentoj", - "search.result.one": "1 kongrua dokumento", - "search.result.other": "# kongruaj dokumentoj", - "skip.link.title": "Saltu al enhavo", - "source.link.title": "Iru al deponejo", - "source.file.date.updated": "Lasta ĝisdatigo", - "source.file.date.created": "Kreita", - "tabs.title": "Langetoj", - "toc.title": "Enhavtabelo" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/es.html b/src/partials/languages/es.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Spanish --> -{% macro t(key) %}{{ { - "language": "es", - "clipboard.copy": "Copiar al portapapeles", - "clipboard.copied": "Copiado al portapapeles", - "consent.accept": "Aceptar", - "consent.manage": "Gestionar cookies", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Siguiente", - "footer.title": "Pie", - "header.title": "Cabecera", - "meta.comments": "Comentarios", - "meta.source": "Fuente", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Búsqueda", - "search.reset": "Limpiar", - "search.result.initializer": "Inicializando búsqueda", - "search.result.placeholder": "Teclee para comenzar búsqueda", - "search.result.none": "No se encontraron documentos", - "search.result.one": "1 documento encontrado", - "search.result.other": "# documentos encontrados", - "search.result.more.one": "1 más en esta página", - "search.result.more.other": "# más en esta página", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar versión", - "skip.link.title": "Saltar a contenido", - "source.link.title": "Ir al repositorio", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creado", - "tabs.title": "Pestañas", - "toc.title": "Tabla de contenidos", - "top.title": "Volver al principio" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/et.html b/src/partials/languages/et.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Estonian --> -{% macro t(key) %}{{ { - "language": "et", - "clipboard.copy": "Kopeeri lõikelauale", - "clipboard.copied": "Kopeeritud", - "edit.link.title": "Muuda seda lehte", - "footer.previous": "Eelmine", - "footer.next": "Järgmine", - "meta.comments": "Kommentaarid", - "meta.source": "Lähtekood", - "search.placeholder": "Otsi", - "search.result.placeholder": "Otsimiseks kirjuta siia", - "search.result.none": "Otsingule ei leitud ühtegi vastet", - "search.result.one": "Leiti üks tulemus", - "search.result.other": "Leiti # tulemust", - "skip.link.title": "Keri sisuni", - "source.link.title": "Ava repositooriumis", - "source.file.date.updated": "Viimane uuendus", - "source.file.date.created": "Loodud", - "toc.title": "Sisukord" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/fa.html b/src/partials/languages/fa.html @@ -1,45 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Persian (Farsi) --> -{% macro t(key) %}{{ { - "language": "fa", - "direction": "rtl", - "clipboard.copy": "کپی کردن", - "clipboard.copied": "کپی شد", - "edit.link.title": "این صفحه را ویرایش کنید", - "footer.previous": "قبلی", - "footer.next": "بعدی", - "meta.comments": "نظرات", - "meta.source": "منبع", - "search.config.pipeline": " ", - "search.placeholder": "جستجو", - "search.result.placeholder": "برای شروع جستجو تایپ کنید", - "search.result.none": "سندی یافت نشد", - "search.result.one": "1 سند یافت شد", - "search.result.other": "# سند یافت شد", - "skip.link.title": "پرش به محتویات", - "source.link.title": "رفتن به مخزن", - "source.file.date.updated": "اخرین بروزرسانی", - "source.file.date.created": "ایجاد شده", - "toc.title": "فهرست موضوعات" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/fi.html b/src/partials/languages/fi.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Finnish --> -{% macro t(key) %}{{ { - "language": "fi", - "clipboard.copy": "Kopioi leikepöydälle", - "clipboard.copied": "Kopioitu leikepöydälle", - "edit.link.title": "Muokkaa tätä sivua", - "footer.previous": "Edellinen", - "footer.next": "Seuraava", - "meta.comments": "Kommentit", - "meta.source": "Lähdekodi", - "search.config.lang": "fi", - "search.placeholder": "Hae", - "search.result.placeholder": "Kirjoita aloittaaksesi haun", - "search.result.none": "Ei täsmääviä dokumentteja", - "search.result.one": "1 täsmäävä dokumentti", - "search.result.other": "# täsmäävää dokumenttia", - "skip.link.title": "Hyppää sisältöön", - "source.link.title": "Mene repositoryyn", - "source.file.date.updated": "Viimeisin päivitys", - "source.file.date.created": "Luotu", - "toc.title": "Sisällysluettelo" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/fr.html b/src/partials/languages/fr.html @@ -1,59 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: French --> -{% macro t(key) %}{{ { - "language": "fr", - "clipboard.copy": "Copier dans le presse-papier", - "clipboard.copied": "Copié dans le presse-papier", - "consent.accept": "Accepter", - "consent.manage": "Paramétrer vos choix", - "consent.reject": "Refuser", - "edit.link.title": "Editer cette page", - "footer.previous": "Précédent", - "footer.next": "Suivant", - "footer.title": "Pied de page", - "header.title": "En-tête", - "meta.comments": "Commentaires", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "fr", - "search.placeholder": "Rechercher", - "search.reset": "Effacer", - "search.result.initializer": "Initialisation de la recherche", - "search.result.placeholder": "Taper pour démarrer la recherche", - "search.result.none": "Aucun document trouvé", - "search.result.one": "1 document trouvé", - "search.result.other": "# documents trouvés", - "search.result.more.one": "1 de plus sur cette page", - "search.result.more.other": "# de plus sur cette page", - "search.result.term.missing": "Non trouvé", - "select.language.title": "Sélectionner la langue", - "select.version.title": "Sélectionner la version", - "skip.link.title": "Aller au contenu", - "source.link.title": "Aller au dépôt", - "source.file.date.updated": "Dernière mise à jour", - "source.file.date.created": "Créé", - "tabs.title": "Onglets", - "toc.title": "Table des matières", - "top.title": "Retour en haut de la page" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/gl.html b/src/partials/languages/gl.html @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Galician --> -{% macro t(key) %}{{ { - "language": "gl", - "clipboard.copy": "Copiar no cortapapeis", - "clipboard.copied": "Copiado no cortapapeis", - "edit.link.title": "Editar esta páxina", - "footer.previous": "Anterior", - "footer.next": "Seguinte", - "footer.title": "Pé", - "header.title": "Cabeceira", - "meta.comments": "Comentarios", - "meta.source": "Fonte", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Procura", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando procura", - "search.result.placeholder": "Insira un termo", - "search.result.none": "Sen resultados", - "search.result.one": "1 resultado atopado", - "search.result.other": "# resultados atopados", - "search.result.more.one": "1 máis nesta páxina", - "search.result.more.other": "# máis nesta páxina", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar version", - "skip.link.title": "Ir ao contido", - "source.link.title": "Ir ao repositorio", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creada", - "tabs.title": "Pestanas", - "toc.title": "Táboa de contidos", - "top.title": "Volver ao principio" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/he.html b/src/partials/languages/he.html @@ -1,63 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Hebrew --> -{% macro t(key) %}{{ { - "language": "he", - "direction": "rtl", - "announce.dismiss": "לא להציג את זה שוב", - "clipboard.copy": "העתקה ללוח", - "clipboard.copied": "הועתק ללוח", - "consent.accept": "לקבל", - "consent.manage": "לנהל הגדרות", - "consent.reject": "לדחות", - "edit.link.title": "עריכת הדף הזה", - "footer.previous": "הקודם", - "footer.next": "הבא", - "footer.title": "כותרת תחתונה", - "header.title": "כותרת עליונה", - "meta.comments": "הערות", - "meta.source": "מקור", - "nav.title": "ניווט", - "search.config.pipeline": " ", - "search.placeholder": "חיפוש", - "search.share": "שיתוף", - "search.reset": "ניקוי", - "search.result.initializer": "אתחול חיפוש", - "search.result.placeholder": "יש להקליד כדי להתחיל לחפש", - "search.result.none": "אין מסמכים תואמים", - "search.result.one": "1 מסמך תואם", - "search.result.other": "# מסמך תואם", - "search.result.more.one": "עוד אחד בדף הזה", - "search.result.more.other": "עוד # בדף הזה", - "search.result.term.missing": "חסר", - "search.title": "חיפוש", - "select.language.title": "בחירת שפה", - "select.version.title": "בחירת גרסה", - "skip.link.title": "לדלג לתוכן", - "source.link.title": "לעבור אל המאגר", - "source.file.date.updated": "עדכון אחרון", - "source.file.date.created": "נוצר", - "tabs.title": "לשוניות", - "toc.title": "תוכן העניינים", - "top.title": "חזרה למעלה" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/hi.html b/src/partials/languages/hi.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Hindi --> -{% macro t(key) %}{{ { - "language": "hi", - "clipboard.copy": "क्लिपबोर्ड पर कॉपी करें", - "clipboard.copied": "क्लिपबोर्ड पर कॉपी कर दिया गया", - "edit.link.title": "इस पृष्ठ को संपादित करें", - "footer.previous": "पिछला", - "footer.next": "आगामी", - "meta.comments": "टिप्पणियाँ", - "meta.source": "स्रोत", - "search.config.lang": "hi", - "search.placeholder": "खोज", - "search.result.placeholder": "खोज शुरू करने के लिए टाइप करें", - "search.result.none": "कोई मिलान डॉक्यूमेंट नहीं", - "search.result.one": "1 मिलान डॉक्यूमेंट", - "search.result.other": "# मिलान डाक्यूमेंट्स", - "skip.link.title": "विषय पर बढ़ें", - "source.link.title": "रिपॉजिटरी पर जाएं", - "source.file.date.updated": "आखिरी अपडेट", - "source.file.date.created": "बनाया था", - "toc.title": "विषय - सूची" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/hr.html b/src/partials/languages/hr.html @@ -1,61 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Croatian --> -{% macro t(key) %}{{ { - "language": "hr", - "announce.dismiss": "Ne prikazuj ovo opet", - "clipboard.copy": "Kopirajte u međuspremnik", - "clipboard.copied": "Kopirano u međuspremnik", - "consent.accept": "Prihvati", - "consent.manage": "Upravljaj postavkama", - "consent.reject": "Odbij", - "edit.link.title": "Uredi stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sljedeće", - "footer.title": "Podnožje", - "header.title": "Zaglavlje", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "nav.title": "Navigacija", - "search.placeholder": "Pretraživanje", - "search.share": "Podijeli", - "search.reset": "Očisti", - "search.result.initializer": "Inicijaliziranje pretraživanja", - "search.result.placeholder": "Unesite pojam pretraživanja", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretraživanja", - "search.result.other": "# rezultata pretraživanja", - "search.result.more.one": "1 rezultat na ovoj stranici", - "search.result.more.other": "# rezultata na ovoj stranici", - "search.result.term.missing": "Nedostaje", - "search.title": "Pretraživanje", - "select.language.title": "Odabir jezika", - "select.version.title": "Odabir verzije", - "skip.link.title": "Preskočite na sadržaj", - "source.link.title": "Idite u repozitorij", - "source.file.date.updated": "Zadnje ažuriranje", - "source.file.date.created": "Stvoreno", - "tabs.title": "Kartice", - "toc.title": "Sadržaj", - "top.title": "Vratite se na vrh" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/hu.html b/src/partials/languages/hu.html @@ -1,53 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Hungarian --> -{% macro t(key) %}{{ { - "language": "hu", - "clipboard.copy": "Másolás vágólapra", - "clipboard.copied": "Vágólapra másolva", - "edit.link.title": "Oldal szerkesztése", - "footer.previous": "Előző", - "footer.next": "Következő", - "footer.title": "Élőláb", - "header.title": "Élőfej", - "meta.comments": "Hozzászólások", - "meta.source": "Forrás", - "nav.title": "Navigáció", - "search.config.lang": "hu", - "search.placeholder": "Keresés", - "search.reset": "Törlés", - "search.result.initializer": "Keresés inicializálása", - "search.result.placeholder": "Kereséshez írj ide valamit", - "search.result.none": "Nincs találat", - "search.result.one": "1 egyező dokumentum", - "search.result.other": "# egyező dokumentum", - "search.result.more.one": "1 további találat az oldalon", - "search.result.more.other": "# további találat az oldalon", - "search.result.term.missing": "Üres", - "skip.link.title": "Kihagyás", - "source.link.title": "Főoldalra ugrás", - "source.file.date.updated": "Utolsó frissítés", - "source.file.date.created": "Létrehozva", - "tabs.title": "Lapok", - "toc.title": "Tartalomjegyzék" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/hy.html b/src/partials/languages/hy.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Armenian --> -{% macro t(key) %}{{ { - "language": "hy", - "clipboard.copy": "Պատճենել", - "clipboard.copied": "Պատճենված է", - "edit.link.title": "Խմբագրել այս էջը", - "footer.previous": "Նախորդը", - "footer.next": "Հաջորդը", - "footer.title": "Վերջնագիր", - "header.title": "Գլխագիր", - "meta.comments": "Մեկնաբանությունները", - "meta.source": "Աղբյուր", - "nav.title": "Տեղորոշում", - "search.config.pipeline": " ", - "search.placeholder": "Փնտրել", - "search.share": "Կիսվել", - "search.reset": "Ջնջել", - "search.result.initializer": "Փնտրում", - "search.result.placeholder": "Մուտքագրեք փնտրելու համար", - "search.result.none": "Համապատասխանություններ չկան", - "search.result.one": "1 համապատասխանություն", - "search.result.other": "# համապատասխանություններ", - "search.result.more.one": "ևս 1-ը այս էջում", - "search.result.more.other": "ևս #-ը այս էջում", - "search.result.term.missing": "Բացակայում է", - "search.title": "Փնտրում", - "select.language.title": "Ընտրել լեզուն", - "select.version.title": "Ընտրել տարբերակը", - "skip.link.title": "Անցնել պարունակությանը", - "source.link.title": "Դեպի պահոց", - "source.file.date.updated": "Վերջին թարմացումը", - "source.file.date.created": "Ստեղծված է", - "tabs.title": "Ներդիրներ", - "toc.title": "Բովանդակություն", - "top.title": "Վերադառնալ սկիզբ" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/id.html b/src/partials/languages/id.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Indonesian --> -{% macro t(key) %}{{ { - "language": "id", - "clipboard.copy": "Salin ke memori", - "clipboard.copied": "Tersalin ke memori", - "edit.link.title": "Ubah halaman ini", - "footer.previous": "Sebelumnya", - "footer.next": "Selanjutnya", - "meta.comments": "Komentar", - "meta.source": "Sumber", - "search.config.pipeline": " ", - "search.placeholder": "Cari", - "search.result.placeholder": "Ketik untuk mulai pencarian", - "search.result.none": "Tidak ada dokumen yang sesuai", - "search.result.one": "1 dokumen ditemukan", - "search.result.other": "# dokumen ditemukan", - "skip.link.title": "Lewati ke isi", - "source.link.title": "Menuju repositori", - "source.file.date.created": "Dibuat", - "toc.title": "Daftar isi" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/is.html b/src/partials/languages/is.html @@ -1,50 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Icelandic --> -{% macro t(key) %}{{ { - "language": "is", - "clipboard.copy": "Afrita í klemmuspjald", - "clipboard.copied": "Afritað í klemmuspjald", - "edit.link.title": "Ritvinna þessa síðu", - "footer.previous": "Fyrra", - "footer.next": "Næsta", - "footer.title": "Síðufótur", - "header.title": "Haus", - "meta.comments": "Athugasemdir", - "meta.source": "Grunnur", - "nav.title": "Valmynd", - "search.placeholder": "Leit", - "search.reset": "Hreinsa", - "search.result.placeholder": "Sláðu inn til að hefja leit", - "search.result.none": "Engin skjöl fundust", - "search.result.one": "1 skjal fannst", - "search.result.other": "# skjöl fundust", - "search.result.more.one": "1 til viðbótar á þessari síðu", - "search.result.more.other": "# til viðbótar á þessari síðu", - "skip.link.title": "Hoppa yfir í efni", - "source.link.title": "Fara í gagnahirslu (e. repository)", - "source.file.date.updated": "Síðasta uppfærsla", - "source.file.date.created": "Búið til", - "tabs.title": "Flipar", - "toc.title": "Efnisyfirlit" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/it.html b/src/partials/languages/it.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Italian --> -{% macro t(key) %}{{ { - "language": "it", - "clipboard.copy": "Copia", - "clipboard.copied": "Copiato", - "edit.link.title": "Modifica", - "footer.previous": "Precedente", - "footer.next": "Prossimo", - "footer.title": "Piede", - "header.title": "Intestazione", - "meta.comments": "Commenti", - "meta.source": "Sorgente", - "nav.title": "Navigazione", - "search.config.lang": "it", - "search.placeholder": "Cerca", - "search.share": "Condividi", - "search.reset": "Cancella", - "search.result.initializer": "Inizializza la ricerca", - "search.result.placeholder": "Scrivi per iniziare a cercare", - "search.result.none": "Nessun documento trovato", - "search.result.one": "1 documento trovato", - "search.result.other": "# documenti trovati", - "search.result.more.one": "1 altro in questa pagina", - "search.result.more.other": "# altri in questa pagina", - "search.result.term.missing": "Non presente", - "search.title": "Cerca", - "select.language.title": "Seleziona la lingua", - "select.version.title": "Seleziona la versione", - "skip.link.title": "Vai al contenuto", - "source.link.title": "Apri repository", - "source.file.date.updated": "Ultimo aggiornamento", - "source.file.date.created": "Creata", - "tabs.title": "Tabs", - "toc.title": "Indice", - "top.title": "Torna su" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ja.html b/src/partials/languages/ja.html @@ -1,55 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Japanese --> -{% macro t(key) %}{{ { - "language": "ja", - "clipboard.copy": "クリップボードへコピー", - "clipboard.copied": "コピーしました", - "edit.link.title": "編集", - "footer.previous": "前", - "footer.next": "次", - "footer.title": "フッター", - "header.title": "ヘッダー", - "meta.comments": "コメント", - "meta.source": "ソース", - "nav.title": "ナビゲーション", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\\s\\- 、。,.]+", - "search.placeholder": "検索", - "search.reset": "クリア", - "search.result.initializer": "検索を初期化", - "search.result.placeholder": "検索キーワードを入力してください", - "search.result.none": "何も見つかりませんでした", - "search.result.one": "1件見つかりました", - "search.result.other": "#件見つかりました", - "search.result.more.one": "このページ内にもう1件見つかりました", - "search.result.more.other": "このページ内にあと#件見つかりました", - "search.result.term.missing": "検索に含まれない", - "skip.link.title": "コンテンツにスキップ", - "source.link.title": "リポジトリへ", - "source.file.date.updated": "最終更新日", - "source.file.date.created": "作成した", - "tabs.title": "タブ", - "toc.title": "目次" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ka.html b/src/partials/languages/ka.html @@ -1,49 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Georgian --> -{% macro t(key) %}{{ { - "language": "ka", - "clipboard.copy": "კოპირება", - "clipboard.copied": "კოპირებულია", - "edit.link.title": "გვერდის რედარქირება", - "footer.previous": "წინა", - "footer.next": "შემდეგი", - "meta.comments": "კომენტარები", - "meta.source": "წყარო", - "nav.title": "ნავიგაცია", - "search.config.pipeline": " ", - "search.placeholder": "ძებნა", - "search.reset": "გასუფთავება", - "search.result.placeholder": "ჩაწერე ძებნის დასაწყებად", - "search.result.none": "დოკუმენტი ვერ მოიძებნა", - "search.result.one": "მოიძებნა 1 დოკუმენტი", - "search.result.other": "მოიძებნა # დოკუმენტი", - "search.result.more.one": "კიდევ 1 ამ გვერდზე", - "search.result.more.other": "კიდევ # ამ გვერდზე", - "skip.link.title": "კონტენტზე გადასვლა", - "source.link.title": "საცავში გადასვლა", - "source.file.date.updated": "ბოლო განახლება", - "source.file.date.created": "შეიქმნა", - "tabs.title": "ტაბები", - "toc.title": "სარჩევი" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/kr.html b/src/partials/languages/kr.html @@ -1,54 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Korean --> -{% macro t(key) %}{{ { - "language": "kr", - "clipboard.copy": "클립보드로 복사", - "clipboard.copied": "클립보드에 복사됨", - "edit.link.title": "이 페이지를 편집", - "footer.previous": "이전", - "footer.next": "다음", - "meta.comments": "댓글", - "meta.source": "출처", - "search.config.pipeline": " ", - "search.placeholder": "검색", - "search.share": "공유", - "search.reset": "지우기", - "search.result.initializer": "검색 초기화", - "search.result.placeholder": "검색어를 입력하세요", - "search.result.none": "검색어와 일치하는 문서가 없습니다", - "search.result.one": "1개의 일치하는 문서", - "search.result.other": "#개의 일치하는 문서", - "search.result.more.one": "이 문서에서 1개의 검색 결과 더 보기", - "search.result.more.other": "이 문서에서 #개의 검색 결과 더 보기", - "search.result.term.missing": "포함되지 않은 검색어", - "search.title": "검색", - "select.language.title": "언어설정", - "select.version.title": "버전 선택", - "skip.link.title": "콘텐츠로 이동", - "source.link.title": "저장소로 이동", - "source.file.date.updated": "마지막 업데이트", - "source.file.date.created": "작성일", - "toc.title": "목차", - "top.title": "맨위로" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/lt.html b/src/partials/languages/lt.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Lithuanian --> -{% macro t(key) %}{{ { - "language": "lt", - "clipboard.copy": "Kopijuoti į iškarpinę", - "clipboard.copied": "Nukopijuota į iškarpinę", - "edit.link.title": "Redaguoti šį puslapį", - "footer.previous": "Ankstesnis", - "footer.next": "Sekantis", - "footer.title": "Poraštė", - "header.title": "Antraštė", - "meta.comments": "Komentarai", - "meta.source": "Išeitinis kodas", - "nav.title": "Navigacija", - "search.config.pipeline": " ", - "search.placeholder": "Paieška", - "search.share": "Dalintis", - "search.reset": "Išvalyti", - "search.result.initializer": "Paieškos inicijavimas", - "search.result.placeholder": "Įveskite norėdami pradėti paiešką", - "search.result.none": "Atitinkančių dokumentų nerasta", - "search.result.one": "1 atitinkantis dokumentas", - "search.result.other": "# atitinkantys dokumentai", - "search.result.more.one": "Dar 1 šiame puslapyje", - "search.result.more.other": "Dar # šiame puslapyje", - "search.result.term.missing": "Nerasta", - "search.title": "Paieška", - "select.language.title": "Pasirinkti kalbą", - "select.version.title": "Pasrinkti versiją", - "skip.link.title": "Pereiti prie turinio", - "source.link.title": "Eiti į saugyklą", - "source.file.date.updated": "Paskutinis atnaujinimas", - "source.file.date.created": "Sukurta", - "tabs.title": "Skirtukai", - "toc.title": "Turinys", - "top.title": "Grįžti į viršų" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/lv.html b/src/partials/languages/lv.html @@ -1,55 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Latvian --> -{% macro t(key) %}{{ { - "language": "lv", - "clipboard.copy": "Kopēt starpliktuvē", - "clipboard.copied": "Kopēts starpliktuvē", - "edit.link.title": "Rediģēt šo lapu", - "footer.previous": "Iepriekšējais", - "footer.next": "Nākamais", - "footer.title": "Kājene", - "header.title": "Galvene", - "meta.comments": "Komentārs", - "meta.source": "Avots", - "nav.title": "Navigācija", - "search.placeholder": "Meklēt", - "search.reset": "Notīrīt", - "search.result.initializer": "Notiek meklēšanas inicializācija", - "search.result.placeholder": "Ierakstiet, lai sāktu meklēšanu", - "search.result.none": "Nav atbilstošu dokumentu", - "search.result.one": "1 atbilstošs dokuments", - "search.result.other": "# atbilstoši dokumenti ", - "search.result.more.one": "1 šajā lapā", - "search.result.more.other": "# un vairāk šajā lapā", - "search.result.term.missing": "Trūkstošs", - "select.language.title": "Izvēlies valodu", - "select.version.title": "Izvēlies versiju", - "skip.link.title": "Pāriet uz saturu", - "source.link.title": "Doties uz repozitoriju", - "source.file.date.updated": "Pēdējoreiz atjaunots", - "source.file.date.created": "Izveidots", - "tabs.title": "Cilnes", - "toc.title": "Satura rādītājs", - "top.title": "Atpakaļ uz augšu" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/mk.html b/src/partials/languages/mk.html @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Macedonian --> -{% macro t(key) %}{{ { - "language": "mk", - "clipboard.copy": "Копирај во таблата", - "clipboard.copied": "Копирано", - "edit.link.title": "Уредете ја оваа страница", - "footer.previous": "Претходно", - "footer.next": "Следно", - "footer.title": "Подножје", - "header.title": "Заглавје", - "meta.comments": "Коментари", - "meta.source": "Извор", - "nav.title": "Наслов за навигација", - "search.config.lang": "ru", - "search.placeholder": "Пребарување", - "search.reset": "Чисти", - "search.result.initializer": "Иницијализирање на пребарувањето", - "search.result.placeholder": "Напишете за да започнете со пребарување", - "search.result.none": "Нема соодветни документи", - "search.result.one": "1 документ што се совпаѓа", - "search.result.other": "# соодветни документи", - "search.result.more.one": "Уште 1 на оваа страница", - "search.result.more.other": "Уште # на оваа страница", - "search.result.term.missing": "Недостасува", - "select.language.title": "Изберете јазик", - "select.version.title": "Изберете верзија", - "skip.link.title": "Прескокнете до содржината", - "source.link.title": "Одете до складиштето", - "source.file.date.updated": "Последно ажурирање", - "source.file.date.created": "Создаден", - "tabs.title": "Јазичиња", - "toc.title": "Содржина", - "top.title": "Вратете се на почетокот" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/mn.html b/src/partials/languages/mn.html @@ -1,51 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Mongolian --> -{% macro t(key) %}{{ { - "language": "mn", - "clipboard.copy": "Хуулах", - "clipboard.copied": "Санах ойд хуулах", - "edit.link.title": "Хуудас засварлах", - "footer.previous": "Өмнөх", - "footer.next": "Дараах", - "footer.title": "Хөл", - "header.title": "Толгой", - "meta.comments": "Сэтгэгдэл", - "meta.source": "Эх үүсвэр", - "nav.title": "Чиглүүлэгч", - "search.config.lang": "ru", - "search.placeholder": "Хайлт", - "search.reset": "Цэвэрлэх", - "search.result.placeholder": "Хайлтын үгээ бичнэ үү", - "search.result.none": "Таарц илэрсэнгүй", - "search.result.one": "1 таарц илэрлээ", - "search.result.other": "# Тохирох баримт бичиг", - "search.result.more.one": "1 илүү хуудас байна", - "search.result.more.other": "# илүү хуудас байна", - "skip.link.title": "Агуулгыг алгасах", - "source.link.title": "Хадгалах сан руу очих", - "source.file.date.updated": "Сүүлийн шинэчлэлт", - "source.file.date.created": "Үүсгэсэн", - "tabs.title": "Табууд", - "toc.title": "Агуулга" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ms.html b/src/partials/languages/ms.html @@ -1,55 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Bahasa Malaysia --> -{% macro t(key) %}{{ { - "language": "ms", - "clipboard.copy": "Salin ke papan keratan", - "clipboard.copied": "Disalin ke papan keratan", - "edit.link.title": "Edit halaman ini", - "footer.previous": "Sebelumnya", - "footer.next" : "Seterusnya", - "footer.title": "Pengaki", - "header.title": "Pengepala", - "meta.comments": "Komen", - "meta.source": "Sumber", - "nav.title": "Navigasi", - "search.placeholder": "Cari", - "search.reset": "Padam", - "search.result.initializer": "Siap carian", - "search.result.placeholder": "Taip untuk mula mencari", - "search.result.none": "Tiada dokumen yang sepadan", - "search.result.one": "1 dokumen yang sepadan", - "search.result.other": "# dokumen yang sepadan", - "search.result.more.one": "1 lagi di halaman ini", - "search.result.more.other": "# lagi di halaman ini", - "search.result.term.missing": "Hilang", - "select.language.title": "Pilih bahasa", - "select.version.title": "Pilih versi", - "skip.link.title": "Langkau tajuk talian", - "source.link.title": "tajuk talian asal", - "source.file.date.updated": "Tarikh fil dikemas kini", - "source.file.date.created": "tarikh fil asal dicipta", - "tabs.title": "Tab", - "toc.title": "Jadual kandungan", - "top.title": "Kembali ke atas" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/my.html b/src/partials/languages/my.html @@ -1,49 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Burmese --> -{% macro t(key) %}{{ { - "language": "my", - "clipboard.copy": "ကလစ်ဘုတ် သို့ ကူးယူရန်", - "clipboard.copied": "ကလစ်ဘုတ် သို့ ကူယူပြီး", - "edit.link.title": "ဤ စာမျက်နှာကို ပြင်ရန်", - "footer.previous": "နောက်သို့", - "footer.next": "ရှေ့သို့", - "footer.title": "အောက်ခြေ", - "header.title": "ခေါင်းပိုင်း", - "meta.comments": "မှတ်ချက်များ", - "meta.source": "ရင်းမြစ်", - "nav.title": "လမ်းညွှန်", - "search.config.pipeline": " ", - "search.placeholder": "ရှာရန်", - "search.reset": "ရှင်းလင်း", - "search.result.placeholder": "ရှာဖွေခြင်းစရန် စာရိုက်ပါ", - "search.result.none": "တူညီသော စာရွက်စာတမ်းများ မရှိပါ", - "search.result.one": "စာရွက်စာတမ်း ၁ ခု တူညီသည်", - "search.result.other": "စာရွက်စာတမ်း # ခု တူညီသည်", - "skip.link.title": "မာတိကာ သို့ သွားရန်", - "source.link.title": "repository သို့ သွားရန်", - "source.file.date.updated": "နောက်ဆုံး ထုတ်ပြန်ချက်", - "source.file.date.created": "နေပြည်တော်", - "tabs.title": "တက်များ", - "toc.title": "ပါဝင်အကြောင်းအရာများ" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/nl.html b/src/partials/languages/nl.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Dutch --> -{% macro t(key) %}{{ { - "language": "nl", - "clipboard.copy": "Kopiëren naar klembord", - "clipboard.copied": "Gekopieerd naar klembord", - "edit.link.title": "Wijzig deze pagina", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Reacties", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Zoeken", - "search.result.placeholder": "Typ om te beginnen met zoeken", - "search.result.none": "Geen overeenkomende documenten", - "search.result.one": "1 overeenkomende document", - "search.result.other": "# overeenkomende documenten", - "skip.link.title": "Ga naar inhoud", - "source.link.title": "Ga naar repository", - "source.file.date.updated": "Laatst geüpdatet", - "source.file.date.created": "Gecreëerd", - "toc.title": "Inhoudsopgave" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/nn.html b/src/partials/languages/nn.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Norwegian Nynorsk --> -{% macro t(key) %}{{ { - "language": "nn", - "clipboard.copy": "Kopier til utklippstavla", - "clipboard.copied": "Kopiert til utklippstavla", - "edit.link.title": "Rediger denne sida", - "footer.previous": "Førre", - "footer.next": "Neste", - "meta.comments": "Kommentarar", - "meta.source": "Kjelde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhald", - "source.link.title": "Gå til kjelde", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Laget", - "toc.title": "Innhaldsliste" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/no.html b/src/partials/languages/no.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Norwegian Bokmål --> -{% macro t(key) %}{{ { - "language": "no", - "clipboard.copy": "Kopier til utklippstavlen", - "clipboard.copied": "Kopiert til utklippstavlen", - "edit.link.title": "Rediger denne siden", - "footer.previous": "Forrige", - "footer.next": "Neste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhold", - "source.link.title": "Gå til kilde", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Created", - "toc.title": "Innholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/pl.html b/src/partials/languages/pl.html @@ -1,53 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Polish --> -{% macro t(key) %}{{ { - "language": "pl", - "clipboard.copy": "Kopiuj do schowka", - "clipboard.copied": "Skopiowane", - "edit.link.title": "Edytuj tę stronę", - "footer.previous": "Poprzednia strona", - "footer.next": "Następna strona", - "footer.title": "Stopka", - "header.title": "Nagłówek", - "meta.comments": "Komentarze", - "meta.source": "Kod źródłowy", - "search.config.pipeline": " ", - "nav.title": "Nawigacja", - "search.placeholder": "Szukaj", - "search.reset": "Wyczyść", - "search.result.initializer": "Inicjowanie wyszukiwania", - "search.result.placeholder": "Zacznij pisać, aby szukać", - "search.result.none": "Brak wyników wyszukiwania", - "search.result.one": "Wyniki wyszukiwania: 1", - "search.result.other": "Wyniki wyszukiwania: #", - "search.result.more.one": "1 więcej na tej stronie", - "search.result.more.other": "# więcej na tej stronie", - "search.result.term.missing": "Brak", - "skip.link.title": "Przejdź do treści", - "source.link.title": "Idź do repozytorium", - "source.file.date.updated": "Ostatnia aktualizacja", - "source.file.date.created": "Utworzony", - "tabs.title": "Zakładki", - "toc.title": "Spis treści" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/pt-BR.html b/src/partials/languages/pt-BR.html @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Portuguese (Brasilian) --> -{% macro t(key) %}{{ { - "language": "pt", - "clipboard.copy": "Copiar para área de Transferência", - "clipboard.copied": "Copiado para área de Transferência", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Próximo", - "footer.title": "Rodapé", - "header.title": "Cabeçalho", - "meta.comments": "Comentários", - "meta.source": "Origem", - "nav.title": "Navegação", - "search.config.lang": "pt", - "search.placeholder": "Buscar", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando busca", - "search.result.placeholder": "Digite para iniciar a busca", - "search.result.none": "Nenhum documento encontrado", - "search.result.one": "1 documento encontrado", - "search.result.other": "# documentos encontrados", - "search.result.more.one": "1 more on this page", - "search.result.more.other": "# more on this page", - "search.result.term.missing": "Perdido", - "search.title": "Pesquisar", - "select.language.title": "Selecione a linguagem", - "select.version.title": "Selecione a versão", - "skip.link.title": "Pular para conteúdo", - "source.link.title": "Ir para repositório", - "source.file.date.updated": "Ultima atualização", - "source.file.date.created": "Criado em", - "tabs.title": "Abas", - "toc.title": "Indice", - "top.title": "Voltar para o topo" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/pt.html b/src/partials/languages/pt.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Portuguese --> -{% macro t(key) %}{{ { - "language": "pt", - "clipboard.copy": "Copiar para área de transferência", - "clipboard.copied": "Copiado para área de transferência", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Próximo", - "footer.title": "Rodapé", - "header.title": "Cabeçalho", - "meta.comments": "Comentários", - "meta.source": "Fonte", - "nav.title": "Navegação", - "search.config.lang": "pt", - "search.placeholder": "Buscar", - "search.share": "Compartilhar", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando a pesquisa", - "search.result.placeholder": "Digite para iniciar a busca", - "search.result.none": "Nenhum resultado encontrado", - "search.result.one": "1 resultado encontrado", - "search.result.other": "# resultados encontrados", - "search.result.more.one": "Mais 1 nesta página", - "search.result.more.other": "Mais # nesta página", - "search.result.term.missing": "Ausente", - "search.title": "Pesquisar", - "select.language.title": "Selecione o idioma", - "select.version.title": "Selecione a versão", - "skip.link.title": "Ir para o conteúdo", - "source.link.title": "Ir ao repositório", - "source.file.date.updated": "Última atualização", - "source.file.date.created": "Criada", - "tabs.title": "Abas", - "toc.title": "Índice", - "top.title": "Voltar ao topo" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ro.html b/src/partials/languages/ro.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Romanian --> -{% macro t(key) %}{{ { - "language": "ro", - "clipboard.copy": "Copiază în clipboard", - "clipboard.copied": "Copiat în clipboard", - "edit.link.title": "Editeaza această pagină", - "footer.previous": "Anterior", - "footer.next": "Următor", - "meta.comments": "Comentarii", - "meta.source": "Sursă", - "search.config.lang": "ro", - "search.placeholder": "Căutare", - "search.result.placeholder": "Tastează pentru a începe căutarea", - "search.result.none": "Nu a fost găsit niciun document", - "search.result.one": "1 document găsit", - "search.result.other": "# documente găsite", - "skip.link.title": "Sari la conținut", - "source.link.title": "Accesează repository-ul", - "source.file.date.updated": "Ultima actualizare", - "source.file.date.created": "Creată", - "toc.title": "Cuprins" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ru.html b/src/partials/languages/ru.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Russian --> -{% macro t(key) %}{{ { - "language": "ru", - "clipboard.copy": "Копировать в буфер", - "clipboard.copied": "Скопировано в буфер", - "edit.link.title": "Редактировать страницу", - "footer.previous": "Назад", - "footer.next": "Вперед", - "footer.title": "Нижний колонтитул", - "header.title": "Верхний колонтитул", - "meta.comments": "Комментарии", - "meta.source": "Исходный код", - "nav.title": "Навигация", - "search.config.lang": "ru", - "search.placeholder": "Поиск", - "search.share": "Поделиться", - "search.reset": "Очистить", - "search.result.initializer": "Инициализация поиска", - "search.result.placeholder": "Начните печатать для поиска", - "search.result.none": "Совпадений не найдено", - "search.result.one": "Найдено 1 совпадение", - "search.result.other": "Найдено совпадений: #", - "search.result.more.one": "Ещё 1 на этой странице", - "search.result.more.other": "Ещё # на этой странице", - "search.result.term.missing": "Отсутствует", - "search.title": "Поиск", - "select.language.title": "Выберите язык", - "select.version.title": "Выберите версию", - "skip.link.title": "Перейти к содержанию", - "source.link.title": "Перейти к репозиторию", - "source.file.date.updated": "Последнее обновление", - "source.file.date.created": "Дата создания", - "tabs.title": "Вкладки", - "toc.title": "Содержание раздела", - "top.title": "К началу" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/sh.html b/src/partials/languages/sh.html @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Serbo-Croatian --> -{% macro t(key) %}{{ { - "language": "sh", - "clipboard.copy": "Kopiraj u klipbord", - "clipboard.copied": "Iskopirano u klipbord", - "edit.link.title": "Ažuriraj stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sledeće", - "footer.title": "Podnožje", - "header.title": "Zaglavlje", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "nav.title": "Navigacija", - "search.placeholder": "Pretraga", - "search.share": "Deljenje", - "search.reset": "Očisti", - "search.result.initializer": "Inicijalizujem pretragu", - "search.result.placeholder": "Unesite pojam pretrage", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretrage", - "search.result.other": "# rezultata pretrage", - "search.result.more.one": "još 1 na ovoj strani", - "search.result.more.other": "još # na ovoj strani", - "search.result.term.missing": "Nedostaje", - "search.title": "Pretraga", - "select.language.title": "Izaberi jezik", - "select.version.title": "Izaberi verziju", - "skip.link.title": "Idi na tekst", - "source.link.title": "Idi u repozitorijum", - "source.file.date.updated": "Ažuriran", - "source.file.date.created": "Kreiran", - "tabs.title": "Tabovi", - "toc.title": "Sadržaj", - "top.title": "Nazad na vrh" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/si.html b/src/partials/languages/si.html @@ -1,51 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Sinhalese --> -{% macro t(key) %}{{ { - "language": "si", - "clipboard.copy": "කොපි කරන්න", - "clipboard.copied": "කොපි කළා", - "edit.link.title": "පිටුව සංස්කරණය", - "footer.previous": "පසුගිය", - "footer.next": "මීළඟ", - "footer.title": "පාදම", - "header.title": "ශීර්ෂය", - "meta.comments": "ප්‍රතිචාර", - "meta.source": "මූලාශ්‍රය", - "nav.title": "යාත්‍රණය", - "search.config.pipeline": " ", - "search.placeholder": "සොයන්න", - "search.reset": "මකන්න", - "search.result.placeholder": "සෙවීමට ටයිප් කරන්න", - "search.result.none": "කිසිවක් හමු නොවුණි", - "search.result.one": "1 ගැලපෙන ගොනුවක්", - "search.result.other": "ගැලපෙන ගොනු # ක්", - "search.result.more.one": "තව 1 ප්‍රතිඵලයක්", - "search.result.more.other": "තව ප්‍රතිඵල # ක්", - "skip.link.title": "අන්තර්ගතය වෙත යන්න", - "source.link.title": "රිපොසිටරියට යන්න", - "source.file.date.updated": "අවසන් යාවත්කාලීන වීම", - "source.file.date.created": "ٺاھيو ويو", - "tabs.title": "ටැබ්ස්", - "toc.title": "පටුන" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/sk.html b/src/partials/languages/sk.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Slovak --> -{% macro t(key) %}{{ { - "language": "sk", - "clipboard.copy": "Kopírovať do schránky", - "clipboard.copied": "Skopírované do schránky", - "edit.link.title": "Upraviť túto stránku", - "footer.previous": "Späť", - "footer.next": "Ďalej", - "meta.comments": "Komentáre", - "meta.source": "Zdroj", - "search.placeholder": "Hľadať", - "search.result.placeholder": "Pre vyhľadávanie začni písať", - "search.result.none": "Žiadne vyhovujúce dokumenty", - "search.result.one": "Vyhovujúci dokument: 1", - "search.result.other": "Vyhovujúce dokumenty: #", - "skip.link.title": "Preskočiť na obsah", - "source.link.title": "Zobraziť repozitár", - "source.file.date.updated": "Posledná aktualizácia", - "source.file.date.created": "Vytvorené", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/sl.html b/src/partials/languages/sl.html @@ -1,43 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Slovenian --> -{% macro t(key) %}{{ { - "language": "sl", - "clipboard.copy": "Kopiraj v odložišče", - "clipboard.copied": "Kopirano v odložišče", - "edit.link.title": "Uredi stran", - "footer.previous": "Prejšnja stran", - "footer.next": "Naslednja stran", - "meta.comments": "Komentarji", - "meta.source": "Izvorna koda", - "search.placeholder": "Išči", - "search.result.placeholder": "Vpiši iskalni niz", - "search.result.none": "Ni zadetkov", - "search.result.one": "1 zadetek", - "search.result.other": "# zadetkov", - "skip.link.title": "Skoči na vsebino", - "source.link.title": "Pojdi na repozitorij", - "source.file.date.updated": "Zadnja posodobitev", - "source.file.date.created": "Ustvarjeno", - "toc.title": "Kazalo" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/sr.html b/src/partials/languages/sr.html @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Serbian --> -{% macro t(key) %}{{ { - "language": "sr", - "clipboard.copy": "Копирај у клипборд", - "clipboard.copied": "Ископирано у клипборд", - "edit.link.title": "Ажурирај страницу", - "footer.previous": "Претходно", - "footer.next": "Следеће", - "footer.title": "Подножје", - "header.title": "Заглавље", - "meta.comments": "Коментари", - "meta.source": "Извор", - "nav.title": "Навигација", - "search.placeholder": "Претрага", - "search.share": "Дељење", - "search.reset": "Очисти", - "search.result.initializer": "Иницијализујем претрагу", - "search.result.placeholder": "Унесите појам претраге", - "search.result.none": "Ништа није пронађено", - "search.result.one": "1 резултат претраге", - "search.result.other": "# резултата претраге", - "search.result.more.one": "још 1 на овој страни", - "search.result.more.other": "још # на овој страни", - "search.result.term.missing": "Недостаје", - "search.title": "Претрага", - "select.language.title": "Изабери језик", - "select.version.title": "Изабери верзију", - "skip.link.title": "Иди на текст", - "source.link.title": "Иди у репозиторијум", - "source.file.date.updated": "Ажуриран", - "source.file.date.created": "Креиран", - "tabs.title": "Табови", - "toc.title": "Садржај", - "top.title": "Назад на врх" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/sv.html b/src/partials/languages/sv.html @@ -1,60 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Swedish --> -{% macro t(key) %}{{ { - "language": "sv", - "clipboard.copy": "Kopiera till urklipp", - "clipboard.copied": "Kopierat till urklipp", - "consent.accept": "Acceptera", - "consent.manage": "Hantera inställningar", - "edit.link.title": "Redigera sidan", - "footer.previous": "Föregående", - "footer.next": "Nästa", - "footer.title": "Sidfot", - "header.title": "Sidhuvud", - "meta.comments": "Kommentarer", - "meta.source": "Källa", - "nav.title": "Navigation", - "search.config.lang": "sv", - "search.placeholder": "Sök", - "search.share": "Dela", - "search.reset": "Rensa", - "search.result.initializer": "Initialiserar sök", - "search.result.placeholder": "Skriv sökord", - "search.result.none": "Inga sökresultat", - "search.result.one": "1 sökresultat", - "search.result.other": "# sökresultat", - "search.result.more.one": "1 till på denna sidan", - "search.result.more.other": "# till på denna sidan", - "search.result.term.missing": "Saknas", - "search.title": "Sök", - "select.language.title": "Välj språk", - "select.version.title": "Välj version", - "skip.link.title": "Gå till innehållet", - "source.link.title": "Gå till datakatalog", - "source.file.date.updated": "Senaste uppdaterad", - "source.file.date.created": "Skapad", - "tabs.title": "Flikar", - "toc.title": "Innehållsförteckning", - "top.title": "Tillbaka till toppen" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/th.html b/src/partials/languages/th.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Thai --> -{% macro t(key) %}{{ { - "language": "th", - "clipboard.copy": "คัดลอก", - "clipboard.copied": "คัดลอกแล้ว", - "edit.link.title": "แก้ไขหน้านี้", - "footer.previous": "ก่อนหน้า", - "footer.next": "ต่อไป", - "meta.comments": "ความคิดเห็น", - "meta.source": "แหล่งที่มา", - "search.config.lang": "th", - "search.placeholder": "ค้นหา", - "search.result.placeholder": "พิมพ์เพื่อเริ่มค้นหา", - "search.result.none": "ไม่พบเอกสารที่ตรงกัน", - "search.result.one": "พบเอกสารที่ตรงกัน", - "search.result.other": "พบ # เอกสารที่ตรงกัน", - "skip.link.title": "ข้ามไปที่เนื้อหา", - "source.link.title": "ไปที่ Repository", - "source.file.date.updated": "สร้าง", - "source.file.date.created": "สร้าง", - "toc.title": "สารบัญ" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/tl.html b/src/partials/languages/tl.html @@ -1,57 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Tagalog --> -{% macro t(key) %}{{ { - "language": "tl", - "clipboard.copy": "Kopyahin sa clipboard", - "clipboard.copied": "Nakopya mula sa clipboard", - "edit.link.title": "I-edit ang pahinang ito", - "footer.previous": "Nakaraan", - "footer.next": "Susunod", - "footer.title": "Lagdang Pangwakas", - "header.title": "Pamuhatan", - "meta.comments": "Mga Komento", - "meta.source": "Pinagmulan", - "nav.title": "Nabigasyon", - "search.placeholder": "Hanapin", - "search.share": "Ibahagi", - "search.reset": "Tanggalin", - "search.result.initializer": "Sinisimulan ang paghahanap", - "search.result.placeholder": "Mag-type upang simulan ang paghahanap", - "search.result.none": "Walang nahanap na dokumento", - "search.result.one": "1 magkatugmang dokumento", - "search.result.other": "# magkatugmang mga dokumento", - "search.result.more.one": "1 meron sa pahina na ito", - "search.result.more.other": "# meron sa pahina na ito", - "search.result.term.missing": "Nawawala", - "search.title": "Hanapin", - "select.language.title": "Pumili ng lenguwahe", - "select.version.title": "Pumili ng bersyon", - "skip.link.title": "I-skip tungo sa nilalaman", - "source.link.title": "Pumunta sa repository", - "source.file.date.updated": "Huling update", - "source.file.date.created": "Nagawa", - "tabs.title": "Mga tala", - "toc.title": "Talaan ng nilalaman", - "top.title": "Bumalik sa taas" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/tr.html b/src/partials/languages/tr.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Turkish --> -{% macro t(key) %}{{ { - "language": "tr", - "clipboard.copy": "Kopyala", - "clipboard.copied": "Kopyalandı", - "edit.link.title": "Düzenle", - "footer.previous": "Önceki", - "footer.next": "Sonraki", - "meta.comments": "Yorumlar", - "meta.source": "Kaynak", - "search.config.lang": "tr", - "search.placeholder": "Ara", - "search.result.placeholder": "Aramaya başlamak için yazın", - "search.result.none": "Eşleşen doküman bulunamadı", - "search.result.one": "1 doküman bulundu", - "search.result.other": "# doküman bulundu", - "skip.link.title": "Ana içeriğe geç", - "source.link.title": "Depoya git", - "source.file.date.updated": "Son Güncelleme", - "source.file.date.created": "Oluşturuldu", - "toc.title": "İçindekiler" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/uk.html b/src/partials/languages/uk.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Ukrainian --> -{% macro t(key) %}{{ { - "language": "uk", - "clipboard.copy": "Скопіювати в буфер", - "clipboard.copied": "Скопійовано в буфер", - "edit.link.title": "Редагувати сторінку", - "footer.previous": "Назад", - "footer.next": "Вперед", - "meta.comments": "Коментарі", - "meta.source": "Вихідний код", - "search.config.lang": "ru", - "search.placeholder": "Пошук", - "search.result.placeholder": "Розпочніть писати для пошуку", - "search.result.none": "Збігів не знайдено", - "search.result.one": "Знайдено 1 збіг", - "search.result.other": "Знайдено # збігів", - "skip.link.title": "Перейти до змісту", - "source.link.title": "Перейти до репозиторію", - "source.file.date.updated": "Останнє оновлення", - "source.file.date.created": "Створено", - "toc.title": "Зміст" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/ur.html b/src/partials/languages/ur.html @@ -1,59 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Urdu --> -{% macro t(key) %}{{ { - "language": "ur", - "direction": "rtl", - "clipboard.copy": "کلِپ بورڈ میں نقل کریں", - "clipboard.copied": "کلِپ بورڈ میں نقل کر دیا گیا", - "edit.link.title": "اس صفحے میں ترمیم کریں", - "footer.previous": "پچھلا", - "footer.next": "اگلا", - "footer.title": "ذیلی تحریر", - "header.title": "سر تحریر", - "meta.comments": "تبصرے", - "meta.source": "ذریعہ", - "nav.title": "رہنمائی", - "search.config.pipeline": " ", - "search.placeholder": "تلاش کریں", - "search.share": "اشتراک کریں", - "search.reset": "صاف کریں", - "search.result.initializer": "تلاش کا آغاز ہو رہا ہے", - "search.result.placeholder": "تلاش شروع کرنے کے لئے ٹائپ کریں", - "search.result.none": "کوئی ملتی جلتی دستاویزات نہیں", - "search.result.one": "۱ ملتی جلتی دستاویز", - "search.result.other": "# ملتی جلتی دستاویزات", - "search.result.more.one": "اِس صفحے پر مزید ۱", - "search.result.more.other": "اِس صفحے پر مزید #", - "search.result.term.missing": "گمشدہ", - "search.title": "تلاش", - "select.language.title": "زبان کا انتخاب کریں", - "select.version.title": "ورژن کا انتخاب کریں", - "skip.link.title": "براہِ راست مواد پر جائیں", - "source.link.title": "ریپازٹری پر جائیں", - "source.file.date.updated": "آخری بار تجدید", - "source.file.date.created": "تخلیق", - "tabs.title": "ٹیبز", - "toc.title": "فہرست", - "top.title": "واپس اوپر جائیں" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/uz.html b/src/partials/languages/uz.html @@ -1,58 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Uzbek --> -{% macro t(key) %}{{ { - "language": "uz", - "clipboard.copy": "Buferga nusxalash", - "clipboard.copied": "Buferga nusxalandi", - "edit.link.title": "Ushbu sahifani tahrirlash", - "footer.previous": "Oldingi sahifa", - "footer.next": "Keyingi sahifa", - "footer.title": "Pastgi qism", - "header.title": "Sarlavha", - "meta.comments": "Izohlar", - "meta.source": "Manba", - "nav.title": "Navigatsiya", - "search.config.lang": "tr", - "search.placeholder": "Qidirish", - "search.share": "Ulashish", - "search.reset": "Tozalash", - "search.result.initializer": "Qidiruv ishga tushirilmoqda", - "search.result.placeholder": "Qidiruvni boshlash uchun kiriting", - "search.result.none": "Mos natijalar yo'q", - "search.result.one": "1 ta mos natija", - "search.result.other": "# ta mos keladigan natijalar", - "search.result.more.one": "Ushbu sahifada yana 1 ta natija", - "search.result.more.other": "Bu sahifada yana # ta natija", - "search.result.term.missing": "To'ldirilmagan", - "search.title": "Qidirish", - "select.language.title": "Tilni tanlang", - "select.version.title": "Versiyani tanlang", - "skip.link.title": "Tarkibga o'tish", - "source.link.title": "Repozitoriyga o'tish", - "source.file.date.updated": "Oxirgi yangilanish", - "source.file.date.created": "Yaratildi", - "tabs.title": "Yorliqlar", - "toc.title": "Mundarija", - "top.title": "Yuqoriga qaytish" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/vi.html b/src/partials/languages/vi.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Vietnamese --> -{% macro t(key) %}{{ { - "language": "vi", - "clipboard.copy": "Sao chép vào bộ nhớ", - "clipboard.copied": "Sao chép xong", - "edit.link.title": "Chỉnh sửa", - "footer.previous": "Trước", - "footer.next": "Sau", - "meta.comments": "Bình luận", - "meta.source": "Mã nguồn", - "search.config.lang": "vi", - "search.placeholder": "Tìm kiếm", - "search.result.placeholder": "Nhập để bắt đầu tìm kiếm", - "search.result.none": "Không tìm thấy tài liệu liên quan", - "search.result.one": "1 tài liệu liên quan", - "search.result.other": "# tài liệu liên quan", - "skip.link.title": "Vào thẳng nội dung", - "source.link.title": "Đến kho lưu trữ mã nguồn", - "source.file.date.updated": "Cập nhật cuối cùng", - "source.file.date.created": "Tạo", - "toc.title": "Mục lục" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/zh-Hant.html b/src/partials/languages/zh-Hant.html @@ -1,47 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Chinese (Traditional) --> -{% macro t(key) %}{{ { - "language": "zh-Hant", - "clipboard.copy": "拷貝", - "clipboard.copied": "已拷貝", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "評論", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\\s\\-,。]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "鍵入以開始檢索", - "search.result.none": "沒有找到符合條件的結果", - "search.result.one": "找到 1 个符合條件的結果", - "search.result.other": "# 個符合條件的結果", - "skip.link.title": "跳轉至", - "source.link.title": "前往倉庫", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/zh-TW.html b/src/partials/languages/zh-TW.html @@ -1,53 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Chinese (Taiwanese) --> -{% macro t(key) %}{{ { - "language": "zh-Hant", - "announce.dismiss": "不再顯示此訊息", - "clipboard.copy": "複製", - "clipboard.copied": "已複製", - "consent.accept": "同意", - "consent.manage": "管理設定", - "consent.reject": "拒絕", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "留言", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\\s\\- 、。,.?;]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "打字進行搜尋", - "search.result.none": "沒有符合的項目", - "search.result.one": "找到 1 個符合的項目", - "search.result.other": "找到 # 個符合的項目", - "search.result.more.one": "此頁尚有 1 個符合的項目", - "search.result.more.other": "此頁尚有 # 個符合的項目", - "skip.link.title": "跳轉到", - "source.link.title": "前往倉庫", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/src/partials/languages/zh.html b/src/partials/languages/zh.html @@ -1,64 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Translations: Chinese (Simplified) --> -{% macro t(key) %}{{ { - "language": "zh", - "announce.dismiss": "不再显示此消息", - "clipboard.copy": "复制", - "clipboard.copied": "已复制", - "consent.accept": "同意", - "consent.manage": "管理设定", - "consent.reject": "拒绝", - "edit.link.title": "编辑此页", - "footer.previous": "上一页", - "footer.next": "下一页", - "footer.title": "页脚", - "header.title": "页眉", - "meta.comments": "评论", - "meta.source": "来源", - "nav.title": "导航栏", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\\s\\-,。]+", - "search.placeholder": "搜索", - "search.share": "分享", - "search.reset": "清空当前内容", - "search.result.initializer": "正在初始化搜索引擎", - "search.result.placeholder": "键入以开始搜索", - "search.result.none": "没有找到符合条件的结果", - "search.result.one": "找到 1 个符合条件的结果", - "search.result.other": "# 个符合条件的结果", - "search.result.more.one": "在该页上还有 1 个符合条件的结果", - "search.result.more.other": "在该页上还有 # 个符合条件的结果", - "search.result.term.missing": "缺少", - "search.title": "查找", - "select.language.title": "选择当前语言", - "select.version.title": "选择当前版本", - "skip.link.title": "跳转至", - "source.link.title": "前往仓库", - "source.file.date.updated": "最后更新", - "source.file.date.created": "创建日期", - "tabs.title": "标签", - "toc.title": "目录", - "top.title": "回到页面顶部" -}[key] }}{% endmacro %} diff --git a/src/partials/logo.html b/src/partials/logo.html @@ -1,29 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Logo --> -{% if config.theme.logo %} - <img src="{{ config.theme.logo | url }}" alt="logo" /> -{% else %} - {% set icon = config.theme.icon.logo or "material/library" %} - {% include ".icons/" ~ icon ~ ".svg" %} -{% endif %} diff --git a/src/partials/nav-item.html b/src/partials/nav-item.html @@ -1,170 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Wrap everything with a macro to reduce file roundtrips (see #2213) --> -{% macro render(nav_item, path, level) %} - - <!-- Determine class according to state --> - {% set class = "md-nav__item" %} - {% if nav_item.active %} - {% set class = class ~ " md-nav__item--active" %} - {% endif %} - - <!-- Main navigation item with nested items --> - {% if nav_item.children %} - - <!-- Determine whether to render item as a section --> - {% if "navigation.sections" in features and level == 1 + ( - "navigation.tabs" in features - ) %} - {% set class = class ~ " md-nav__item--section" %} - {% endif %} - - <!-- Render item with nested items --> - <li class="{{ class }} md-nav__item--nested"> - - <!-- Active checkbox expands items contained within nested section --> - {% set checked = "checked" if nav_item.active %} - {% if "navigation.expand" in features and not checked %} - <input - class="md-nav__toggle md-toggle md-toggle--indeterminate" - data-md-toggle="{{ path }}" - type="checkbox" - id="{{ path }}" - checked - /> - {% else %} - <input - class="md-nav__toggle md-toggle" - data-md-toggle="{{ path }}" - type="checkbox" - id="{{ path }}" - {{ checked }} - /> - {% endif %} - - <!-- Determine all nested items that are index pages --> - {% set indexes = [] %} - {% if "navigation.indexes" in features %} - {% for nav_item in nav_item.children %} - {% if nav_item.is_index and not index is defined %} - {% set _ = indexes.append(nav_item) %} - {% endif %} - {% endfor %} - {% endif %} - - <!-- Render toggle to expand nested items --> - {% if not indexes %} - <label class="md-nav__link" for="{{ path }}"> - {{ nav_item.title }} - <span class="md-nav__icon md-icon"></span> - </label> - - <!-- Render link to index page + toggle --> - {% else %} - {% set index = indexes | first %} - {% set class = "md-nav__link--active" if index == page %} - <div class="md-nav__link md-nav__link--index {{ class }}"> - <a href="{{ index.url | url }}">{{ nav_item.title }}</a> - - <!-- Only render toggle if there's at least one more page --> - {% if nav_item.children | length > 1 %} - <label for="{{ path }}"> - <span class="md-nav__icon md-icon"></span> - </label> - {% endif %} - </div> - {% endif %} - - <!-- Render nested navigation --> - <nav - class="md-nav" - aria-label="{{ nav_item.title }}" - data-md-level="{{ level }}" - > - <label class="md-nav__title" for="{{ path }}"> - <span class="md-nav__icon md-icon"></span> - {{ nav_item.title }} - </label> - <ul class="md-nav__list" data-md-scrollfix> - - <!-- Render nested item list --> - {% for nav_item in nav_item.children %} - {% if not indexes or nav_item != indexes | first %} - {{ render(nav_item, path ~ "_" ~ loop.index, level + 1) }} - {% endif %} - {% endfor %} - </ul> - </nav> - </li> - - <!-- Currently active page --> - {% elif nav_item == page %} - <li class="{{ class }}"> - {% set toc = page.toc %} - - <!-- Active checkbox expands items contained within nested section --> - <input - class="md-nav__toggle md-toggle" - data-md-toggle="toc" - type="checkbox" - id="__toc" - /> - - <!-- Hack: see partials/toc.html for more information --> - {% set first = toc | first %} - {% if first and first.level == 1 %} - {% set toc = first.children %} - {% endif %} - - <!-- Render table of contents, if not empty --> - {% if toc %} - <label class="md-nav__link md-nav__link--active" for="__toc"> - {{ nav_item.title }} - <span class="md-nav__icon md-icon"></span> - </label> - {% endif %} - <a - href="{{ nav_item.url | url }}" - class="md-nav__link md-nav__link--active" - > - {{ nav_item.title }} - </a> - - <!-- Show table of contents --> - {% if toc %} - {% include "partials/toc.html" %} - {% endif %} - </li> - - <!-- Main navigation item --> - {% else %} - <li class="{{ class }}"> - <a href="{{ nav_item.url | url }}" class="md-nav__link"> - {{ nav_item.title }} - </a> - </li> - {% endif %} -{% endmacro %} - -<!-- Render current and nested navigation items --> -{{ render(nav_item, path, level) }} diff --git a/src/partials/nav.html b/src/partials/nav.html @@ -1,68 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine class according to configuration --> -{% set class = "md-nav md-nav--primary" %} -{% if "navigation.tabs" in features %} - {% set class = class ~ " md-nav--lifted" %} -{% endif %} -{% if "toc.integrate" in features %} - {% set class = class ~ " md-nav--integrated" %} -{% endif %} - -<!-- Main navigation --> -<nav - class="{{ class }}" - aria-label="{{ lang.t('nav.title') }}" - data-md-level="0" -> - - <!-- Site title --> - <label class="md-nav__title" for="__drawer"> - <a - href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}" - title="{{ config.site_name | e }}" - class="md-nav__button md-logo" - aria-label="{{ config.site_name }}" - data-md-component="logo" - > - {% include "partials/logo.html" %} - </a> - {{ config.site_name }} - </label> - - <!-- Repository information --> - {% if config.repo_url %} - <div class="md-nav__source"> - {% include "partials/source.html" %} - </div> - {% endif %} - - <!-- Render item list --> - <ul class="md-nav__list" data-md-scrollfix> - {% for nav_item in nav %} - {% set path = "__nav_" ~ loop.index %} - {% set level = 1 %} - {% include "partials/nav-item.html" %} - {% endfor %} - </ul> -</nav> diff --git a/src/partials/palette.html b/src/partials/palette.html @@ -1,66 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Primary colors --> -{% macro primary(key) %}{{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" -}[key] }}{% endmacro %} - -<!-- Accent colors --> -{% macro accent(key) %}{{ { - "red": "#ff1a47", - "pink": "#f50056", - "purple": "#df41fb", - "deep-purple": "#7c4dff", - "indigo": "#526cfe", - "blue": "#4287ff", - "light-blue": "#0091eb", - "cyan": "#00bad6", - "teal": "#00bda4", - "green": "#00c753", - "light-green": "#63de17", - "lime": "#b0eb00", - "yellow": "#ffd500", - "amber": "#ffaa00", - "orange": "#ff9100", - "deep-orange": "#ff6e42" -}[key] }}{% endmacro %} diff --git a/src/partials/search.html b/src/partials/search.html @@ -1,103 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Search interface --> -<div class="md-search" data-md-component="search" role="dialog"> - <label class="md-search__overlay" for="__search"></label> - <div class="md-search__inner" role="search"> - <form class="md-search__form" name="search"> - - <!-- Search input --> - <input - type="text" - class="md-search__input" - name="query" - aria-label="{{ lang.t('search.placeholder') }}" - placeholder="{{ lang.t('search.placeholder') }}" - autocapitalize="off" - autocorrect="off" - autocomplete="off" - spellcheck="false" - data-md-component="search-query" - required - /> - - <!-- Button to open search --> - <label class="md-search__icon md-icon" for="__search"> - {% include ".icons/material/magnify.svg" %} - {% include ".icons/material/arrow-left.svg" %} - </label> - - <!-- Search options --> - <nav - class="md-search__options" - aria-label="{{ lang.t('search.title') }}" - > - - <!-- Button to share search --> - {% if "search.share" in features %} - <a - href="javascript:void(0)" - class="md-search__icon md-icon" - aria-label="{{ lang.t('search.share') }}" - data-clipboard - data-clipboard-text="" - data-md-component="search-share" - tabindex="-1" - > - {% include ".icons/material/share-variant.svg" %} - </a> - {% endif %} - - <!-- Button to reset search --> - <button - type="reset" - class="md-search__icon md-icon" - aria-label="{{ lang.t('search.reset') }}" - tabindex="-1" - > - {% include ".icons/material/close.svg" %} - </button> - </nav> - - <!-- Search suggestions --> - {% if "search.suggest" in features %} - <div - class="md-search__suggest" - data-md-component="search-suggest" - ></div> - {% endif %} - </form> - <div class="md-search__output"> - <div class="md-search__scrollwrap" data-md-scrollfix> - - <!-- Search results --> - <div class="md-search-result" data-md-component="search-result"> - <div class="md-search-result__meta"> - {{ lang.t("search.result.initializer") }} - </div> - <ol class="md-search-result__list"></ol> - </div> - </div> - </div> - </div> -</div> diff --git a/src/partials/social.html b/src/partials/social.html @@ -1,40 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Social links --> -<div class="md-social"> - {% for social in config.extra.social %} - {% set title = social.name %} - {% if not title and "//" in social.link %} - {% set _, url = social.link.split("//") %} - {% set title = url.split("/")[0] %} - {% endif %} - <a - href="{{ social.link }}" - target="_blank" rel="noopener" - title="{{ title | e }}" - class="md-social__link" - > - {% include ".icons/" ~ social.icon ~ ".svg" %} - </a> - {% endfor %} -</div> diff --git a/src/partials/source-file.html b/src/partials/source-file.html @@ -1,44 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Source file information --> -<hr /> -<div class="md-source-file"> - <small> - - <!-- mkdocs-git-revision-date-localized-plugin --> - {% if page.meta.git_revision_date_localized %} - {{ lang.t("source.file.date.updated") }}: - {{ page.meta.git_revision_date_localized }} - {% if page.meta.git_creation_date_localized %} - <br /> - {{ lang.t("source.file.date.created") }}: - {{ page.meta.git_creation_date_localized }} - {% endif %} - - <!-- mkdocs-git-revision-date-plugin --> - {% elif page.meta.revision_date %} - {{ lang.t("source.file.date.updated") }}: - {{ page.meta.revision_date }} - {% endif %} - </small> -</div> diff --git a/src/partials/source.html b/src/partials/source.html @@ -1,37 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Repository information --> -<a - href="{{ config.repo_url }}" - title="{{ lang.t('source.link.title') }}" - class="md-source" - data-md-component="source" -> - <div class="md-source__icon md-icon"> - {% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %} - {% include ".icons/" ~ icon ~ ".svg" %} - </div> - <div class="md-source__repository"> - {{ config.repo_name }} - </div> -</a> diff --git a/src/partials/tabs-item.html b/src/partials/tabs-item.html @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine class according to state --> -{% if not class %} - {% set class = "md-tabs__link" %} - {% if nav_item.active %} - {% set class = class ~ " md-tabs__link--active" %} - {% endif %} -{% endif %} - -<!-- Main navigation item with nested items --> -{% if nav_item.children %} - {% set title = title | d(nav_item.title) %} - {% set nav_item = nav_item.children | first %} - - <!-- Recurse, if the first item has further nested items --> - {% if nav_item.children %} - {% include "partials/tabs-item.html" %} - - <!-- Render item --> - {% else %} - <li class="md-tabs__item"> - <a href="{{ nav_item.url | url }}" class="{{ class }}"> - {{ title }} - </a> - </li> - {% endif %} - -<!-- Main navigation item --> -{% else %} - <li class="md-tabs__item"> - <a href="{{ nav_item.url | url }}" class="{{ class }}"> - {{ nav_item.title }} - </a> - </li> -{% endif %} diff --git a/src/partials/tabs.html b/src/partials/tabs.html @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Hack: unset variable, as we're using it recursively in tabs-item.html --> -{% set class = "" %} - -<!-- Navigation tabs --> -<nav - class="md-tabs" - aria-label="{{ lang.t('tabs.title') }}" - data-md-component="tabs" -> - <div class="md-tabs__inner md-grid"> - <ul class="md-tabs__list"> - {% for nav_item in nav %} - {% include "partials/tabs-item.html" %} - {% endfor %} - </ul> - </div> -</nav> diff --git a/src/partials/tags.html b/src/partials/tags.html @@ -1,41 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine whether to show tags --> -{% if page.meta and page.meta.hide %} - {% set hidden = "hidden" if "tags" in page.meta.hide %} -{% endif %} - -<!-- Tags --> -{% if tags %} - <nav class="md-tags" {{ hidden }}> - {% for tag in tags %} - {% if tag.url %} - <a href="{{ tag.url | url }}" class="md-tag"> - {{ tag.name }} - </a> - {% else %} - <span class="md-tag">{{ tag.name }}</span> - {% endif %} - {% endfor %} - </nav> -{% endif %} diff --git a/src/partials/toc-item.html b/src/partials/toc-item.html @@ -1,39 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Table of contents item --> -<li class="md-nav__item"> - <a href="{{ toc_item.url }}" class="md-nav__link"> - {{ toc_item.title }} - </a> - - <!-- Table of contents list --> - {% if toc_item.children %} - <nav class="md-nav" aria-label="{{ toc_item.title }}"> - <ul class="md-nav__list"> - {% for toc_item in toc_item.children %} - {% include "partials/toc-item.html" %} - {% endfor %} - </ul> - </nav> - {% endif %} -</li> diff --git a/src/partials/toc.html b/src/partials/toc.html @@ -1,56 +0,0 @@ -<!-- - Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - - 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. ---> - -<!-- Determine title --> -{% set title = lang.t("toc.title") %} -{% if config.mdx_configs.toc and config.mdx_configs.toc.title %} - {% set title = config.mdx_configs.toc.title %} -{% endif %} - -<!-- Table of contents --> -<nav class="md-nav md-nav--secondary" aria-label="{{ title }}"> - {% set toc = page.toc %} - - <!-- - Hack: check whether the content contains a h1 headline. If it does, the - top-level anchor must be skipped, since it would be redundant to the link - to the current page that is located just above the anchor. Therefore we - directly continue with the children of the anchor. - --> - {% set first = toc | first %} - {% if first and first.level == 1 %} - {% set toc = first.children %} - {% endif %} - - <!-- Table of contents title and list --> - {% if toc %} - <label class="md-nav__title" for="__toc"> - <span class="md-nav__icon md-icon"></span> - {{ title }} - </label> - <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> - {% for toc_item in toc %} - {% include "partials/toc-item.html" %} - {% endfor %} - </ul> - {% endif %} -</nav> diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py diff --git a/src/plugins/search/__init__.py b/src/plugins/search/__init__.py diff --git a/src/plugins/search/plugin.py b/src/plugins/search/plugin.py @@ -1,55 +0,0 @@ -# Copyright (c) 2016-2021 Martin Donath <martin.donath@squidfunk.com> - -# 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. - -from mkdocs.contrib.search import SearchPlugin as BasePlugin -from mkdocs.contrib.search.search_index import SearchIndex as BaseIndex - -# ----------------------------------------------------------------------------- -# Class -# ----------------------------------------------------------------------------- - -# Search plugin with custom search index -class SearchPlugin(BasePlugin): - - # Override to use a custom search index - def on_pre_build(self, config): - super().on_pre_build(config) - self.search_index = SearchIndex(**self.config) - -# ----------------------------------------------------------------------------- - -# Search index with support for additional fields -class SearchIndex(BaseIndex): - - # Override to add additional fields for each page - def add_entry_from_context(self, page): - index = len(self._entries) - super().add_entry_from_context(page) - entry = self._entries[index] - - # Add document tags - if page.meta.get("tags"): - entry["tags"] = page.meta["tags"] - - # Add document boost for search - if "search" in page.meta: - search = page.meta["search"] - if "boost" in search: - entry["boost"] = search["boost"] diff --git a/src/plugins/tags/__init__.py b/src/plugins/tags/__init__.py diff --git a/src/plugins/tags/plugin.py b/src/plugins/tags/plugin.py @@ -1,138 +0,0 @@ -# Copyright (c) 2016-2022 Martin Donath <martin.donath@squidfunk.com> - -# 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 logging -import os -import sys - -from collections import defaultdict -from markdown.extensions.toc import slugify -from mkdocs import utils -from mkdocs.commands.build import DuplicateFilter -from mkdocs.config.config_options import Type -from mkdocs.plugins import BasePlugin - -# ----------------------------------------------------------------------------- -# Class -# ----------------------------------------------------------------------------- - -# Tags plugin -class TagsPlugin(BasePlugin): - - # Configuration scheme - config_scheme = ( - ("tags_file", Type(str, required = False)), - ) - - # Initialize plugin - def __init__(self): - self.tags = defaultdict(list) - self.tags_file = None - self.slugify = None - - # Retrieve configuration for anchor generation - def on_config(self, config): - if "toc" in config["markdown_extensions"]: - toc = { "slugify": slugify, "separator": "-" } - if "toc" in config["mdx_configs"]: - toc = { **toc, **config["mdx_configs"]["toc"] } - - # Partially apply slugify function - self.slugify = lambda value: ( - toc["slugify"](str(value), toc["separator"]) - ) - - # Hack: 2nd pass for tags index page - def on_nav(self, nav, files, **kwargs): - file = self.config.get("tags_file") - if file: - self.tags_file = files.get_file_from_path(file) - if not self.tags_file: - log.error(f"Configuration error: {file} doesn't exist.") - sys.exit() - - # Add tags file to files - files.append(self.tags_file) - - # Build and render tags index page - def on_page_markdown(self, markdown, page, **kwargs): - if page.file == self.tags_file: - return self.__render_tag_index(markdown) - - # Add page to tags index - for tag in page.meta.get("tags", []): - self.tags[tag].append(page) - - # Inject tags into page (after search and before minification) - def on_page_context(self, context, page, **kwargs): - if "tags" in page.meta: - context["tags"] = [ - self.__render_tag(tag) - for tag in page.meta["tags"] - ] - - # ------------------------------------------------------------------------- - - # Render tags index - def __render_tag_index(self, markdown): - if not "[TAGS]" in markdown: - markdown += "\n[TAGS]" - - # Replace placeholder in Markdown with rendered tags index - return markdown.replace("[TAGS]", "\n".join([ - self.__render_tag_links(*args) - for args in sorted(self.tags.items()) - ])) - - # Render the given tag and links to all pages with occurrences - def __render_tag_links(self, tag, pages): - content = [f"## <span class=\"md-tag\">{tag}</span>", ""] - for page in pages: - url = utils.get_relative_url( - page.file.src_path.replace(os.path.sep, "/"), - self.tags_file.src_path.replace(os.path.sep, "/") - ) - - # Ensure forward slashes, as we have to use the path of the source - # file which contains the operating system's path separator. - content.append("- [{}]({})".format( - page.meta.get("title", page.title), - url - )) - - # Return rendered tag links - return "\n".join(content) - - # Render the given tag, linking to the tags index (if enabled) - def __render_tag(self, tag): - if not self.tags_file or not self.slugify: - return dict(name = tag) - else: - url = self.tags_file.url - url += f"#{self.slugify(tag)}" - return dict(name = tag, url = url) - -# ----------------------------------------------------------------------------- -# Data -# ----------------------------------------------------------------------------- - -# Set up logging -log = logging.getLogger("mkdocs") -log.addFilter(DuplicateFilter())