diff options
Diffstat (limited to '')
-rw-r--r-- | src/librustdoc/html/static/js/main.js | 325 | ||||
-rw-r--r-- | src/librustdoc/html/static/js/scrape-examples.js | 2 | ||||
-rw-r--r-- | src/librustdoc/html/static/js/search.js | 31 | ||||
-rw-r--r-- | src/librustdoc/html/static/js/settings.js | 11 | ||||
-rw-r--r-- | src/librustdoc/html/static/js/source-script.js | 23 | ||||
-rw-r--r-- | src/librustdoc/html/static/js/storage.js | 4 |
6 files changed, 236 insertions, 160 deletions
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 0702b2b0b..33480fa41 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -55,7 +55,7 @@ function blurHandler(event, parentElem, hideCallback) { function setMobileTopbar() { // FIXME: It would be nicer to generate this text content directly in HTML, // but with the current code it's hard to get the right information in the right place. - const mobileLocationTitle = document.querySelector(".mobile-topbar h2.location"); + const mobileLocationTitle = document.querySelector(".mobile-topbar h2"); const locationTitle = document.querySelector(".sidebar h2.location"); if (mobileLocationTitle && locationTitle) { mobileLocationTitle.innerHTML = locationTitle.innerHTML; @@ -192,6 +192,8 @@ function loadCss(cssFileName) { } (function() { + const isHelpPage = window.location.pathname.endsWith("/help.html"); + function loadScript(url) { const script = document.createElement("script"); script.src = url; @@ -199,6 +201,9 @@ function loadCss(cssFileName) { } getSettingsButton().onclick = event => { + if (event.ctrlKey || event.altKey || event.metaKey) { + return; + } addClass(getSettingsButton(), "rotate"); event.preventDefault(); // Sending request for the CSS and the JS files at the same time so it will @@ -348,8 +353,7 @@ function loadCss(cssFileName) { function onHashChange(ev) { // If we're in mobile mode, we should hide the sidebar in any case. - const sidebar = document.getElementsByClassName("sidebar")[0]; - removeClass(sidebar, "shown"); + hideSidebar(); handleHashes(ev); } @@ -405,9 +409,12 @@ function loadCss(cssFileName) { break; case "+": + ev.preventDefault(); + expandAllDocs(); + break; case "-": ev.preventDefault(); - toggleAllDocs(); + collapseAllDocs(); break; case "?": @@ -443,18 +450,15 @@ function loadCss(cssFileName) { return; } - const div = document.createElement("div"); - div.className = "block " + shortty; const h3 = document.createElement("h3"); h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`; - div.appendChild(h3); const ul = document.createElement("ul"); + ul.className = "block " + shortty; for (const item of filtered) { const name = item[0]; const desc = item[1]; // can be null - let klass = shortty; let path; if (shortty === "mod") { path = name + "/index.html"; @@ -462,20 +466,19 @@ function loadCss(cssFileName) { path = shortty + "." + name + ".html"; } const current_page = document.location.href.split("/").pop(); - if (path === current_page) { - klass += " current"; - } const link = document.createElement("a"); link.href = path; link.title = desc; - link.className = klass; + if (path === current_page) { + link.className = "current"; + } link.textContent = name; const li = document.createElement("li"); li.appendChild(link); ul.appendChild(li); } - div.appendChild(ul); - sidebar.appendChild(div); + sidebar.appendChild(h3); + sidebar.appendChild(ul); } if (sidebar) { @@ -501,6 +504,10 @@ function loadCss(cssFileName) { const synthetic_implementors = document.getElementById("synthetic-implementors-list"); const inlined_types = new Set(); + const TEXT_IDX = 0; + const SYNTHETIC_IDX = 1; + const TYPES_IDX = 2; + if (synthetic_implementors) { // This `inlined_types` variable is used to avoid having the same implementation // showing up twice. For example "String" in the "Sync" doc page. @@ -519,15 +526,15 @@ function loadCss(cssFileName) { } let currentNbImpls = implementors.getElementsByClassName("impl").length; - const traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent; + const traitName = document.querySelector("h1.fqn > .trait").textContent; const baseIdName = "impl-" + traitName + "-"; const libs = Object.getOwnPropertyNames(imp); // We don't want to include impls from this JS file, when the HTML already has them. // The current crate should always be ignored. Other crates that should also be // ignored are included in the attribute `data-ignore-extern-crates`. - const ignoreExternCrates = document - .querySelector("script[data-ignore-extern-crates]") - .getAttribute("data-ignore-extern-crates"); + const script = document + .querySelector("script[data-ignore-extern-crates]"); + const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; for (const lib of libs) { if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { continue; @@ -536,10 +543,12 @@ function loadCss(cssFileName) { struct_loop: for (const struct of structs) { - const list = struct.synthetic ? synthetic_implementors : implementors; + const list = struct[SYNTHETIC_IDX] ? synthetic_implementors : implementors; - if (struct.synthetic) { - for (const struct_type of struct.types) { + // The types list is only used for synthetic impls. + // If this changes, `main.js` and `write_shared.rs` both need changed. + if (struct[SYNTHETIC_IDX]) { + for (const struct_type of struct[TYPES_IDX]) { if (inlined_types.has(struct_type)) { continue struct_loop; } @@ -548,9 +557,8 @@ function loadCss(cssFileName) { } const code = document.createElement("h3"); - code.innerHTML = struct.text; + code.innerHTML = struct[TEXT_IDX]; addClass(code, "code-header"); - addClass(code, "in-band"); onEachLazy(code.getElementsByTagName("a"), elem => { const href = elem.getAttribute("href"); @@ -588,38 +596,52 @@ function loadCss(cssFileName) { return; } // Draw a convenient sidebar of known crates if we have a listing - const div = document.createElement("div"); - div.className = "block crate"; - div.innerHTML = "<h3>Crates</h3>"; + const h3 = document.createElement("h3"); + h3.innerHTML = "Crates"; const ul = document.createElement("ul"); - div.appendChild(ul); + ul.className = "block crate"; for (const crate of window.ALL_CRATES) { - let klass = "crate"; - if (window.rootPath !== "./" && crate === window.currentCrate) { - klass += " current"; - } const link = document.createElement("a"); link.href = window.rootPath + crate + "/index.html"; - link.className = klass; + if (window.rootPath !== "./" && crate === window.currentCrate) { + link.className = "current"; + } link.textContent = crate; const li = document.createElement("li"); li.appendChild(link); ul.appendChild(li); } - sidebarElems.appendChild(div); + sidebarElems.appendChild(h3); + sidebarElems.appendChild(ul); } + function expandAllDocs() { + const innerToggle = document.getElementById(toggleAllDocsId); + removeClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { + if (!hasClass(e, "type-contents-toggle")) { + e.open = true; + } + }); + innerToggle.title = "collapse all docs"; + innerToggle.children[0].innerText = "\u2212"; // "\u2212" is "−" minus sign + } - function labelForToggleButton(sectionIsCollapsed) { - if (sectionIsCollapsed) { - // button will expand the section - return "+"; - } - // button will collapse the section - // note that this text is also set in the HTML template in ../render/mod.rs - return "\u2212"; // "\u2212" is "−" minus sign + function collapseAllDocs() { + const innerToggle = document.getElementById(toggleAllDocsId); + addClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { + if (e.parentNode.id !== "implementations-list" || + (!hasClass(e, "implementors-toggle") && + !hasClass(e, "type-contents-toggle")) + ) { + e.open = false; + } + }); + innerToggle.title = "expand all docs"; + innerToggle.children[0].innerText = "+"; } function toggleAllDocs() { @@ -627,29 +649,11 @@ function loadCss(cssFileName) { if (!innerToggle) { return; } - let sectionIsCollapsed = false; if (hasClass(innerToggle, "will-expand")) { - removeClass(innerToggle, "will-expand"); - onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { - if (!hasClass(e, "type-contents-toggle")) { - e.open = true; - } - }); - innerToggle.title = "collapse all docs"; + expandAllDocs(); } else { - addClass(innerToggle, "will-expand"); - onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => { - if (e.parentNode.id !== "implementations-list" || - (!hasClass(e, "implementors-toggle") && - !hasClass(e, "type-contents-toggle")) - ) { - e.open = false; - } - }); - sectionIsCollapsed = true; - innerToggle.title = "expand all docs"; + collapseAllDocs(); } - innerToggle.children[0].innerText = labelForToggleButton(sectionIsCollapsed); } (function() { @@ -692,47 +696,102 @@ function loadCss(cssFileName) { } }()); + window.rustdoc_add_line_numbers_to_examples = () => { + onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => { + const parent = x.parentNode; + const line_numbers = parent.querySelectorAll(".example-line-numbers"); + if (line_numbers.length > 0) { + return; + } + const count = x.textContent.split("\n").length; + const elems = []; + for (let i = 0; i < count; ++i) { + elems.push(i + 1); + } + const node = document.createElement("pre"); + addClass(node, "example-line-numbers"); + node.innerHTML = elems.join("\n"); + parent.insertBefore(node, x); + }); + }; + + window.rustdoc_remove_line_numbers_from_examples = () => { + onEachLazy(document.getElementsByClassName("rust-example-rendered"), x => { + const parent = x.parentNode; + const line_numbers = parent.querySelectorAll(".example-line-numbers"); + for (const node of line_numbers) { + parent.removeChild(node); + } + }); + }; + (function() { // To avoid checking on "rustdoc-line-numbers" value on every loop... - let lineNumbersFunc = () => {}; if (getSettingValue("line-numbers") === "true") { - lineNumbersFunc = x => { - const count = x.textContent.split("\n").length; - const elems = []; - for (let i = 0; i < count; ++i) { - elems.push(i + 1); - } - const node = document.createElement("pre"); - addClass(node, "line-number"); - node.innerHTML = elems.join("\n"); - x.parentNode.insertBefore(node, x); - }; + window.rustdoc_add_line_numbers_to_examples(); } - onEachLazy(document.getElementsByClassName("rust-example-rendered"), e => { - if (hasClass(e, "compile_fail")) { - e.addEventListener("mouseover", function() { - this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00"; - }); - e.addEventListener("mouseout", function() { - this.parentElement.previousElementSibling.childNodes[0].style.color = ""; - }); - } else if (hasClass(e, "ignore")) { - e.addEventListener("mouseover", function() { - this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200"; - }); - e.addEventListener("mouseout", function() { - this.parentElement.previousElementSibling.childNodes[0].style.color = ""; - }); - } - lineNumbersFunc(e); - }); }()); + let oldSidebarScrollPosition = null; + + // Scroll locking used both here and in source-script.js + + window.rustdocMobileScrollLock = function() { + const mobile_topbar = document.querySelector(".mobile-topbar"); + if (window.innerWidth <= window.RUSTDOC_MOBILE_BREAKPOINT) { + // This is to keep the scroll position on mobile. + oldSidebarScrollPosition = window.scrollY; + document.body.style.width = `${document.body.offsetWidth}px`; + document.body.style.position = "fixed"; + document.body.style.top = `-${oldSidebarScrollPosition}px`; + if (mobile_topbar) { + mobile_topbar.style.top = `${oldSidebarScrollPosition}px`; + mobile_topbar.style.position = "relative"; + } + } else { + oldSidebarScrollPosition = null; + } + }; + + window.rustdocMobileScrollUnlock = function() { + const mobile_topbar = document.querySelector(".mobile-topbar"); + if (oldSidebarScrollPosition !== null) { + // This is to keep the scroll position on mobile. + document.body.style.width = ""; + document.body.style.position = ""; + document.body.style.top = ""; + if (mobile_topbar) { + mobile_topbar.style.top = ""; + mobile_topbar.style.position = ""; + } + // The scroll position is lost when resetting the style, hence why we store it in + // `oldSidebarScrollPosition`. + window.scrollTo(0, oldSidebarScrollPosition); + oldSidebarScrollPosition = null; + } + }; + + function showSidebar() { + window.rustdocMobileScrollLock(); + const sidebar = document.getElementsByClassName("sidebar")[0]; + addClass(sidebar, "shown"); + } + function hideSidebar() { + window.rustdocMobileScrollUnlock(); const sidebar = document.getElementsByClassName("sidebar")[0]; removeClass(sidebar, "shown"); } + window.addEventListener("resize", () => { + if (window.innerWidth > window.RUSTDOC_MOBILE_BREAKPOINT && + oldSidebarScrollPosition !== null) { + // If the user opens the sidebar in "mobile" mode, and then grows the browser window, + // we need to switch away from mobile mode and make the main content area scrollable. + hideSidebar(); + } + }); + function handleClick(id, f) { const elem = document.getElementById(id); if (elem) { @@ -775,9 +834,9 @@ function loadCss(cssFileName) { sidebar_menu_toggle.addEventListener("click", () => { const sidebar = document.getElementsByClassName("sidebar")[0]; if (!hasClass(sidebar, "shown")) { - addClass(sidebar, "shown"); + showSidebar(); } else { - removeClass(sidebar, "shown"); + hideSidebar(); } }); } @@ -834,7 +893,10 @@ function loadCss(cssFileName) { rustdoc_version.appendChild(rustdoc_version_code); const container = document.createElement("div"); - container.className = "popover"; + if (!isHelpPage) { + container.className = "popover"; + } + container.id = "help"; container.style.display = "none"; const side_by_side = document.createElement("div"); @@ -846,15 +908,22 @@ function loadCss(cssFileName) { container.appendChild(side_by_side); container.appendChild(rustdoc_version); - const help_button = getHelpButton(); - help_button.appendChild(container); + if (isHelpPage) { + const help_section = document.createElement("section"); + help_section.appendChild(container); + document.getElementById("main-content").appendChild(help_section); + container.style.display = "block"; + } else { + const help_button = getHelpButton(); + help_button.appendChild(container); - container.onblur = helpBlurHandler; - container.onclick = event => { - event.preventDefault(); - }; - help_button.onblur = helpBlurHandler; - help_button.children[0].onblur = helpBlurHandler; + container.onblur = helpBlurHandler; + container.onclick = event => { + event.preventDefault(); + }; + help_button.onblur = helpBlurHandler; + help_button.children[0].onblur = helpBlurHandler; + } return container; } @@ -863,7 +932,7 @@ function loadCss(cssFileName) { * Hide all the popover menus. */ window.hidePopoverMenus = function() { - onEachLazy(document.querySelectorAll(".search-container .popover"), elem => { + onEachLazy(document.querySelectorAll(".search-form .popover"), elem => { elem.style.display = "none"; }); }; @@ -895,19 +964,43 @@ function loadCss(cssFileName) { } } - document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => { - const target = event.target; - if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) { - return; - } - const menu = getHelpMenu(true); - const shouldShowHelp = menu.style.display === "none"; - if (shouldShowHelp) { - showHelp(); - } else { - window.hidePopoverMenus(); - } - }); + if (isHelpPage) { + showHelp(); + document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { + // Already on the help page, make help button a no-op. + const target = event.target; + if (target.tagName !== "A" || + target.parentElement.id !== HELP_BUTTON_ID || + event.ctrlKey || + event.altKey || + event.metaKey) { + return; + } + event.preventDefault(); + }); + } else { + document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click", event => { + // By default, have help button open docs in a popover. + // If user clicks with a moderator, though, use default browser behavior, + // probably opening in a new window or tab. + const target = event.target; + if (target.tagName !== "A" || + target.parentElement.id !== HELP_BUTTON_ID || + event.ctrlKey || + event.altKey || + event.metaKey) { + return; + } + event.preventDefault(); + const menu = getHelpMenu(true); + const shouldShowHelp = menu.style.display === "none"; + if (shouldShowHelp) { + showHelp(); + } else { + window.hidePopoverMenus(); + } + }); + } setMobileTopbar(); addSidebarItems(); diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index fd7a14497..d0fd115fd 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -8,7 +8,7 @@ // Scroll code block to the given code location function scrollToLoc(elt, loc) { - const lines = elt.querySelector(".line-numbers"); + const lines = elt.querySelector(".src-line-numbers"); let scrollOffset; // If the block is greater than the size of the viewer, diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 75c7bd45a..d04ec357c 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -429,9 +429,9 @@ function initSearch(rawSearchIndex) { } const posBefore = parserState.pos; getNextElem(query, parserState, elems, endChar === ">"); - // This case can be encountered if `getNextElem` encounted a "stop character" right from - // the start. For example if you have `,,` or `<>`. In this case, we simply move up the - // current position to continue the parsing. + // This case can be encountered if `getNextElem` encountered a "stop character" right + // from the start. For example if you have `,,` or `<>`. In this case, we simply move up + // the current position to continue the parsing. if (posBefore === parserState.pos) { parserState.pos += 1; } @@ -581,7 +581,7 @@ function initSearch(rawSearchIndex) { const elem = document.getElementById("crate-search"); if (elem && - elem.value !== "All crates" && + elem.value !== "all crates" && hasOwnPropertyRustdoc(rawSearchIndex, elem.value) ) { return elem.value; @@ -1551,12 +1551,6 @@ function initSearch(rawSearchIndex) { return [displayPath, href]; } - function escape(content) { - const h1 = document.createElement("h1"); - h1.textContent = content; - return h1.innerHTML; - } - function pathSplitter(path) { const tmp = "<span>" + path.replace(/::/g, "::</span><span>"); if (tmp.endsWith("<span>")) { @@ -1710,22 +1704,15 @@ function initSearch(rawSearchIndex) { let crates = ""; const crates_list = Object.keys(rawSearchIndex); if (crates_list.length > 1) { - crates = " in <select id=\"crate-search\"><option value=\"All crates\">" + - "All crates</option>"; + crates = " in <div id=\"crate-search-div\"><select id=\"crate-search\">" + + "<option value=\"all crates\">all crates</option>"; for (const c of crates_list) { crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`; } - crates += "</select>"; - } - - let typeFilter = ""; - if (results.query.typeFilter !== NO_TYPE_FILTER) { - typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")"; + crates += "</select></div>"; } - let output = "<div id=\"search-settings\">" + - `<h1 class="search-results-title">Results for ${escape(results.query.userQuery)}` + - `${typeFilter}</h1>${crates}</div>`; + let output = `<h1 class="search-results-title">Results${crates}</h1>`; if (results.query.error !== null) { output += `<h3>Query parser error: "${results.query.error}".</h3>`; output += "<div id=\"titles\">" + @@ -2245,7 +2232,7 @@ function initSearch(rawSearchIndex) { } function updateCrate(ev) { - if (ev.target.value === "All crates") { + if (ev.target.value === "all crates") { // If we don't remove it from the URL, it'll be picked up again by the search. const params = searchState.getQueryStringParams(); const query = searchState.input.value.trim(); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 797b931af..5e1c7e6f0 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -19,6 +19,13 @@ updateSystemTheme(); updateLightAndDark(); break; + case "line-numbers": + if (value === true) { + window.rustdoc_add_line_numbers_to_examples(); + } else { + window.rustdoc_remove_line_numbers_from_examples(); + } + break; } } @@ -209,7 +216,9 @@ const innerHTML = `<div class="settings">${buildSettingsPageSections(settings)}</div>`; const el = document.createElement(elementKind); el.id = "settings"; - el.className = "popover"; + if (!isSettingsPage) { + el.className = "popover"; + } el.innerHTML = innerHTML; if (isSettingsPage) { diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index c45d61429..0b9368dd8 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -10,7 +10,6 @@ (function() { const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; -let oldScrollPosition = 0; const NAME_OFFSET = 0; const DIRS_OFFSET = 1; @@ -70,24 +69,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { function toggleSidebar() { const child = this.parentNode.children[0]; if (child.innerText === ">") { - if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) { - // This is to keep the scroll position on mobile. - oldScrollPosition = window.scrollY; - document.body.style.position = "fixed"; - document.body.style.top = `-${oldScrollPosition}px`; - } + window.rustdocMobileScrollLock(); addClass(document.documentElement, "source-sidebar-expanded"); child.innerText = "<"; updateLocalStorage("source-sidebar-show", "true"); } else { - if (window.innerWidth < window.RUSTDOC_MOBILE_BREAKPOINT) { - // This is to keep the scroll position on mobile. - document.body.style.position = ""; - document.body.style.top = ""; - // The scroll position is lost when resetting the style, hence why we store it in - // `oldScroll`. - window.scrollTo(0, oldScrollPosition); - } + window.rustdocMobileScrollUnlock(); removeClass(document.documentElement, "source-sidebar-expanded"); child.innerText = ">"; updateLocalStorage("source-sidebar-show", "false"); @@ -111,7 +98,7 @@ function createSidebarToggle() { return sidebarToggle; } -// This function is called from "source-files.js", generated in `html/render/mod.rs`. +// This function is called from "source-files.js", generated in `html/render/write_shared.rs`. // eslint-disable-next-line no-unused-vars function createSourceSidebar() { const container = document.querySelector("nav.sidebar"); @@ -169,7 +156,7 @@ function highlightSourceLines(match) { if (x) { x.scrollIntoView(); } - onEachLazy(document.getElementsByClassName("line-numbers"), e => { + onEachLazy(document.getElementsByClassName("src-line-numbers"), e => { onEachLazy(e.getElementsByTagName("span"), i_e => { removeClass(i_e, "line-highlighted"); }); @@ -231,7 +218,7 @@ window.addEventListener("hashchange", () => { } }); -onEachLazy(document.getElementsByClassName("line-numbers"), el => { +onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { el.addEventListener("click", handleSourceHighlight); }); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 0c5389d45..b462a2c50 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -10,9 +10,9 @@ window.currentTheme = document.getElementById("themeStyle"); window.mainTheme = document.getElementById("mainThemeStyle"); // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY -// If you update this line, then you also need to update the two media queries with the same +// If you update this line, then you also need to update the media query with the same // warning in rustdoc.css -window.RUSTDOC_MOBILE_BREAKPOINT = 701; +window.RUSTDOC_MOBILE_BREAKPOINT = 700; const settingsDataset = (function() { const settingsElement = document.getElementById("default-settings"); |