CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/main/_static/doctools.js
Views: 494
/*1* doctools.js2* ~~~~~~~~~~~3*4* Base JavaScript utilities for all Sphinx HTML documentation.5*6* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.7* :license: BSD, see LICENSE for details.8*9*/10"use strict";1112const _ready = (callback) => {13if (document.readyState !== "loading") {14callback();15} else {16document.addEventListener("DOMContentLoaded", callback);17}18};1920/**21* highlight a given string on a node by wrapping it in22* span elements with the given class name.23*/24const _highlight = (node, addItems, text, className) => {25if (node.nodeType === Node.TEXT_NODE) {26const val = node.nodeValue;27const parent = node.parentNode;28const pos = val.toLowerCase().indexOf(text);29if (30pos >= 0 &&31!parent.classList.contains(className) &&32!parent.classList.contains("nohighlight")33) {34let span;3536const closestNode = parent.closest("body, svg, foreignObject");37const isInSVG = closestNode && closestNode.matches("svg");38if (isInSVG) {39span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");40} else {41span = document.createElement("span");42span.classList.add(className);43}4445span.appendChild(document.createTextNode(val.substr(pos, text.length)));46parent.insertBefore(47span,48parent.insertBefore(49document.createTextNode(val.substr(pos + text.length)),50node.nextSibling51)52);53node.nodeValue = val.substr(0, pos);5455if (isInSVG) {56const rect = document.createElementNS(57"http://www.w3.org/2000/svg",58"rect"59);60const bbox = parent.getBBox();61rect.x.baseVal.value = bbox.x;62rect.y.baseVal.value = bbox.y;63rect.width.baseVal.value = bbox.width;64rect.height.baseVal.value = bbox.height;65rect.setAttribute("class", className);66addItems.push({ parent: parent, target: rect });67}68}69} else if (node.matches && !node.matches("button, select, textarea")) {70node.childNodes.forEach((el) => _highlight(el, addItems, text, className));71}72};73const _highlightText = (thisNode, text, className) => {74let addItems = [];75_highlight(thisNode, addItems, text, className);76addItems.forEach((obj) =>77obj.parent.insertAdjacentElement("beforebegin", obj.target)78);79};8081/**82* Small JavaScript module for the documentation.83*/84const Documentation = {85init: () => {86Documentation.highlightSearchWords();87Documentation.initDomainIndexTable();88Documentation.initOnKeyListeners();89},9091/**92* i18n support93*/94TRANSLATIONS: {},95PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),96LOCALE: "unknown",9798// gettext and ngettext don't access this so that the functions99// can safely bound to a different name (_ = Documentation.gettext)100gettext: (string) => {101const translated = Documentation.TRANSLATIONS[string];102switch (typeof translated) {103case "undefined":104return string; // no translation105case "string":106return translated; // translation exists107default:108return translated[0]; // (singular, plural) translation tuple exists109}110},111112ngettext: (singular, plural, n) => {113const translated = Documentation.TRANSLATIONS[singular];114if (typeof translated !== "undefined")115return translated[Documentation.PLURAL_EXPR(n)];116return n === 1 ? singular : plural;117},118119addTranslations: (catalog) => {120Object.assign(Documentation.TRANSLATIONS, catalog.messages);121Documentation.PLURAL_EXPR = new Function(122"n",123`return (${catalog.plural_expr})`124);125Documentation.LOCALE = catalog.locale;126},127128/**129* highlight the search words provided in the url in the text130*/131highlightSearchWords: () => {132const highlight =133new URLSearchParams(window.location.search).get("highlight") || "";134const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);135if (terms.length === 0) return; // nothing to do136137// There should never be more than one element matching "div.body"138const divBody = document.querySelectorAll("div.body");139const body = divBody.length ? divBody[0] : document.querySelector("body");140window.setTimeout(() => {141terms.forEach((term) => _highlightText(body, term, "highlighted"));142}, 10);143144const searchBox = document.getElementById("searchbox");145if (searchBox === null) return;146searchBox.appendChild(147document148.createRange()149.createContextualFragment(150'<p class="highlight-link">' +151'<a href="javascript:Documentation.hideSearchWords()">' +152Documentation.gettext("Hide Search Matches") +153"</a></p>"154)155);156},157158/**159* helper function to hide the search marks again160*/161hideSearchWords: () => {162document163.querySelectorAll("#searchbox .highlight-link")164.forEach((el) => el.remove());165document166.querySelectorAll("span.highlighted")167.forEach((el) => el.classList.remove("highlighted"));168const url = new URL(window.location);169url.searchParams.delete("highlight");170window.history.replaceState({}, "", url);171},172173/**174* helper function to focus on search bar175*/176focusSearchBar: () => {177document.querySelectorAll("input[name=q]")[0]?.focus();178},179180/**181* Initialise the domain index toggle buttons182*/183initDomainIndexTable: () => {184const toggler = (el) => {185const idNumber = el.id.substr(7);186const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);187if (el.src.substr(-9) === "minus.png") {188el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;189toggledRows.forEach((el) => (el.style.display = "none"));190} else {191el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;192toggledRows.forEach((el) => (el.style.display = ""));193}194};195196const togglerElements = document.querySelectorAll("img.toggler");197togglerElements.forEach((el) =>198el.addEventListener("click", (event) => toggler(event.currentTarget))199);200togglerElements.forEach((el) => (el.style.display = ""));201if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);202},203204initOnKeyListeners: () => {205// only install a listener if it is really needed206if (207!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&208!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS209)210return;211212const blacklistedElements = new Set([213"TEXTAREA",214"INPUT",215"SELECT",216"BUTTON",217]);218document.addEventListener("keydown", (event) => {219if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements220if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys221222if (!event.shiftKey) {223switch (event.key) {224case "ArrowLeft":225if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;226227const prevLink = document.querySelector('link[rel="prev"]');228if (prevLink && prevLink.href) {229window.location.href = prevLink.href;230event.preventDefault();231}232break;233case "ArrowRight":234if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;235236const nextLink = document.querySelector('link[rel="next"]');237if (nextLink && nextLink.href) {238window.location.href = nextLink.href;239event.preventDefault();240}241break;242case "Escape":243if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;244Documentation.hideSearchWords();245event.preventDefault();246}247}248249// some keyboard layouts may need Shift to get /250switch (event.key) {251case "/":252if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;253Documentation.focusSearchBar();254event.preventDefault();255}256});257},258};259260// quick alias for translations261const _ = Documentation.gettext;262263_ready(Documentation.init);264265266