From cb1acef1df3dcab2dc12399f697f72e558887dc8 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Sat, 28 Sep 2019 19:55:08 +0200 Subject: [PATCH] Improved build dependency resolution --- Makefile | 9 +- package.json | 2 +- src/assets/javascripts/application.js | 537 ------------------ src/assets/javascripts/components/Material.js | 43 -- .../javascripts/components/Material/Event.js | 33 -- .../components/Material/Event/Listener.js | 89 --- .../components/Material/Event/MatchMedia.js | 59 -- .../javascripts/components/Material/Header.js | 33 -- .../components/Material/Header/Shadow.js | 101 ---- .../components/Material/Header/Title.js | 97 ---- .../javascripts/components/Material/Nav.js | 35 -- .../components/Material/Nav/Blur.js | 132 ----- .../components/Material/Nav/Collapse.js | 134 ----- .../components/Material/Nav/Scrolling.js | 176 ------ .../javascripts/components/Material/Search.js | 33 -- .../components/Material/Search/Lock.js | 101 ---- .../components/Material/Search/Result.jsx | 414 -------------- .../components/Material/Sidebar.js | 31 - .../components/Material/Sidebar/Position.js | 135 ----- .../javascripts/components/Material/Source.js | 33 -- .../components/Material/Source/Adapter.js | 31 - .../Material/Source/Adapter/Abstract.js | 117 ---- .../Material/Source/Adapter/GitHub.js | 95 ---- .../components/Material/Source/Repository.jsx | 63 -- .../javascripts/components/Material/Tabs.js | 31 - .../components/Material/Tabs/Toggle.js | 74 --- src/assets/javascripts/modernizr.js | 23 - src/assets/javascripts/providers/.babelrc | 8 - src/assets/javascripts/providers/jsx.js | 74 --- 29 files changed, 6 insertions(+), 2737 deletions(-) delete mode 100644 src/assets/javascripts/application.js delete mode 100644 src/assets/javascripts/components/Material.js delete mode 100644 src/assets/javascripts/components/Material/Event.js delete mode 100644 src/assets/javascripts/components/Material/Event/Listener.js delete mode 100644 src/assets/javascripts/components/Material/Event/MatchMedia.js delete mode 100644 src/assets/javascripts/components/Material/Header.js delete mode 100644 src/assets/javascripts/components/Material/Header/Shadow.js delete mode 100644 src/assets/javascripts/components/Material/Header/Title.js delete mode 100644 src/assets/javascripts/components/Material/Nav.js delete mode 100644 src/assets/javascripts/components/Material/Nav/Blur.js delete mode 100644 src/assets/javascripts/components/Material/Nav/Collapse.js delete mode 100644 src/assets/javascripts/components/Material/Nav/Scrolling.js delete mode 100644 src/assets/javascripts/components/Material/Search.js delete mode 100644 src/assets/javascripts/components/Material/Search/Lock.js delete mode 100644 src/assets/javascripts/components/Material/Search/Result.jsx delete mode 100644 src/assets/javascripts/components/Material/Sidebar.js delete mode 100644 src/assets/javascripts/components/Material/Sidebar/Position.js delete mode 100644 src/assets/javascripts/components/Material/Source.js delete mode 100644 src/assets/javascripts/components/Material/Source/Adapter.js delete mode 100644 src/assets/javascripts/components/Material/Source/Adapter/Abstract.js delete mode 100644 src/assets/javascripts/components/Material/Source/Adapter/GitHub.js delete mode 100644 src/assets/javascripts/components/Material/Source/Repository.jsx delete mode 100644 src/assets/javascripts/components/Material/Tabs.js delete mode 100644 src/assets/javascripts/components/Material/Tabs/Toggle.js delete mode 100644 src/assets/javascripts/modernizr.js delete mode 100644 src/assets/javascripts/providers/.babelrc delete mode 100644 src/assets/javascripts/providers/jsx.js diff --git a/Makefile b/Makefile index 4ea3df7a6..8d8b0bfc3 100644 --- a/Makefile +++ b/Makefile @@ -117,15 +117,16 @@ material/assets/javascripts/lunr/%.js: ${LUNR_SOURCE}/%.js | $$(@D)/. @ echo "+ $@" @ cp $< $@ -# All scripts +# Scripts material/assets/javascripts: $$@/lunr # ----------------------------------------------------------------------------- # Stylesheets STYLESHEETS = $(subst src,material,$(wildcard src/assets/stylesheets/a*.scss)) +STYLESHEETS_PARTIALS = $(shell find src -name "_*.scss") material/assets/stylesheets: $(patsubst %.scss,%.css,${STYLESHEETS}) -material/assets/stylesheets/%.css: src/assets/stylesheets/%.scss | $$(@D)/. +material/%.css: src/%.scss ${STYLESHEETS_PARTIALS} | $$(@D)/. @ echo "+ $@" @ ${BIN}/node-sass -q \ --source-map $@.map \ @@ -141,13 +142,13 @@ material/assets/stylesheets/%.css: src/assets/stylesheets/%.scss | $$(@D)/. # ----------------------------------------------------------------------------- -# All assets +# Assets material/assets: $$@/fonts $$@/images $$@/javascripts $$@/stylesheets # ----------------------------------------------------------------------------- # Templates -HTML = $(subst src,material,$(shell find src -type f -name "*.html" )) +HTML = $(subst src,material,$(shell find src -name "*.html" )) material/%.html: src/%.html | $$(@D)/. @ echo "+ $@" @ ${BIN}/html-minifier \ diff --git a/package.json b/package.json index 235e787c7..3ca9e79ec 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "build": "make build", "clean": "make clean", "lint": "make lint", - "start": "make -j start" + "start": "make start" }, "dependencies": { "clipboard": "^2.0.0", diff --git a/src/assets/javascripts/application.js b/src/assets/javascripts/application.js deleted file mode 100644 index 1962eea7f..000000000 --- a/src/assets/javascripts/application.js +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "../images/icons/bitbucket.svg" -import "../images/icons/github.svg" -import "../images/icons/gitlab.svg" - -import "../stylesheets/application.scss" -import "../stylesheets/application-palette.scss" - -/* ---------------------------------------------------------------------------- - * Polyfills - * ------------------------------------------------------------------------- */ - -import "custom-event-polyfill" -import "unfetch/polyfill" - -import Promise from "promise-polyfill" -window.Promise = window.Promise || Promise - -/* ---------------------------------------------------------------------------- - * Dependencies - * ------------------------------------------------------------------------- */ - -import Clipboard from "clipboard" - -import Material from "./components/Material" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Return the meta tag value for the given key - * - * @param {string} key - Meta name - * - * @return {string} Meta content value - */ -const translate = key => { - const meta = document.getElementsByName(`lang:${key}`)[0] - if (!(meta instanceof HTMLMetaElement)) - throw new ReferenceError - return meta.content -} - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/** - * Initialize Material for MkDocs - * - * @param {Object} config - Configuration - */ -function initialize(config) { // eslint-disable-line func-style - - /* Initialize Modernizr */ - new Material.Event.Listener(document, "DOMContentLoaded", () => { - if (!(document.body instanceof HTMLElement)) - throw new ReferenceError - - /* Test for iOS */ - Modernizr.addTest("ios", () => { - return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g) - }) - - /* Wrap all data tables for better overflow scrolling */ - const tables = document.querySelectorAll("table:not([class])") // TODO: this is JSX, we should rename the file - Array.prototype.forEach.call(tables, table => { - const wrap = ( -
-
-
- ) - if (table.nextSibling) { - table.parentNode.insertBefore(wrap, table.nextSibling) - } else { - table.parentNode.appendChild(wrap) - } - wrap.children[0].appendChild(table) - }) - - /* Clipboard integration */ - if (Clipboard.isSupported()) { - const blocks = document.querySelectorAll(".codehilite > pre, pre > code") - Array.prototype.forEach.call(blocks, (block, index) => { - const id = `__code_${index}` - - /* Create button with message container */ - const button = ( - - ) - - /* Link to block and insert button */ - const parent = block.parentNode - parent.id = id - parent.insertBefore(button, block) - }) - - /* Initialize Clipboard listener */ - const copy = new Clipboard(".md-clipboard") - - /* Success handler */ - copy.on("success", action => { - const message = action.trigger.querySelector(".md-clipboard__message") - if (!(message instanceof HTMLElement)) - throw new ReferenceError - - /* Clear selection and reset debounce logic */ - action.clearSelection() - if (message.dataset.mdTimer) - clearTimeout(parseInt(message.dataset.mdTimer, 10)) - - /* Set message indicating success and show it */ - message.classList.add("md-clipboard__message--active") - message.innerHTML = translate("clipboard.copied") - - /* Hide message after two seconds */ - message.dataset.mdTimer = setTimeout(() => { - message.classList.remove("md-clipboard__message--active") - message.dataset.mdTimer = "" - }, 2000).toString() - }) - } - - /* Polyfill details/summary functionality */ - if (!Modernizr.details) { - const blocks = document.querySelectorAll("details > summary") - Array.prototype.forEach.call(blocks, summary => { - summary.addEventListener("click", ev => { - const details = ev.target.parentNode - if (details.hasAttribute("open")) { - details.removeAttribute("open") - } else { - details.setAttribute("open", "") - } - }) - }) - } - - /* Open details after anchor jump */ - const details = () => { - if (document.location.hash) { - const el = document.getElementById(document.location.hash.substring(1)) - if (!el) - return - - /* Walk up as long as we're not in a details tag */ - let parent = el.parentNode - while (parent && !(parent instanceof HTMLDetailsElement)) - parent = parent.parentNode - - /* If there's a details tag, open it */ - if (parent && !parent.open) { - parent.open = true - - /* Force reload, so the viewport repositions */ - const loc = location.hash - location.hash = " " - location.hash = loc - } - } - } - window.addEventListener("hashchange", details) - details() - - /* Force 1px scroll offset to trigger overflow scrolling */ - if (Modernizr.ios) { - const scrollable = document.querySelectorAll("[data-md-scrollfix]") - Array.prototype.forEach.call(scrollable, item => { - item.addEventListener("touchstart", () => { - const top = item.scrollTop - - /* We're at the top of the container */ - if (top === 0) { - item.scrollTop = 1 - - /* We're at the bottom of the container */ - } else if (top + item.offsetHeight === item.scrollHeight) { - item.scrollTop = top - 1 - } - }) - }) - } - }).listen() - - /* Component: header shadow toggle */ - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Header.Shadow( - "[data-md-component=container]", - "[data-md-component=header]") - ).listen() - - /* Component: header title toggle */ - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Header.Title( - "[data-md-component=title]", - ".md-typeset h1") - ).listen() - - /* Component: hero visibility toggle */ - if (document.querySelector("[data-md-component=hero]")) - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Tabs.Toggle("[data-md-component=hero]")).listen() - - /* Component: tabs visibility toggle */ - if (document.querySelector("[data-md-component=tabs]")) - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Tabs.Toggle("[data-md-component=tabs]")).listen() - - /* Component: sidebar with navigation */ - new Material.Event.MatchMedia("(min-width: 1220px)", - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Sidebar.Position( - "[data-md-component=navigation]", - "[data-md-component=header]"))) - - /* Component: sidebar with table of contents (missing on 404 page) */ - if (document.querySelector("[data-md-component=toc]")) - new Material.Event.MatchMedia("(min-width: 960px)", - new Material.Event.Listener(window, [ - "scroll", "resize", "orientationchange" - ], new Material.Sidebar.Position( - "[data-md-component=toc]", - "[data-md-component=header]"))) - - /* Component: link blurring for table of contents */ - new Material.Event.MatchMedia("(min-width: 960px)", - new Material.Event.Listener(window, "scroll", - new Material.Nav.Blur("[data-md-component=toc] .md-nav__link"))) - - /* Component: collapsible elements for navigation */ - const collapsibles = - document.querySelectorAll("[data-md-component=collapsible]") - Array.prototype.forEach.call(collapsibles, collapse => { - new Material.Event.MatchMedia("(min-width: 1220px)", - new Material.Event.Listener(collapse.previousElementSibling, "click", - new Material.Nav.Collapse(collapse))) - }) - - /* Component: active pane monitor for iOS scrolling fixes */ - new Material.Event.MatchMedia("(max-width: 1219px)", - new Material.Event.Listener( - "[data-md-component=navigation] [data-md-toggle]", "change", - new Material.Nav.Scrolling("[data-md-component=navigation] nav"))) - - /* Initialize search, if available */ - if (document.querySelector("[data-md-component=search]")) { - - /* Component: search body lock for mobile */ - new Material.Event.MatchMedia("(max-width: 959px)", - new Material.Event.Listener("[data-md-toggle=search]", "change", - new Material.Search.Lock("[data-md-toggle=search]"))) - - /* Component: search results */ - new Material.Event.Listener("[data-md-component=query]", [ - "focus", "keyup", "change" - ], new Material.Search.Result("[data-md-component=result]", () => { - return fetch(`${config.url.base}/search/search_index.json`, { - credentials: "same-origin" - }).then(response => response.json()) - .then(data => { - return data.docs.map(doc => { - doc.location = `${config.url.base}/${doc.location}` - return doc - }) - }) - })).listen() - - /* Listener: focus input after form reset */ - new Material.Event.Listener("[data-md-component=reset]", "click", () => { - setTimeout(() => { - const query = document.querySelector("[data-md-component=query]") - if (!(query instanceof HTMLInputElement)) - throw new ReferenceError - query.focus() - }, 10) - }).listen() - - /* Listener: focus input after opening search */ - new Material.Event.Listener("[data-md-toggle=search]", "change", ev => { - setTimeout(toggle => { - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - const query = document.querySelector("[data-md-component=query]") - if (!(query instanceof HTMLInputElement)) - throw new ReferenceError - query.focus() - } - }, 400, ev.target) - }).listen() - - /* Listener: open search on focus */ - new Material.Event.Listener("[data-md-component=query]", "focus", () => { - const toggle = document.querySelector("[data-md-toggle=search]") - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (!toggle.checked) { - toggle.checked = true - toggle.dispatchEvent(new CustomEvent("change")) - } - }).listen() - - /* Listener: keyboard handlers */ // eslint-disable-next-line complexity - new Material.Event.Listener(window, "keydown", ev => { // TODO: split up into component to reduce complexity - const toggle = document.querySelector("[data-md-toggle=search]") - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - const query = document.querySelector("[data-md-component=query]") - if (!(query instanceof HTMLInputElement)) - throw new ReferenceError - - /* Skip editable elements */ - if (document.activeElement instanceof HTMLElement && - document.activeElement.isContentEditable) - return - - /* Abort if meta key (macOS) or ctrl key (Windows) is pressed */ - if (ev.metaKey || ev.ctrlKey) - return - - /* Search is open */ - if (toggle.checked) { - - /* Enter: prevent form submission */ - if (ev.keyCode === 13) { - if (query === document.activeElement) { - ev.preventDefault() - - /* Go to current active/focused link */ - const focus = document.querySelector( - "[data-md-component=search] [href][data-md-state=active]") - if (focus instanceof HTMLLinkElement) { - window.location = focus.getAttribute("href") - - /* Close search */ - toggle.checked = false - toggle.dispatchEvent(new CustomEvent("change")) - query.blur() - } - } - - /* Escape or Tab: close search */ - } else if (ev.keyCode === 9 || ev.keyCode === 27) { - toggle.checked = false - toggle.dispatchEvent(new CustomEvent("change")) - query.blur() - - /* Horizontal arrows and backspace: focus input */ - } else if ([8, 37, 39].indexOf(ev.keyCode) !== -1) { - if (query !== document.activeElement) - query.focus() - - /* Vertical arrows: select previous or next search result */ - } else if ([38, 40].indexOf(ev.keyCode) !== -1) { - const key = ev.keyCode - - /* Retrieve all results */ - const links = Array.prototype.slice.call( - document.querySelectorAll( - "[data-md-component=query], [data-md-component=search] [href]")) - - /* Retrieve current active/focused result */ - const focus = links.find(link => { - if (!(link instanceof HTMLElement)) - throw new ReferenceError - return link.dataset.mdState === "active" - }) - if (focus) - focus.dataset.mdState = "" - - /* Calculate index depending on direction, add length to form ring */ - const index = Math.max(0, ( - links.indexOf(focus) + links.length + (key === 38 ? -1 : +1) - ) % links.length) - - /* Set active state and focus */ - if (links[index]) { - links[index].dataset.mdState = "active" - links[index].focus() - } - - /* Prevent scrolling of page */ - ev.preventDefault() - ev.stopPropagation() - - /* Return false prevents the cursor position from changing */ - return false - } - - /* Search is closed and we're not inside a form */ - } else if (document.activeElement && !document.activeElement.form) { - - /* Fixes #1026: search grabs focus for non-form input elements */ - if (document.activeElement.tagName === "TEXTAREA" || - document.activeElement.tagName === "INPUT") - return - - /* F/S: Open search if not in input field */ - if (ev.keyCode === 70 || ev.keyCode === 83) { - query.focus() - ev.preventDefault() - } - } - }).listen() - - /* Listener: focus query if in search is open and character is typed */ - new Material.Event.Listener(window, "keypress", () => { - const toggle = document.querySelector("[data-md-toggle=search]") - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - const query = document.querySelector("[data-md-component=query]") - if (!(query instanceof HTMLInputElement)) - throw new ReferenceError - if (query !== document.activeElement) - query.focus() - } - }).listen() - } - - /* Listener: handle tabbing context for better accessibility */ - new Material.Event.Listener(document.body, "keydown", ev => { - if (ev.keyCode === 9) { - const labels = document.querySelectorAll( - "[data-md-component=navigation] .md-nav__link[for]:not([tabindex])") - Array.prototype.forEach.call(labels, label => { - if (label.offsetHeight) - label.tabIndex = 0 - }) - } - }).listen() - - /* Listener: reset tabbing behavior */ - new Material.Event.Listener(document.body, "mousedown", () => { - const labels = document.querySelectorAll( - "[data-md-component=navigation] .md-nav__link[tabindex]") - Array.prototype.forEach.call(labels, label => { - label.removeAttribute("tabIndex") - }) - }).listen() - - document.body.addEventListener("click", () => { - if (document.body.dataset.mdState === "tabbing") - document.body.dataset.mdState = "" - }) - - /* Listener: close drawer when anchor links are clicked */ - new Material.Event.MatchMedia("(max-width: 959px)", - new Material.Event.Listener("[data-md-component=navigation] [href^='#']", - "click", () => { - const toggle = document.querySelector("[data-md-toggle=drawer]") - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - toggle.checked = false - toggle.dispatchEvent(new CustomEvent("change")) - } - })) - - /* Retrieve facts for the given repository type */ - ;(() => { - const el = document.querySelector("[data-md-source]") - if (!el) - return Promise.resolve([]) - else if (!(el instanceof HTMLAnchorElement)) - throw new ReferenceError - switch (el.dataset.mdSource) { - case "github": return new Material.Source.Adapter.GitHub(el).fetch() - default: return Promise.resolve([]) - } - - /* Render repository information */ - })().then(facts => { - const sources = document.querySelectorAll("[data-md-source]") - Array.prototype.forEach.call(sources, source => { - new Material.Source.Repository(source) - .initialize(facts) - }) - }) - - /* Before-print hook */ - const print = () => { - const details = document.querySelectorAll("details") - Array.prototype.forEach.call(details, detail => { - detail.setAttribute("open", "") - }) - } - - /* Open details before printing */ - new Material.Event.MatchMedia("print", { - listen: print, unlisten: () => {} - }) // Webkit - window.onbeforeprint = print // IE, FF -} - -/* ---------------------------------------------------------------------------- - * Exports - * ------------------------------------------------------------------------- */ - -/* Provide this for downward compatibility for now */ -const app = { - initialize -} - -export { - app -} diff --git a/src/assets/javascripts/components/Material.js b/src/assets/javascripts/components/Material.js deleted file mode 100644 index b4a5f5e4d..000000000 --- a/src/assets/javascripts/components/Material.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Event from "./Material/Event" -import Header from "./Material/Header" -import Nav from "./Material/Nav" -import Search from "./Material/Search" -import Sidebar from "./Material/Sidebar" -import Source from "./Material/Source" -import Tabs from "./Material/Tabs" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Event, - Header, - Nav, - Search, - Sidebar, - Source, - Tabs -} diff --git a/src/assets/javascripts/components/Material/Event.js b/src/assets/javascripts/components/Material/Event.js deleted file mode 100644 index de6dd21f7..000000000 --- a/src/assets/javascripts/components/Material/Event.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Listener from "./Event/Listener" -import MatchMedia from "./Event/MatchMedia" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Listener, - MatchMedia -} diff --git a/src/assets/javascripts/components/Material/Event/Listener.js b/src/assets/javascripts/components/Material/Event/Listener.js deleted file mode 100644 index 024d3f542..000000000 --- a/src/assets/javascripts/components/Material/Event/Listener.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Listener { - - /** - * Generic event listener - * - * @constructor - * - * @property {(Array)} els_ - Event targets - * @property {Object} handler_- Event handlers - * @property {Array} events_ - Event names - * @property {Function} update_ - Update handler - * - * @param {?(string|EventTarget|NodeList)} els - - * Selector or Event targets - * @param {(string|Array)} events - Event names - * @param {(Object|Function)} handler - Handler to be invoked - */ - constructor(els, events, handler) { - this.els_ = Array.prototype.slice.call( - (typeof els === "string") - ? document.querySelectorAll(els) - : [].concat(els)) - - /* Set handler as function or directly as object */ - this.handler_ = typeof handler === "function" - ? { update: handler } - : handler - - /* Initialize event names and update handler */ - this.events_ = [].concat(events) - this.update_ = ev => this.handler_.update(ev) - } - - /** - * Register listener for all relevant events - */ - listen() { - this.els_.forEach(el => { - this.events_.forEach(event => { - el.addEventListener(event, this.update_, false) - }) - }) - - /* Execute setup handler, if implemented */ - if (typeof this.handler_.setup === "function") - this.handler_.setup() - } - - /** - * Unregister listener for all relevant events - */ - unlisten() { - this.els_.forEach(el => { - this.events_.forEach(event => { - el.removeEventListener(event, this.update_) - }) - }) - - /* Execute reset handler, if implemented */ - if (typeof this.handler_.reset === "function") - this.handler_.reset() - } -} diff --git a/src/assets/javascripts/components/Material/Event/MatchMedia.js b/src/assets/javascripts/components/Material/Event/MatchMedia.js deleted file mode 100644 index 235f11f51..000000000 --- a/src/assets/javascripts/components/Material/Event/MatchMedia.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Listener from "./Listener" // eslint-disable-line no-unused-vars - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class MatchMedia { - - /** - * Media query listener - * - * This class listens for state changes of media queries and automatically - * switches the given listeners on or off. - * - * @constructor - * - * @property {Function} handler_ - Media query event handler - * - * @param {string} query - Media query to test for - * @param {Listener} listener - Event listener - */ - constructor(query, listener) { - this.handler_ = mq => { - if (mq.matches) - listener.listen() - else - listener.unlisten() - } - - /* Initialize media query listener */ - const media = window.matchMedia(query) - media.addListener(this.handler_) - - /* Always check at initialization */ - this.handler_(media) - } -} diff --git a/src/assets/javascripts/components/Material/Header.js b/src/assets/javascripts/components/Material/Header.js deleted file mode 100644 index 9894b6195..000000000 --- a/src/assets/javascripts/components/Material/Header.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Shadow from "./Header/Shadow" -import Title from "./Header/Title" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Shadow, - Title -} diff --git a/src/assets/javascripts/components/Material/Header/Shadow.js b/src/assets/javascripts/components/Material/Header/Shadow.js deleted file mode 100644 index 4a4d99b99..000000000 --- a/src/assets/javascripts/components/Material/Header/Shadow.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Shadow { - - /** - * Show or hide header shadow depending on page y-offset - * - * @constructor - * - * @property {HTMLElement} el_ - Content container - * @property {HTMLElement} header_ - Header - * @property {number} height_ - Offset height of previous nodes - * @property {boolean} active_ - Header shadow state - * - * @param {(string|HTMLElement)} el - Selector or HTML element - * @param {(string|HTMLElement)} header - Selector or HTML element - */ - constructor(el, header) { - let ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement) || - !(ref.parentNode instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref.parentNode - - /* Retrieve header */ - ref = (typeof header === "string") - ? document.querySelector(header) - : header - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.header_ = ref - - /* Initialize height and state */ - this.height_ = 0 - this.active_ = false - } - - /** - * Calculate total height of previous nodes - */ - setup() { - let current = this.el_ - while ((current = current.previousElementSibling)) { - if (!(current instanceof HTMLElement)) - throw new ReferenceError - this.height_ += current.offsetHeight - } - this.update() - } - - /** - * Update shadow state - * - * @param {Event} ev - Event - */ - update(ev) { - if (ev && (ev.type === "resize" || ev.type === "orientationchange")) { - this.height_ = 0 - this.setup() - } else { - const active = window.pageYOffset >= this.height_ - if (active !== this.active_) - this.header_.dataset.mdState = (this.active_ = active) ? "shadow" : "" - } - } - - /** - * Reset shadow state - */ - reset() { - this.header_.dataset.mdState = "" - this.height_ = 0 - this.active_ = false - } -} diff --git a/src/assets/javascripts/components/Material/Header/Title.js b/src/assets/javascripts/components/Material/Header/Title.js deleted file mode 100644 index 394a849da..000000000 --- a/src/assets/javascripts/components/Material/Header/Title.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Title { - - /** - * Swap header title topics when header is scrolled past - * - * @constructor - * - * @property {HTMLElement} el_ - Element - * @property {HTMLElement} header_ - Header - * @property {boolean} active_ - Title state - * - * @param {(string|HTMLElement)} el - Selector or HTML element - * @param {(string|HTMLHeadingElement)} header - Selector or HTML element - */ - constructor(el, header) { - let ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - - /* Retrieve header */ - ref = (typeof header === "string") - ? document.querySelector(header) - : header - if (!(ref instanceof HTMLHeadingElement)) - throw new ReferenceError - this.header_ = ref - - /* Initialize state */ - this.active_ = false - } - - /** - * Setup title state - */ - setup() { - Array.prototype.forEach.call(this.el_.children, node => { // TODO: use childNodes here for IE? - node.style.width = `${this.el_.offsetWidth - 20}px` - }) - } - - /** - * Update title state - * - * @param {Event} ev - Event - */ - update(ev) { - const active = window.pageYOffset >= this.header_.offsetTop - if (active !== this.active_) - this.el_.dataset.mdState = (this.active_ = active) ? "active" : "" - - /* Hack: induce ellipsis on topics */ - if (ev.type === "resize" || ev.type === "orientationchange") { - Array.prototype.forEach.call(this.el_.children, node => { - node.style.width = `${this.el_.offsetWidth - 20}px` - }) - } - - } - - /** - * Reset title state - */ - reset() { - this.el_.dataset.mdState = "" - this.el_.style.width = "" - this.active_ = false - } -} diff --git a/src/assets/javascripts/components/Material/Nav.js b/src/assets/javascripts/components/Material/Nav.js deleted file mode 100644 index c6a83c1d2..000000000 --- a/src/assets/javascripts/components/Material/Nav.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Blur from "./Nav/Blur" -import Collapse from "./Nav/Collapse" -import Scrolling from "./Nav/Scrolling" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Blur, - Collapse, - Scrolling -} diff --git a/src/assets/javascripts/components/Material/Nav/Blur.js b/src/assets/javascripts/components/Material/Nav/Blur.js deleted file mode 100644 index fd5a81982..000000000 --- a/src/assets/javascripts/components/Material/Nav/Blur.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Blur { - - /** - * Blur links within the table of contents above current page y-offset - * - * @constructor - * - * @property {NodeList} els_ - Table of contents links - * @property {Array} anchors_ - Referenced anchor nodes - * @property {number} index_ - Current link index - * @property {number} offset_ - Current page y-offset - * @property {boolean} dir_ - Scroll direction change - * - * @param {(string|NodeList)} els - Selector or HTML elements - */ - constructor(els) { - this.els_ = (typeof els === "string") - ? document.querySelectorAll(els) - : els - - /* Initialize index and page y-offset */ - this.index_ = 0 - this.offset_ = window.pageYOffset - - /* Necessary state to correctly reset the index */ - this.dir_ = false - - /* Index anchor node offsets for fast lookup */ - this.anchors_ = [].reduce.call(this.els_, (anchors, el) => { - const hash = decodeURIComponent(el.hash) - return anchors.concat( - document.getElementById(hash.substring(1)) || []) - }, []) - } - - /** - * Initialize blur states - */ - setup() { - this.update() - } - - /** - * Update blur states - * - * Deduct the static offset of the header (56px) and sidebar offset (24px), - * see _permalinks.scss for more information. - */ - update() { - const offset = window.pageYOffset - const dir = this.offset_ - offset < 0 - - /* Hack: reset index if direction changed to catch very fast scrolling, - because otherwise we would have to register a timer and that sucks */ - if (this.dir_ !== dir) - this.index_ = dir - ? this.index_ = 0 - : this.index_ = this.els_.length - 1 - - /* Exit when there are no anchors */ - if (this.anchors_.length === 0) - return - - /* Scroll direction is down */ - if (this.offset_ <= offset) { - for (let i = this.index_ + 1; i < this.els_.length; i++) { - if (this.anchors_[i].offsetTop - (56 + 24) <= offset) { - if (i > 0) - this.els_[i - 1].dataset.mdState = "blur" - this.index_ = i - } else { - break - } - } - - /* Scroll direction is up */ - } else { - for (let i = this.index_; i >= 0; i--) { - if (this.anchors_[i].offsetTop - (56 + 24) > offset) { - if (i > 0) - this.els_[i - 1].dataset.mdState = "" - } else { - this.index_ = i - break - } - } - } - - /* Remember current offset and direction for next iteration */ - this.offset_ = offset - this.dir_ = dir - } - - /** - * Reset blur states - */ - reset() { - Array.prototype.forEach.call(this.els_, el => { - el.dataset.mdState = "" - }) - - /* Reset index and page y-offset */ - this.index_ = 0 - this.offset_ = window.pageYOffset - } -} diff --git a/src/assets/javascripts/components/Material/Nav/Collapse.js b/src/assets/javascripts/components/Material/Nav/Collapse.js deleted file mode 100644 index a362bb4e0..000000000 --- a/src/assets/javascripts/components/Material/Nav/Collapse.js +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Collapse { - - /** - * Expand or collapse navigation on toggle - * - * @constructor - * - * @property {HTMLElement} el_ - Navigation list - * - * @param {(string|HTMLElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - } - - /** - * Initialize overflow and display for accessibility - */ - setup() { - const current = this.el_.getBoundingClientRect().height - - /* Hidden links should not be focusable, so hide them when the navigation - is collapsed and set overflow so the outline is not cut off */ - this.el_.style.display = current ? "block" : "none" - this.el_.style.overflow = current ? "visible" : "hidden" - } - - /** - * Animate expand and collapse smoothly - * - * Internet Explorer 11 is very slow at recognizing changes on the dataset - * which results in the menu not expanding or collapsing properly. THerefore, - * for reasons of compatibility, the attribute accessors are used. - */ - update() { - const current = this.el_.getBoundingClientRect().height - - /* Reset overflow to CSS defaults */ - this.el_.style.display = "block" - this.el_.style.overflow = "" - - /* Hack: read value directly from input field */ - const expanded = this.el_ - .previousElementSibling - .previousElementSibling - .checked - - /* Expanded, so collapse */ - if (expanded) { - this.el_.style.maxHeight = `${current}px` - requestAnimationFrame(() => { - this.el_.setAttribute("data-md-state", "animate") - this.el_.style.maxHeight = "0px" - }) - - /* Collapsed, so expand */ - } else { - this.el_.setAttribute("data-md-state", "expand") - this.el_.style.maxHeight = "" - - /* Read height and unset pseudo-toggled state */ - const height = this.el_.getBoundingClientRect().height - this.el_.removeAttribute("data-md-state") - - /* Set initial state and animate */ - this.el_.style.maxHeight = "0px" - requestAnimationFrame(() => { - this.el_.setAttribute("data-md-state", "animate") - this.el_.style.maxHeight = `${height}px` - }) - } - - /* Remove state on end of transition */ - const end = ev => { - const target = ev.target - if (!(target instanceof HTMLElement)) - throw new ReferenceError - - /* Reset height and state */ - target.removeAttribute("data-md-state") - target.style.maxHeight = "" - - /* Hidden links should not be focusable, so hide them when the navigation - is collapsed and set overflow so the outline is not cut off */ - target.style.display = expanded ? "none" : "block" - target.style.overflow = expanded ? "hidden" : "visible" - - /* Only fire once, so directly remove event listener */ - target.removeEventListener("transitionend", end) - } - this.el_.addEventListener("transitionend", end, false) - } - - /** - * Reset height and pseudo-toggled state - */ - reset() { - this.el_.dataset.mdState = "" - this.el_.style.maxHeight = "" - this.el_.style.display = "" - this.el_.style.overflow = "" - } -} diff --git a/src/assets/javascripts/components/Material/Nav/Scrolling.js b/src/assets/javascripts/components/Material/Nav/Scrolling.js deleted file mode 100644 index 06816efd6..000000000 --- a/src/assets/javascripts/components/Material/Nav/Scrolling.js +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Scrolling { - - /** - * Set overflow scrolling on the current active pane (for iOS) - * - * @constructor - * - * @property {HTMLElement} el_ - Primary navigation - * - * @param {(string|HTMLElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - } - - /** - * Setup panes - */ - setup() { - - /* Initially set overflow scrolling on main pane */ - const main = this.el_.children[this.el_.children.length - 1] - main.style.webkitOverflowScrolling = "touch" - - /* Find all toggles and check which one is active */ - const toggles = this.el_.querySelectorAll("[data-md-toggle]") - Array.prototype.forEach.call(toggles, toggle => { - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - - /* Find corresponding navigational pane */ - let pane = toggle.nextElementSibling - if (!(pane instanceof HTMLElement)) - throw new ReferenceError - while (pane.tagName !== "NAV" && pane.nextElementSibling) - pane = pane.nextElementSibling - - /* Check references */ - if (!(toggle.parentNode instanceof HTMLElement) || - !(toggle.parentNode.parentNode instanceof HTMLElement)) - throw new ReferenceError - - /* Find current and parent list elements */ - const parent = toggle.parentNode.parentNode - const target = pane.children[pane.children.length - 1] - - /* Always reset all lists when transitioning */ - parent.style.webkitOverflowScrolling = "" - target.style.webkitOverflowScrolling = "touch" - } - }) - } - - /** - * Update active panes - * - * @param {Event} ev - Change event - */ - update(ev) { - const target = ev.target - if (!(target instanceof HTMLElement)) - throw new ReferenceError - - /* Find corresponding navigational pane */ - let pane = target.nextElementSibling - if (!(pane instanceof HTMLElement)) - throw new ReferenceError - while (pane.tagName !== "NAV" && pane.nextElementSibling) - pane = pane.nextElementSibling - - /* Check references */ - if (!(target.parentNode instanceof HTMLElement) || - !(target.parentNode.parentNode instanceof HTMLElement)) - throw new ReferenceError - - /* Find parent and active panes */ - const parent = target.parentNode.parentNode - const active = pane.children[pane.children.length - 1] - - /* Always reset all lists when transitioning */ - parent.style.webkitOverflowScrolling = "" - active.style.webkitOverflowScrolling = "" - - /* Set overflow scrolling on parent pane */ - if (!target.checked) { - const end = () => { - if (pane instanceof HTMLElement) { - parent.style.webkitOverflowScrolling = "touch" - pane.removeEventListener("transitionend", end) - } - } - pane.addEventListener("transitionend", end, false) - } - - /* Set overflow scrolling on active pane */ - if (target.checked) { - const end = () => { - if (pane instanceof HTMLElement) { - active.style.webkitOverflowScrolling = "touch" - pane.removeEventListener("transitionend", end) - } - } - pane.addEventListener("transitionend", end, false) - } - } - - /** - * Reset panes - */ - reset() { - - /* Reset overflow scrolling on main pane */ - this.el_.children[1].style.webkitOverflowScrolling = "" - - /* Find all toggles and check which one is active */ - const toggles = this.el_.querySelectorAll("[data-md-toggle]") - Array.prototype.forEach.call(toggles, toggle => { - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - - /* Find corresponding navigational pane */ - let pane = toggle.nextElementSibling - if (!(pane instanceof HTMLElement)) - throw new ReferenceError - while (pane.tagName !== "NAV" && pane.nextElementSibling) - pane = pane.nextElementSibling - - /* Check references */ - if (!(toggle.parentNode instanceof HTMLElement) || - !(toggle.parentNode.parentNode instanceof HTMLElement)) - throw new ReferenceError - - /* Find parent and active panes */ - const parent = toggle.parentNode.parentNode - const active = pane.children[pane.children.length - 1] - - /* Always reset all lists when transitioning */ - parent.style.webkitOverflowScrolling = "" - active.style.webkitOverflowScrolling = "" - } - }) - } -} diff --git a/src/assets/javascripts/components/Material/Search.js b/src/assets/javascripts/components/Material/Search.js deleted file mode 100644 index cdcbaa4a6..000000000 --- a/src/assets/javascripts/components/Material/Search.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Lock from "./Search/Lock" -import Result from "./Search/Result" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Lock, - Result -} diff --git a/src/assets/javascripts/components/Material/Search/Lock.js b/src/assets/javascripts/components/Material/Search/Lock.js deleted file mode 100644 index 7f39fe582..000000000 --- a/src/assets/javascripts/components/Material/Search/Lock.js +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Lock { - - /** - * Lock body for full-screen search modal - * - * @constructor - * - * @property {HTMLInputElement} el_ - Lock toggle - * @property {HTMLElement} lock_ - Element to lock (document body) - * @property {number} offset_ - Current page y-offset - * - * @param {(string|HTMLElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLInputElement)) - throw new ReferenceError - this.el_ = ref - - /* Retrieve element to lock (= body) */ - if (!document.body) - throw new ReferenceError - this.lock_ = document.body - } - - /** - * Setup locked state - */ - setup() { - this.update() - } - - /** - * Update locked state - */ - update() { - - /* Entering search mode */ - if (this.el_.checked) { - this.offset_ = window.pageYOffset - - /* Scroll to top after transition, to omit flickering */ - setTimeout(() => { - window.scrollTo(0, 0) - - /* Lock body after finishing transition */ - if (this.el_.checked) { - this.lock_.dataset.mdState = "lock" - } - }, 400) - - /* Exiting search mode */ - } else { - this.lock_.dataset.mdState = "" - - /* Scroll to former position, but wait for 100ms to prevent flashes on - iOS. A short timeout seems to do the trick */ - setTimeout(() => { - if (typeof this.offset_ !== "undefined") - window.scrollTo(0, this.offset_) - }, 100) - } - } - - /** - * Reset locked state and page y-offset - */ - reset() { - if (this.lock_.dataset.mdState === "lock") - window.scrollTo(0, this.offset_) - this.lock_.dataset.mdState = "" - } -} diff --git a/src/assets/javascripts/components/Material/Search/Result.jsx b/src/assets/javascripts/components/Material/Search/Result.jsx deleted file mode 100644 index 4c876de54..000000000 --- a/src/assets/javascripts/components/Material/Search/Result.jsx +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import lunr from "expose-loader?lunr!lunr" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Escape a regular expression string - * - * Taken from the package `escape-string-regexp` - * - * @param regex - Regular expresison string - * - * @return - */ -const escapeRegex = regex => { - return regex.replace(/[|\\{}()[\]^$+*?.-]/g, '\\$&'); -}; - -/** - * Escape HTML strings - * - * Documentation may contain code JavaScript code snippets which would get - * executed when inserted into the DOM as plain HTML. - * - * See https://github.com/squidfunk/mkdocs-material/issues/906 - * - * @param {string} html - HTML string - * - * @return {string} Escaped HTML string - */ -const escapeHTML = html => { - var text = document.createTextNode(html); - var p = document.createElement('p'); - p.appendChild(text); - return p.innerHTML; -} - -/** - * Truncate a string after the given number of character - * - * This is not a 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. - * - * @param {string} string - String to be truncated - * @param {number} n - Number of characters - * @return {string} Truncated string - */ -const truncate = (string, n) => { - let i = n - if (string.length > i) { - while (string[i] !== " " && --i > 0); - return `${string.substring(0, i)}...` - } - return string -} - -/** - * Return the meta tag value for the given key - * - * @param {string} key - Meta name - * - * @return {string} Meta content value - */ -const translate = key => { - const meta = document.getElementsByName(`lang:${key}`)[0] - if (!(meta instanceof HTMLMetaElement)) - throw new ReferenceError - return meta.content -} - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Result { - - /** - * Perform search and update results on keyboard events - * - * @constructor - * - * @property {HTMLElement} el_ - Search result container - * @property {(Array|Function)} data_ - Raw document data - * @property {Object} docs_ - Indexed documents - * @property {HTMLElement} meta_ - Search meta information - * @property {HTMLElement} list_ - Search result list - * @property {Array} lang_ - Search languages - * @property {Object} message_ - Search result messages - * @property {Object} index_ - Search index - * @property {Array} stack_ - Search result stack - * @property {string} value_ - Last input value - * - * @param {(string|HTMLElement)} el - Selector or HTML element - * @param {(Array|Function)} data - Function providing data or array - */ - constructor(el, data) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - - /* Retrieve metadata and list element */ - const [meta, list] = Array.prototype.slice.call(this.el_.children) - - /* Set data, metadata and list elements */ - this.data_ = data - this.meta_ = meta - this.list_ = list - - /* Load messages for metadata display */ - this.message_ = { - placeholder: this.meta_.textContent, - none: translate("search.result.none"), - one: translate("search.result.one"), - other: translate("search.result.other") - } - - /* Override tokenizer separator, if given */ - const tokenizer = translate("search.tokenizer") - if (tokenizer.length) - lunr.tokenizer.separator = tokenizer - - /* Load search languages */ - this.lang_ = translate("search.language").split(",") - .filter(Boolean) - .map(lang => lang.trim()) - } - - /** - * Update search results - * - * @param {Event} ev - Input or focus event - */ - update(ev) { - - /* Initialize index, if this has not be done yet */ - if (ev.type === "focus" && !this.index_) { - - /* Initialize index */ - const init = data => { - - /* Preprocess and index sections and documents */ - this.docs_ = data.reduce((docs, doc) => { - const [path, hash] = doc.location.split("#") - - /* Escape HTML */ - doc.text = escapeHTML(doc.text) - - /* Associate section with parent document */ - if (hash) { - doc.parent = docs.get(path) - - /* Override page title with document title if first section */ - if (doc.parent && !doc.parent.done) { - doc.parent.title = doc.title - doc.parent.text = doc.text - doc.parent.done = true - } - } - - /* Some cleanup on the text */ - doc.text = doc.text - .replace(/\n/g, " ") /* Remove newlines */ - .replace(/\s+/g, " ") /* Compact whitespace */ - .replace(/\s+([,.:;!?])/g, /* Correct punctuation */ - (_, char) => char) - - /* Index sections and documents, but skip top-level headline */ - if (!doc.parent || doc.parent.title !== doc.title) - docs.set(doc.location, doc) - return docs - }, new Map) - - /* eslint-disable no-invalid-this */ - const docs = this.docs_, - lang = this.lang_ - - /* Create stack and index */ - this.stack_ = [] - this.index_ = lunr(function() { - const filters = { - "search.pipeline.trimmer": lunr.trimmer, - "search.pipeline.stopwords": lunr.stopWordFilter - } - - /* Disable stop words filter and trimmer, if desired */ - const pipeline = Object.keys(filters).reduce((result, name) => { - if (!translate(name).match(/^false$/i)) - result.push(filters[name]) - return result - }, []) - - /* Remove stemmer, as it cripples search experience */ - this.pipeline.reset() - if (pipeline) - this.pipeline.add(...pipeline) - - /* Set up alternate search languages */ - if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) { - this.use(lunr[lang[0]]) - } else if (lang.length > 1) { - this.use(lunr.multiLanguage(...lang)) - } - - /* Index fields */ - this.field("title", { boost: 10 }) - this.field("text") - this.ref("location") - - /* Index documents */ - docs.forEach(doc => this.add(doc)) - }) - - /* Register event handler for lazy rendering */ - const container = this.el_.parentNode - if (!(container instanceof HTMLElement)) - throw new ReferenceError - container.addEventListener("scroll", () => { - while (this.stack_.length && container.scrollTop + - container.offsetHeight >= container.scrollHeight - 16) - this.stack_.splice(0, 10).forEach(render => render()) - }) - } - /* eslint-enable no-invalid-this */ - - /* Initialize index after short timeout to account for transition */ - setTimeout(() => { - return typeof this.data_ === "function" - ? this.data_().then(init) - : init(this.data_) - }, 250) - - /* Execute search on new input event */ - } else if (ev.type === "focus" || ev.type === "keyup") { - const target = ev.target - if (!(target instanceof HTMLInputElement)) - throw new ReferenceError - - /* Abort early, if index is not build or input hasn't changed */ - if (!this.index_ || target.value === this.value_) - return - - /* Clear current list */ - while (this.list_.firstChild) - this.list_.removeChild(this.list_.firstChild) - - /* Abort early, if search input is empty */ - this.value_ = target.value - if (this.value_.length === 0) { - this.meta_.textContent = this.message_.placeholder - return - } - - /* Perform search on index and group sections by document */ - const result = this.index_ - - /* Append trailing wildcard to all terms for prefix querying */ - .query(query => { - this.value_.toLowerCase().split(" ") - .filter(Boolean) - .forEach(term => { - query.term(term, { wildcard: lunr.Query.wildcard.TRAILING }) - }) - }) - - /* Process query results */ - .reduce((items, item) => { - const doc = this.docs_.get(item.ref) - if (doc.parent) { - const ref = doc.parent.location - items.set(ref, (items.get(ref) || []).concat(item)) - } else { - const ref = doc.location - items.set(ref, (items.get(ref) || [])) - } - return items - }, new Map) - - /* Assemble regular expressions for matching */ - const query = escapeRegex(this.value_.trim()).replace( - new RegExp(lunr.tokenizer.separator, "img"), "|") - const match = - new RegExp(`(^|${lunr.tokenizer.separator})(${query})`, "img") - const highlight = (_, separator, token) => - `${separator}${token}` - - /* Reset stack and render results */ - this.stack_ = [] - result.forEach((items, ref) => { - const doc = this.docs_.get(ref) - - /* Render article */ - const article = ( -
  • - -
    -

    - {{ __html: doc.title.replace(match, highlight) }} -

    - {doc.text.length ? -

    - {{ __html: doc.text.replace(match, highlight) }} -

    : {}} -
    -
    -
  • - ) - - /* Render sections for article */ - const sections = items.map(item => { - return () => { - const section = this.docs_.get(item.ref) - article.appendChild( - -
    -

    - {{ __html: section.title.replace(match, highlight) }} -

    - {section.text.length ? -

    - {{ __html: truncate( - section.text.replace(match, highlight), 400) - }} -

    : {}} -
    -
    - ) - } - }) - - /* Push articles and section renderers onto stack */ - this.stack_.push(() => this.list_.appendChild(article), ...sections) - }) - - /* Gradually add results as long as the height of the container grows */ - const container = this.el_.parentNode - if (!(container instanceof HTMLElement)) - throw new ReferenceError - while (this.stack_.length && - container.offsetHeight >= container.scrollHeight - 16) - (this.stack_.shift())() - - /* Bind click handlers for anchors */ - const anchors = this.list_.querySelectorAll("[data-md-rel=anchor]") - Array.prototype.forEach.call(anchors, anchor => { - ["click", "keydown"].forEach(action => { - anchor.addEventListener(action, ev2 => { - if (action === "keydown" && ev2.keyCode !== 13) - return - - /* Close search */ - const toggle = document.querySelector("[data-md-toggle=search]") - if (!(toggle instanceof HTMLInputElement)) - throw new ReferenceError - if (toggle.checked) { - toggle.checked = false - toggle.dispatchEvent(new CustomEvent("change")) - } - - /* Hack: prevent default, as the navigation needs to be delayed due - to the search body lock on mobile */ - ev2.preventDefault() - setTimeout(() => { - document.location.href = anchor.href - }, 100) - }) - }) - }) - - /* Update search metadata */ - switch (result.size) { - case 0: - this.meta_.textContent = this.message_.none - break - case 1: - this.meta_.textContent = this.message_.one - break - default: - this.meta_.textContent = - this.message_.other.replace("#", result.size) - } - } - } -} diff --git a/src/assets/javascripts/components/Material/Sidebar.js b/src/assets/javascripts/components/Material/Sidebar.js deleted file mode 100644 index cfc9bf707..000000000 --- a/src/assets/javascripts/components/Material/Sidebar.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Position from "./Sidebar/Position" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Position -} diff --git a/src/assets/javascripts/components/Material/Sidebar/Position.js b/src/assets/javascripts/components/Material/Sidebar/Position.js deleted file mode 100644 index 171243926..000000000 --- a/src/assets/javascripts/components/Material/Sidebar/Position.js +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Position { - - /** - * Set sidebars to locked state and limit height to parent node - * - * @constructor - * - * @property {HTMLElement} el_ - Sidebar - * @property {HTMLElement} parent_ - Sidebar container - * @property {HTMLElement} header_ - Header - * @property {number} height_ - Current sidebar height - * @property {number} offset_ - Current page y-offset - * @property {boolean} pad_ - Pad when header is fixed - * - * @param {(string|HTMLElement)} el - Selector or HTML element - * @param {(string|HTMLElement)} header - Selector or HTML element - */ - constructor(el, header) { - let ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement) || - !(ref.parentNode instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - this.parent_ = ref.parentNode - - /* Retrieve header */ - ref = (typeof header === "string") - ? document.querySelector(header) - : header - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.header_ = ref - - /* Initialize current height and test whether header is fixed */ - this.height_ = 0 - this.pad_ = window.getComputedStyle(this.header_).position === "fixed" - } - - /** - * Initialize sidebar state - */ - setup() { - const top = Array.prototype.reduce.call( - this.parent_.children, (offset, child) => { - return Math.max(offset, child.offsetTop) - }, 0) - - /* Set lock offset for element with largest top offset */ - this.offset_ = top - (this.pad_ ? this.header_.offsetHeight : 0) - this.update() - } - - /** - * Update locked state and height - * - * The inner height of the window (= the visible area) is the maximum - * possible height for the stretching sidebar. This height must be deducted - * by the height of the fixed header (56px). Depending on the page y-offset, - * the top offset of the sidebar must be taken into account, as well as the - * case where the window is scrolled beyond the sidebar container. - * - * @param {Event?} ev - Event - */ - update(ev) { - const offset = window.pageYOffset - const visible = window.innerHeight - - /* Update offset, in case window is resized */ - if (ev && ev.type === "resize") - this.setup() - - /* Set bounds of sidebar container - must be calculated on every run, as - the height of the content might change due to loading images etc. */ - const bounds = { - top: this.pad_ ? this.header_.offsetHeight : 0, - bottom: this.parent_.offsetTop + this.parent_.offsetHeight - } - - /* Calculate new offset and height */ - const height = visible - bounds.top - - Math.max(0, this.offset_ - offset) - - Math.max(0, offset + visible - bounds.bottom) - - /* If height changed, update element */ - if (height !== this.height_) - this.el_.style.height = `${this.height_ = height}px` - - /* Sidebar should be locked, as we're below parent offset */ - if (offset >= this.offset_) { - if (this.el_.dataset.mdState !== "lock") - this.el_.dataset.mdState = "lock" - - /* Sidebar should be unlocked, if locked */ - } else if (this.el_.dataset.mdState === "lock") { - this.el_.dataset.mdState = "" - } - } - - /** - * Reset locked state and height - */ - reset() { - this.el_.dataset.mdState = "" - this.el_.style.height = "" - this.height_ = 0 - } -} diff --git a/src/assets/javascripts/components/Material/Source.js b/src/assets/javascripts/components/Material/Source.js deleted file mode 100644 index d085c75a6..000000000 --- a/src/assets/javascripts/components/Material/Source.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Adapter from "./Source/Adapter" -import Repository from "./Source/Repository" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Adapter, - Repository -} diff --git a/src/assets/javascripts/components/Material/Source/Adapter.js b/src/assets/javascripts/components/Material/Source/Adapter.js deleted file mode 100644 index f67ebb0f6..000000000 --- a/src/assets/javascripts/components/Material/Source/Adapter.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import GitHub from "./Adapter/GitHub" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - GitHub -} diff --git a/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js b/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js deleted file mode 100644 index 19a82474c..000000000 --- a/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Cookies from "js-cookie" - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Abstract { - - /** - * Retrieve repository information - * - * @constructor - * - * @property {HTMLAnchorElement} el_ - Link to repository - * @property {string} base_ - API base URL - * @property {number} salt_ - Unique identifier - * - * @param {(string|HTMLAnchorElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLAnchorElement)) - throw new ReferenceError - this.el_ = ref - - /* Retrieve base URL */ - this.base_ = this.el_.href - this.salt_ = this.hash_(this.base_) - } - - /** - * Retrieve data from Cookie or fetch from respective API - * - * @return {Promise>} Promise that returns an array of facts - */ - fetch() { - return new Promise(resolve => { - const cached = Cookies.getJSON(`${this.salt_}.cache-source`) - if (typeof cached !== "undefined") { - resolve(cached) - - /* If the data is not cached in a cookie, invoke fetch and set - a cookie that automatically expires in 15 minutes */ - } else { - this.fetch_().then(data => { - Cookies.set(`${this.salt_}.cache-source`, data, { expires: 1 / 96 }) - resolve(data) - }) - } - }) - } - - /** - * Abstract private function that fetches relevant repository information - * - * @abstract - */ - fetch_() { - throw new Error("fetch_(): Not implemented") - } - - /** - * Format a number with suffix - * - * @param {number} number - Number to format - * @return {string} Formatted number - */ - format_(number) { - if (number > 10000) - return `${(number / 1000).toFixed(0)}k` - else if (number > 1000) - return `${(number / 1000).toFixed(1)}k` - return `${number}` - } - - /** - * Simple hash function - * - * Taken from http://stackoverflow.com/a/7616484/1065584 - * - * @param {string} str - Input string - * @return {number} Hashed string - */ - hash_(str) { - let hash = 0 - if (str.length === 0) return hash - for (let i = 0, len = str.length; i < len; i++) { - hash = ((hash << 5) - hash) + str.charCodeAt(i) - hash |= 0 // Convert to 32bit integer - } - return hash - } -} diff --git a/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js b/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js deleted file mode 100644 index 3dce25a66..000000000 --- a/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Abstract from "./Abstract" - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class GitHub extends Abstract { - - /** - * Retrieve repository information from GitHub - * - * @constructor - * - * @property {string} name_ - Name of the repository - * - * @param {(string|HTMLAnchorElement)} el - Selector or HTML element - */ - constructor(el) { - super(el) - - /* Extract user (and repository name) from URL, as we have to query for all - repositories, to omit 404 errors for private repositories */ - const matches = /^.+github\.com\/([^/]+)\/?([^/]+)?.*$/ - .exec(this.base_) - if (matches && matches.length === 3) { - const [, user, name] = matches - - /* Initialize base URL and repository name */ - this.base_ = `https://api.github.com/users/${user}/repos` - this.name_ = name - } - } - - /** - * Fetch relevant repository information from GitHub - * - * @return {Promise>} Promise returning an array of facts - */ - fetch_() { - const paginate = (page = 0) => { - return fetch(`${this.base_}?per_page=30&page=${page}`) - .then(response => response.json()) - .then(data => { - if (!(data instanceof Array)) - throw new TypeError - - /* Display number of stars and forks, if repository is given */ - if (this.name_) { - const repo = data.find(item => item.name === this.name_) - if (!repo && data.length === 30) - return paginate(page + 1) - - /* If we found a repo, extract the facts */ - return repo - ? [ - `${this.format_(repo.stargazers_count)} Stars`, - `${this.format_(repo.forks_count)} Forks` - ] - : [] - - /* Display number of repositories, otherwise */ - } else { - return [ - `${data.length} Repositories` - ] - } - }) - } - - /* Paginate through repos */ - return paginate() - } -} diff --git a/src/assets/javascripts/components/Material/Source/Repository.jsx b/src/assets/javascripts/components/Material/Source/Repository.jsx deleted file mode 100644 index ea4bd81fc..000000000 --- a/src/assets/javascripts/components/Material/Source/Repository.jsx +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Repository { - - /** - * Render repository information - * - * @constructor - * - * @property {HTMLElement} el_ - Repository information - * - * @param {(string|HTMLElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof HTMLElement)) - throw new ReferenceError - this.el_ = ref - } - - /** - * Initialize the repository - * - * @param {Array} facts - Facts to be rendered - */ - initialize(facts) { - if (facts.length && this.el_.children.length) - this.el_.children[this.el_.children.length - 1].appendChild( -
      - {facts.map(fact =>
    • {fact}
    • )} -
    - ) - - /* Finish rendering with animation */ - this.el_.dataset.mdState = "done" - } -} diff --git a/src/assets/javascripts/components/Material/Tabs.js b/src/assets/javascripts/components/Material/Tabs.js deleted file mode 100644 index 803ef0489..000000000 --- a/src/assets/javascripts/components/Material/Tabs.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import Toggle from "./Tabs/Toggle" - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -export default { - Toggle -} diff --git a/src/assets/javascripts/components/Material/Tabs/Toggle.js b/src/assets/javascripts/components/Material/Tabs/Toggle.js deleted file mode 100644 index 67d5f90eb..000000000 --- a/src/assets/javascripts/components/Material/Tabs/Toggle.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -export default class Toggle { - - /** - * Toggle tabs visibility depending on page y-offset - * - * @constructor - * - * @property {HTMLElement} el_ - Content container - * @property {number} height_ - Header height - * @property {number} offset_ - Toggle page-y offset - * @property {boolean} active_ - Tabs visibility - * - * @param {(string|HTMLElement)} el - Selector or HTML element - */ - constructor(el) { - const ref = (typeof el === "string") - ? document.querySelector(el) - : el - if (!(ref instanceof Node)) - throw new ReferenceError - this.el_ = ref - - /* Obtain header */ - const header = document.querySelector("[data-md-component=header]") - - /* Initialize height and state */ - this.height_ = header.offsetHeight - this.active_ = false - } - - /** - * Update visibility - */ - update() { - const active = window.pageYOffset >= - this.el_.children[0].offsetTop + (5 - this.height_) - if (active !== this.active_) - this.el_.dataset.mdState = (this.active_ = active) ? "hidden" : "" - } - - /** - * Reset visibility - */ - reset() { - this.el_.dataset.mdState = "" - this.active_ = false - } -} diff --git a/src/assets/javascripts/modernizr.js b/src/assets/javascripts/modernizr.js deleted file mode 100644 index 04c27d12f..000000000 --- a/src/assets/javascripts/modernizr.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "../../../.modernizr-autorc" diff --git a/src/assets/javascripts/providers/.babelrc b/src/assets/javascripts/providers/.babelrc deleted file mode 100644 index 658db6455..000000000 --- a/src/assets/javascripts/providers/.babelrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presets": [ - ["@babel/preset-env", { - "loose": true, - "targets": " > 1%, last 2 versions" - }] - ] -} diff --git a/src/assets/javascripts/providers/jsx.js b/src/assets/javascripts/providers/jsx.js deleted file mode 100644 index 8e229f67d..000000000 --- a/src/assets/javascripts/providers/jsx.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2016-2019 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Module - * ------------------------------------------------------------------------- */ - -/* eslint-disable no-underscore-dangle */ - -/** - * Create a native DOM node from JSX's intermediate representation - * - * @param {string} tag - Tag name - * @param {?Object} properties - Properties - * @param {Array>} - * children - Child nodes - * @return {HTMLElement} Native DOM node - */ -export function createElement(tag, properties, ...children) { - const el = document.createElement(tag) - - /* Set all properties */ - if (properties) - Array.prototype.forEach.call(Object.keys(properties), attr => { - el.setAttribute(attr, properties[attr]) - }) - - /* Iterate child nodes */ - const iterateChildNodes = nodes => { - Array.prototype.forEach.call(nodes, node => { - - /* Directly append text content */ - if (typeof node === "string" || - typeof node === "number") { - el.textContent += node - - /* Recurse, if we got an array */ - } else if (Array.isArray(node)) { - iterateChildNodes(node) - - /* Append raw HTML */ - } else if (typeof node.__html !== "undefined") { - el.innerHTML += node.__html - - /* Append regular nodes */ - } else if (node instanceof Node) { - el.appendChild(node) - } - }) - } - - /* Iterate child nodes and return element */ - iterateChildNodes(children) - return el -}