| // SPDX-FileCopyrightText: 2021 GNOME Foundation |
| // |
| // SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later |
| "use strict"; |
| |
| |
| const urlMap = new Map(typeof baseURLs !== 'undefined' ? baseURLs : []); |
| |
| window.addEventListener("hashchange", onDidHashChange); |
| window.addEventListener("load", onDidLoad, false); |
| window.addEventListener("keydown", onKeyDown); |
| |
| function onDidLoad() { |
| attachScrollHandlers() |
| attachToggleHandlers() |
| attachCopyHandlers() |
| |
| if (window.onInitSearch) { |
| window.onInitSearch() |
| } |
| } |
| |
| function onDidHashChange() { |
| // When URL fragment changes to ID of a collapsible section, |
| // expand it when it is collapsed. |
| // This is useful for clicking section links in the sidebar on the index page. |
| const sectionHeader = document.querySelector(".section-header" + location.hash); |
| if (sectionHeader !== null) { |
| const parent = sectionHeader.parentNode; |
| if (hasClass(parent, "toggle-wrapper")) { |
| const toggle = parent.querySelector(".collapse-toggle"); |
| if (hasClass(toggle, "collapsed")) { |
| toggle.click(); |
| } |
| } |
| } |
| } |
| |
| |
| function attachScrollHandlers() { |
| const btnToTop = document.getElementById("btn-to-top"); |
| |
| btnToTop.addEventListener('click', onClick); |
| window.addEventListener('scroll', onScroll); |
| |
| function onClick(e) { |
| e.preventDefault(); |
| window.scroll({ top: 0, behavior: 'smooth' }); |
| } |
| |
| function onScroll() { |
| if (window.scrollY < 400) { |
| addClass(btnToTop, "hidden"); |
| } else { |
| removeClass(btnToTop, "hidden"); |
| } |
| } |
| } |
| |
| function attachToggleHandlers() { |
| function label(isCollapsed) { |
| return ( |
| "[<span class=\"inner\">" + |
| (isCollapsed ? "+" : "\u2212") + |
| "</span>]" |
| ) |
| } |
| |
| function createToggle(isCollapsed) { |
| const toggle = document.createElement("a"); |
| toggle.href = "javascript:void(0)"; |
| toggle.className = "collapse-toggle"; |
| toggle.innerHTML = label(isCollapsed); |
| toggle.addEventListener('click', onClickToggle); |
| return toggle; |
| } |
| |
| function onClickToggle() { |
| if (hasClass(this, "collapsed")) { |
| removeClass(this, "collapsed"); |
| this.innerHTML = label(false); |
| forEach(this.parentNode.querySelectorAll(".docblock"), function(e) { |
| removeClass(e, "hidden"); |
| }); |
| } else { |
| addClass(this, "collapsed"); |
| this.innerHTML = label(true); |
| forEach(this.parentNode.querySelectorAll(".docblock"), function(e) { |
| addClass(e, "hidden"); |
| }); |
| } |
| } |
| |
| forEach(document.querySelectorAll(".toggle-wrapper"), function(e) { |
| const sectionHeader = e.querySelector(".section-header"); |
| const fragmentMatches = sectionHeader !== null && location.hash === "#" + sectionHeader.getAttribute('id'); |
| const collapsedByDefault = hasClass(e, "default-hide") && !fragmentMatches; |
| const toggle = createToggle(collapsedByDefault); |
| e.insertBefore(toggle, e.firstChild); |
| if (collapsedByDefault) { |
| addClass(toggle, "collapsed"); |
| forEach(e.querySelectorAll(".docblock"), function(d) { |
| addClass(d, "hidden"); |
| }); |
| } |
| }); |
| |
| function resolveNamespaceLink(namespace) { |
| return urlMap.get(namespace); |
| } |
| |
| forEach(document.querySelectorAll(".external"), function(e) { |
| if (e.tagName == "A" && e.dataset.hasOwnProperty('namespace')) { |
| var data_namespace = e.dataset.namespace |
| var data_link = e.dataset.link |
| var base_url = resolveNamespaceLink(data_namespace) |
| if (base_url !== undefined) { |
| e.href = base_url + data_link; |
| } else { |
| e.title = "No reference to the " + data_namespace + " namespace"; |
| } |
| } |
| }) |
| } |
| |
| function attachCopyHandlers() { |
| if (!navigator.clipboard) |
| return; |
| |
| forEach(document.querySelectorAll(".codehilite"), function(e) { |
| const button = document.createElement("button"); |
| button.className = "copy-button"; |
| button.innerText = "Copy"; |
| button.title = "Copy code to clipboard"; |
| |
| const text = e.innerText; |
| button.addEventListener("click", () => { |
| navigator.clipboard.writeText(text); |
| }); |
| |
| e.appendChild(button); |
| }) |
| } |
| |
| function onKeyDown(event) { |
| let search_input = document.querySelector("#search-input"); |
| // We don't want to try to focus the search input if it isn't visible. That way |
| // we avoid the preventDefault(), hence allowing devhelp to use S as mnemonic. |
| let potentially_hidden_parent = search_input.closest('.hidden, .devhelp-hidden'); |
| |
| if (window.getComputedStyle(potentially_hidden_parent).display !== 'none' && |
| event.code === "KeyS" && document.activeElement !== search_input) { |
| event.preventDefault(); |
| search_input.focus(); |
| } |
| } |
| |
| // Helpers |
| |
| function hasClass(elem, className) { |
| return elem && elem.classList && elem.classList.contains(className); |
| } |
| |
| function addClass(elem, className) { |
| return elem && elem.classList && elem.classList.add(className); |
| } |
| |
| function removeClass(elem, className) { |
| return elem && elem.classList && elem.classList.remove(className); |
| } |
| |
| function forEach(arr, func) { |
| for (let i = 0; i < arr.length; ++i) { |
| func(arr[i]) |
| } |
| } |