/* frame.js: the first script in every frame document the gallery renders, and no part of the design system. Three jobs, all done before the document's own scripts run. The scheme. A frame does not inherit its parent's colour scheme, and the gallery's reader may have chosen Light or Dark before this frame loaded. The parent is same-origin, so its is readable: whatever data-theme it carries is copied here before the first paint, and gallery.js writes it again on every change after. Opened on its own, outside a frame, there is no parent: a shell demo or the demo application in a tab of its own, or a document a reader followed a link into. Every frame document says data-rst-scheme-store="local", so fiesta.js would restore the stored choice, but fiesta.js is deferred here and restores only when it is in the head without defer; after the first paint is too late. So the restore is this script's: localStorage["fiesta-scheme"] is read at parse time and data-theme set for light or dark, and on pageshow from the back/forward cache storage is read again and the attribute set or removed. fiesta.js skips its own restore, the marking of the scheme menu included, when the root already carries data-theme, so once the body is parsed, and again after a cache restore, every [rst-scheme] copy the document holds is marked here: aria-current on the stored scheme's button, on System when nothing is stored, the same marking fiesta.js does. Framed, the parent's scheme is the one truth and nothing is read from storage. Submits. Every href in a frame's body is "#", so a click goes nowhere; a form would still request its action, "#" included, which is the page again with its fields in the query. Cancelling every submit at the window, in the capture phase, stops the request before any other listener runs, and runs them all the same: fiesta.js's scheme switch sees its submit in its own capture listener on the document and applies the scheme as usual. Autofocus. The page around a same-origin frame grants its autofocus: a sign-in field would take the reader's focus as its lazy frame loaded, and the gallery would scroll down to it. A browser grants autofocus early in a rendering update, to the first field that asked and can take focus, and runs animation frame callbacks after. So in a frame each field that asks is inert from the parser's insertion (a microtask, before any update) to the first animation frame after load, and its request is refused. Removing the attribute does not work (the request is made on insertion), nor does hiding or inerting the frame (Chromium focuses inside it anyway; measured, in the gallery this came from). Opened in a tab of its own, the document keeps its autofocus. */ (function () { "use strict"; var root = document.documentElement, KEY = "fiesta-scheme", SCHEME = "[rst-scheme],.rst-scheme"; var host = null; try { host = window.frameElement; } catch (e) { /* framed by another origin, whose page is not the gallery's */ } function stored() { var s = null; try { s = localStorage.getItem(KEY); } catch (e) { /* storage off: nothing is stored */ } return s === "light" || s === "dark" ? s : "system"; } function apply(s) { if (s === "system") root.removeAttribute("data-theme"); else root.setAttribute("data-theme", s); } // Not toggleAttribute: aria-current="" reads as false. function mark(s) { var menus = document.querySelectorAll(SCHEME); for (var m = 0; m < menus.length; m++) { var buttons = menus[m].querySelectorAll("button"); for (var i = 0; i < buttons.length; i++) { var f = buttons[i].form, v = f && f.elements.scheme && f.elements.scheme.value; if (v === s) buttons[i].setAttribute("aria-current", "true"); else buttons[i].removeAttribute("aria-current"); } } } function ready(fn) { if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", fn); else fn(); } if (host) { var parent = host.ownerDocument.documentElement, s = parent.getAttribute("data-theme"); if (s === "light" || s === "dark") root.setAttribute("data-theme", s); else root.removeAttribute("data-theme"); } else if (!root.hasAttribute("data-theme")) { var kept = stored(); if (kept !== "system") apply(kept); ready(function () { mark(kept); }); addEventListener("pageshow", function (event) { if (!event.persisted) return; var now = stored(); apply(now); mark(now); }); } addEventListener("submit", function (event) { event.preventDefault(); }, true); if (host && host.classList.contains("ds-view__frame")) { var asked = []; var hold = function (el) { if (el.hasAttribute("autofocus") && !el.inert) { el.inert = true; asked.push(el); } }; var inserted = new MutationObserver(function (records) { for (var r = 0; r < records.length; r++) { var added = records[r].addedNodes; for (var n = 0; n < added.length; n++) { if (added[n].nodeType !== 1) continue; hold(added[n]); var inner = added[n].querySelectorAll("[autofocus]"); for (var i = 0; i < inner.length; i++) hold(inner[i]); } } }); inserted.observe(document.documentElement, { childList: true, subtree: true }); addEventListener("load", function () { inserted.disconnect(); requestAnimationFrame(function () { for (var i = 0; i < asked.length; i++) asked[i].inert = false; }); }); } })();