URI:
       doctools.js - sphere - GPU-based 3D discrete element method algorithm with optional fluid coupling
  HTML git clone git://src.adamsgaard.dk/sphere
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       doctools.js (4332B)
       ---
            1 /*
            2  * Base JavaScript utilities for all Sphinx HTML documentation.
            3  */
            4 "use strict";
            5 
            6 const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
            7   "TEXTAREA",
            8   "INPUT",
            9   "SELECT",
           10   "BUTTON",
           11 ]);
           12 
           13 const _ready = (callback) => {
           14   if (document.readyState !== "loading") {
           15     callback();
           16   } else {
           17     document.addEventListener("DOMContentLoaded", callback);
           18   }
           19 };
           20 
           21 /**
           22  * Small JavaScript module for the documentation.
           23  */
           24 const Documentation = {
           25   init: () => {
           26     Documentation.initDomainIndexTable();
           27     Documentation.initOnKeyListeners();
           28   },
           29 
           30   /**
           31    * i18n support
           32    */
           33   TRANSLATIONS: {},
           34   PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
           35   LOCALE: "unknown",
           36 
           37   // gettext and ngettext don't access this so that the functions
           38   // can safely bound to a different name (_ = Documentation.gettext)
           39   gettext: (string) => {
           40     const translated = Documentation.TRANSLATIONS[string];
           41     switch (typeof translated) {
           42       case "undefined":
           43         return string; // no translation
           44       case "string":
           45         return translated; // translation exists
           46       default:
           47         return translated[0]; // (singular, plural) translation tuple exists
           48     }
           49   },
           50 
           51   ngettext: (singular, plural, n) => {
           52     const translated = Documentation.TRANSLATIONS[singular];
           53     if (typeof translated !== "undefined")
           54       return translated[Documentation.PLURAL_EXPR(n)];
           55     return n === 1 ? singular : plural;
           56   },
           57 
           58   addTranslations: (catalog) => {
           59     Object.assign(Documentation.TRANSLATIONS, catalog.messages);
           60     Documentation.PLURAL_EXPR = new Function(
           61       "n",
           62       `return (${catalog.plural_expr})`,
           63     );
           64     Documentation.LOCALE = catalog.locale;
           65   },
           66 
           67   /**
           68    * helper function to focus on search bar
           69    */
           70   focusSearchBar: () => {
           71     document.querySelectorAll("input[name=q]")[0]?.focus();
           72   },
           73 
           74   /**
           75    * Initialise the domain index toggle buttons
           76    */
           77   initDomainIndexTable: () => {
           78     const toggler = (el) => {
           79       const idNumber = el.id.substr(7);
           80       const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
           81       if (el.src.substr(-9) === "minus.png") {
           82         el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
           83         toggledRows.forEach((el) => (el.style.display = "none"));
           84       } else {
           85         el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
           86         toggledRows.forEach((el) => (el.style.display = ""));
           87       }
           88     };
           89 
           90     const togglerElements = document.querySelectorAll("img.toggler");
           91     togglerElements.forEach((el) =>
           92       el.addEventListener("click", (event) => toggler(event.currentTarget)),
           93     );
           94     togglerElements.forEach((el) => (el.style.display = ""));
           95     if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
           96   },
           97 
           98   initOnKeyListeners: () => {
           99     // only install a listener if it is really needed
          100     if (
          101       !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS
          102       && !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
          103     )
          104       return;
          105 
          106     document.addEventListener("keydown", (event) => {
          107       // bail for input elements
          108       if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName))
          109         return;
          110       // bail with special keys
          111       if (event.altKey || event.ctrlKey || event.metaKey) return;
          112 
          113       if (!event.shiftKey) {
          114         switch (event.key) {
          115           case "ArrowLeft":
          116             if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
          117 
          118             const prevLink = document.querySelector('link[rel="prev"]');
          119             if (prevLink && prevLink.href) {
          120               window.location.href = prevLink.href;
          121               event.preventDefault();
          122             }
          123             break;
          124           case "ArrowRight":
          125             if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
          126 
          127             const nextLink = document.querySelector('link[rel="next"]');
          128             if (nextLink && nextLink.href) {
          129               window.location.href = nextLink.href;
          130               event.preventDefault();
          131             }
          132             break;
          133         }
          134       }
          135 
          136       // some keyboard layouts may need Shift to get /
          137       switch (event.key) {
          138         case "/":
          139           if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
          140           Documentation.focusSearchBar();
          141           event.preventDefault();
          142       }
          143     });
          144   },
          145 };
          146 
          147 // quick alias for translations
          148 const _ = Documentation.gettext;
          149 
          150 _ready(Documentation.init);