1(function () { 2 "use strict"; 3 4 const synchronizers = new WeakMap(); 5 6 function readableName(checkbox) { 7 const label = checkbox.labels && checkbox.labels[0]; 8 const row = checkbox.closest("tr"); 9 const rowHeading = row && row.querySelector("td, th"); 10 const followingText = checkbox.nextSibling && checkbox.nextSibling.nodeType === Node.TEXT_NODE && checkbox.nextSibling.textContent.trim(); 11 return (label && label.textContent || 12 rowHeading && rowHeading.textContent || 13 checkbox.getAttribute("aria-label") || 14 followingText || 15 checkbox.name || "Option").trim().replace(/\s+/g, " "); 16 } 17 18 function enhance(checkbox) { 19 if (synchronizers.has(checkbox) || checkbox.closest("[data-yn-exclude]")) return; 20 21 const name = readableName(checkbox); 22 const selector = document.createElement("span"); 23 selector.className = "yn-selector"; 24 selector.setAttribute("role", "group"); 25 selector.setAttribute("aria-label", name); 26 27 const yes = document.createElement("button"); 28 const no = document.createElement("button"); 29 for (const [button, letter, word, className] of [ 30 [yes, "Y", "Yes", "yn-yes"], 31 [no, "N", "No", "yn-no"], 32 ]) { 33 button.type = "button"; 34 button.className = "yn-choice " + className; 35 button.textContent = letter; 36 button.setAttribute("aria-label", word + ": " + name); 37 selector.appendChild(button); 38 } 39 40 function sync() { 41 selector.dataset.selected = checkbox.checked ? "y" : "n"; 42 yes.setAttribute("aria-pressed", String(checkbox.checked)); 43 no.setAttribute("aria-pressed", String(!checkbox.checked)); 44 yes.disabled = checkbox.disabled; 45 no.disabled = checkbox.disabled; 46 } 47 48 function choose(checked) { 49 if (checkbox.disabled || checkbox.checked === checked) return; 50 checkbox.checked = checked; 51 checkbox.dispatchEvent(new Event("input", { bubbles: true })); 52 checkbox.dispatchEvent(new Event("change", { bubbles: true })); 53 sync(); 54 } 55 56 yes.addEventListener("click", function () { choose(true); }); 57 no.addEventListener("click", function () { choose(false); }); 58 checkbox.addEventListener("change", sync); 59 checkbox.insertAdjacentElement("afterend", selector); 60 checkbox.classList.add("yn-native"); 61 checkbox.tabIndex = -1; 62 checkbox.setAttribute("aria-hidden", "true"); 63 checkbox.parentElement.classList.add("yn-field"); 64 synchronizers.set(checkbox, sync); 65 sync(); 66 } 67 68 function sync(scope) { 69 (scope || document).querySelectorAll("input.yn-native[type='checkbox']").forEach(function (checkbox) { 70 const update = synchronizers.get(checkbox); 71 if (update) update(); 72 }); 73 } 74 75 function init() { 76 document.querySelectorAll("main input[type='checkbox']").forEach(enhance); 77 document.querySelectorAll("main form").forEach(function (form) { 78 form.addEventListener("reset", function () { 79 window.setTimeout(function () { sync(form); }, 0); 80 }); 81 }); 82 } 83 84 window.LHHYN = { sync: sync }; 85 if (document.readyState === "loading") { 86 document.addEventListener("DOMContentLoaded", init); 87 } else { 88 init(); 89 } 90})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.