Merge branch 'nunocoracao:main' into main

This commit is contained in:
ish
2025-09-16 10:00:05 +08:00
committed by GitHub
426 changed files with 1875 additions and 13600 deletions
+124 -210
View File
@@ -1,4 +1,4 @@
/*! tailwindcss v4.1.11 | MIT License | https://tailwindcss.com */
/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */
/*! Blowfish | MIT License | https://github.com/nunocoracao/blowfish */
@layer properties;
#zen-mode-button {
@@ -421,6 +421,9 @@ body.zen-mode-enable {
::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
padding-block: 0;
}
::-webkit-calendar-picker-indicator {
line-height: 1;
}
:-moz-ui-invalid {
box-shadow: none;
}
@@ -488,6 +491,12 @@ body.zen-mode-enable {
.inset-x-0 {
inset-inline: calc(var(--spacing) * 0);
}
.-start-6 {
inset-inline-start: calc(var(--spacing) * -6);
}
.start-\[calc\(max\(-50vw\,-800px\)\+50\%\)\] {
inset-inline-start: calc(max(-50vw, -800px) + 50%);
}
.top-0 {
top: calc(var(--spacing) * 0);
}
@@ -515,9 +524,6 @@ body.zen-mode-enable {
.left-1\/2 {
left: calc(1/2 * 100%);
}
.left-\[calc\(max\(-50vw\,-800px\)\+50\%\)\] {
left: calc(max(-50vw, -800px) + 50%);
}
.-z-10 {
z-index: calc(10 * -1);
}
@@ -620,6 +626,30 @@ body.zen-mode-enable {
.my-3 {
margin-block: calc(var(--spacing) * 3);
}
.-ms-5 {
margin-inline-start: calc(var(--spacing) * -5);
}
.ms-0 {
margin-inline-start: calc(var(--spacing) * 0);
}
.ms-2 {
margin-inline-start: calc(var(--spacing) * 2);
}
.ms-6 {
margin-inline-start: calc(var(--spacing) * 6);
}
.-me-48 {
margin-inline-end: calc(var(--spacing) * -48);
}
.me-1 {
margin-inline-end: calc(var(--spacing) * 1);
}
.me-2 {
margin-inline-end: calc(var(--spacing) * 2);
}
.me-4 {
margin-inline-end: calc(var(--spacing) * 4);
}
.prose {
color: var(--tw-prose-body);
max-width: 65ch;
@@ -1117,9 +1147,6 @@ body.zen-mode-enable {
.mt-\[0\.5rem\] {
margin-top: 0.5rem;
}
.-mr-48 {
margin-right: calc(var(--spacing) * -48);
}
.-mr-\[100\%\] {
margin-right: calc(100% * -1);
}
@@ -1138,9 +1165,6 @@ body.zen-mode-enable {
.mr-5 {
margin-right: calc(var(--spacing) * 5);
}
.mr-\[10px\] {
margin-right: 10px;
}
.mr-auto {
margin-right: auto;
}
@@ -1189,9 +1213,6 @@ body.zen-mode-enable {
.mb-\[2px\] {
margin-bottom: 2px;
}
.-ml-12 {
margin-left: calc(var(--spacing) * -12);
}
.ml-0 {
margin-left: calc(var(--spacing) * 0);
}
@@ -1201,9 +1222,6 @@ body.zen-mode-enable {
.ml-3 {
margin-left: calc(var(--spacing) * 3);
}
.ml-6 {
margin-left: calc(var(--spacing) * 6);
}
.ml-auto {
margin-left: auto;
}
@@ -1289,9 +1307,6 @@ body.zen-mode-enable {
.inline-block {
display: inline-block;
}
.list-item {
display: list-item;
}
.table {
display: table;
}
@@ -1491,12 +1506,6 @@ body.zen-mode-enable {
.flex-none {
flex: none;
}
.flex-shrink {
flex-shrink: 1;
}
.shrink {
flex-shrink: 1;
}
.shrink-0 {
flex-shrink: 0;
}
@@ -1509,9 +1518,6 @@ body.zen-mode-enable {
.basis-auto {
flex-basis: auto;
}
.border-collapse {
border-collapse: collapse;
}
.-translate-x-1\/2 {
--tw-translate-x: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -1754,6 +1760,14 @@ body.zen-mode-enable {
border-inline-start-style: var(--tw-border-style);
border-inline-start-width: 0px;
}
.border-s-1 {
border-inline-start-style: var(--tw-border-style);
border-inline-start-width: 1px;
}
.border-s-2 {
border-inline-start-style: var(--tw-border-style);
border-inline-start-width: 2px;
}
.border-s-\[0\.125rem\] {
border-inline-start-style: var(--tw-border-style);
border-inline-start-width: 0.125rem;
@@ -1770,10 +1784,6 @@ body.zen-mode-enable {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 2px;
}
.border-l-2 {
border-left-style: var(--tw-border-style);
border-left-width: 2px;
}
.border-dotted {
--tw-border-style: dotted;
border-style: dotted;
@@ -1848,6 +1858,9 @@ body.zen-mode-enable {
.bg-\[\#6d6d6d\] {
background-color: #6d6d6d;
}
.bg-black {
background-color: #000;
}
.bg-neutral {
background-color: rgba(var(--color-neutral), 1);
}
@@ -1893,6 +1906,9 @@ body.zen-mode-enable {
.bg-transparent {
background-color: transparent;
}
.bg-white {
background-color: #fff;
}
.bg-gradient-to-b {
--tw-gradient-position: to bottom in oklab;
background-image: linear-gradient(var(--tw-gradient-stops));
@@ -2028,6 +2044,18 @@ body.zen-mode-enable {
.py-\[1px\] {
padding-block: 1px;
}
.ps-2 {
padding-inline-start: calc(var(--spacing) * 2);
}
.ps-5 {
padding-inline-start: calc(var(--spacing) * 5);
}
.pe-2 {
padding-inline-end: calc(var(--spacing) * 2);
}
.pe-3 {
padding-inline-end: calc(var(--spacing) * 3);
}
.pt-1 {
padding-top: calc(var(--spacing) * 1);
}
@@ -2085,9 +2113,6 @@ body.zen-mode-enable {
.pl-0 {
padding-left: calc(var(--spacing) * 0);
}
.pl-2 {
padding-left: calc(var(--spacing) * 2);
}
.pl-4 {
padding-left: calc(var(--spacing) * 4);
}
@@ -2097,12 +2122,18 @@ body.zen-mode-enable {
.text-center {
text-align: center;
}
.text-end {
text-align: end;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-start {
text-align: start;
}
.-indent-\[999px\] {
text-indent: calc(999px * -1);
}
@@ -2264,6 +2295,9 @@ body.zen-mode-enable {
.text-transparent {
color: transparent;
}
.text-white {
color: #fff;
}
.capitalize {
text-transform: capitalize;
}
@@ -2356,14 +2390,6 @@ body.zen-mode-enable {
--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.ring {
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.outline {
outline-style: var(--tw-outline-style);
outline-width: 1px;
}
.blur {
--tw-blur: blur(8px);
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
@@ -2561,11 +2587,24 @@ body.zen-mode-enable {
border-style: solid;
}
}
.group-data-\[twe-input-focused\]\:border-white {
&:is(:where(.group)[data-twe-input-focused] *) {
border-color: #fff;
}
}
.group-data-\[twe-input-focused\]\:border-t-transparent {
&:is(:where(.group)[data-twe-input-focused] *) {
border-top-color: transparent;
}
}
.group-data-\[twe-input-focused\]\:shadow-white {
&:is(:where(.group)[data-twe-input-focused] *) {
--tw-shadow-color: #fff;
@supports (color: color-mix(in lab, red, red)) {
--tw-shadow-color: color-mix(in oklab, #fff var(--tw-shadow-alpha), transparent);
}
}
}
.group-data-\[twe-input-state-active\]\:border-x-0 {
&:is(:where(.group)[data-twe-input-state-active] *) {
border-inline-style: var(--tw-border-style);
@@ -2721,13 +2760,6 @@ body.zen-mode-enable {
}
}
}
.hover\:decoration-neutral-300 {
&:hover {
@media (hover: hover) {
text-decoration-color: rgba(var(--color-neutral-300), 1);
}
}
}
.hover\:decoration-primary-400 {
&:hover {
@media (hover: hover) {
@@ -2735,13 +2767,6 @@ body.zen-mode-enable {
}
}
}
.hover\:decoration-primary-500 {
&:hover {
@media (hover: hover) {
text-decoration-color: rgba(var(--color-primary-500), 1);
}
}
}
.hover\:decoration-2 {
&:hover {
@media (hover: hover) {
@@ -2866,6 +2891,11 @@ body.zen-mode-enable {
transition-property: none;
}
}
.sm\:me-7 {
@media (width >= 640px) {
margin-inline-end: calc(var(--spacing) * 7);
}
}
.sm\:mt-16 {
@media (width >= 640px) {
margin-top: calc(var(--spacing) * 16);
@@ -2922,16 +2952,23 @@ body.zen-mode-enable {
line-height: var(--tw-leading, var(--text-lg--line-height));
}
}
.sm\:last\:me-0 {
@media (width >= 640px) {
&:last-child {
margin-inline-end: calc(var(--spacing) * 0);
}
}
}
.md\:-me-16 {
@media (width >= 853px) {
margin-inline-end: calc(var(--spacing) * -16);
}
}
.md\:mt-0 {
@media (width >= 853px) {
margin-top: calc(var(--spacing) * 0);
}
}
.md\:-mr-16 {
@media (width >= 853px) {
margin-right: calc(var(--spacing) * -16);
}
}
.md\:mr-7 {
@media (width >= 853px) {
margin-right: calc(var(--spacing) * 7);
@@ -3022,11 +3059,6 @@ body.zen-mode-enable {
top: 140px;
}
}
.lg\:left-0 {
@media (width >= 1024px) {
left: calc(var(--spacing) * 0);
}
}
.lg\:order-last {
@media (width >= 1024px) {
order: 9999;
@@ -3157,6 +3189,11 @@ body.zen-mode-enable {
padding-block: calc(var(--spacing) * 32);
}
}
.lg\:ps-8 {
@media (width >= 1024px) {
padding-inline-start: calc(var(--spacing) * 8);
}
}
.xl\:w-1\/4 {
@media (width >= 1280px) {
width: calc(1/4 * 100%);
@@ -3177,34 +3214,14 @@ body.zen-mode-enable {
right: calc(var(--spacing) * 0);
}
}
.ltr\:-left-6 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
left: calc(var(--spacing) * -6);
}
}
.ltr\:mr-1 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
margin-right: calc(var(--spacing) * 1);
}
}
.ltr\:mr-4 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
margin-right: calc(var(--spacing) * 4);
}
}
.ltr\:-ml-5 {
.ltr\:-ml-12 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
margin-left: calc(var(--spacing) * -5);
}
}
.ltr\:ml-0 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
margin-left: calc(var(--spacing) * 0);
}
}
.ltr\:ml-2 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
margin-left: calc(var(--spacing) * 2);
margin-left: calc(var(--spacing) * -12);
}
}
.ltr\:block {
@@ -3222,83 +3239,19 @@ body.zen-mode-enable {
display: inline;
}
}
.ltr\:border-l {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
border-left-style: var(--tw-border-style);
border-left-width: 1px;
}
}
.ltr\:pr-2 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
padding-right: calc(var(--spacing) * 2);
}
}
.ltr\:pr-3 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
padding-right: calc(var(--spacing) * 3);
}
}
.ltr\:pl-5 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
padding-left: calc(var(--spacing) * 5);
}
}
.ltr\:text-right {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
text-align: right;
}
}
.ltr\:sm\:mr-7 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
@media (width >= 640px) {
margin-right: calc(var(--spacing) * 7);
}
}
}
.ltr\:sm\:last\:mr-0 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
@media (width >= 640px) {
&:last-child {
margin-right: calc(var(--spacing) * 0);
}
}
}
}
.ltr\:lg\:pl-8 {
&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *) {
@media (width >= 1024px) {
padding-left: calc(var(--spacing) * 8);
}
}
}
.rtl\:-right-6 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
right: calc(var(--spacing) * -6);
}
}
.rtl\:left-0 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
left: calc(var(--spacing) * 0);
}
}
.rtl\:-mr-5 {
.rtl\:-mr-\[79px\] {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
margin-right: calc(var(--spacing) * -5);
}
}
.rtl\:mr-0 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
margin-right: calc(var(--spacing) * 0);
}
}
.rtl\:mr-2 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
margin-right: calc(var(--spacing) * 2);
}
}
.rtl\:ml-1 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
margin-left: calc(var(--spacing) * 1);
margin-right: calc(79px * -1);
}
}
.rtl\:ml-4 {
@@ -3321,55 +3274,6 @@ body.zen-mode-enable {
display: inline;
}
}
.rtl\:border-r {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
border-right-style: var(--tw-border-style);
border-right-width: 1px;
}
}
.rtl\:pr-5 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
padding-right: calc(var(--spacing) * 5);
}
}
.rtl\:pl-2 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
padding-left: calc(var(--spacing) * 2);
}
}
.rtl\:pl-3 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
padding-left: calc(var(--spacing) * 3);
}
}
.rtl\:text-left {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
text-align: left;
}
}
.rtl\:sm\:ml-7 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
@media (width >= 640px) {
margin-left: calc(var(--spacing) * 7);
}
}
}
.rtl\:sm\:last\:ml-0 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
@media (width >= 640px) {
&:last-child {
margin-left: calc(var(--spacing) * 0);
}
}
}
}
.rtl\:lg\:pr-8 {
&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
@media (width >= 1024px) {
padding-right: calc(var(--spacing) * 8);
}
}
}
.dark\:flex {
&:is(.dark *) {
display: flex;
@@ -3405,6 +3309,11 @@ body.zen-mode-enable {
border-color: rgba(var(--color-primary-600), 1);
}
}
.dark\:border-white\/10 {
&:is(.dark *) {
border-color: color-mix(in oklab, #fff 10%, transparent);
}
}
.dark\:prose-invert {
&:is(.dark *) {
--tw-prose-body: var(--tw-prose-invert-body);
@@ -3579,6 +3488,11 @@ body.zen-mode-enable {
color: rgba(var(--color-primary-400), 1);
}
}
.dark\:text-white {
&:is(.dark *) {
color: #fff;
}
}
.dark\:opacity-60 {
&:is(.dark *) {
opacity: 60%;
@@ -4317,11 +4231,6 @@ pre {
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
initial-value: solid;
}
@property --tw-blur {
syntax: "*";
inherits: false;
@@ -4424,6 +4333,11 @@ pre {
initial-value: "";
inherits: false;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
initial-value: solid;
}
@keyframes pulse {
50% {
opacity: 0.5;
@@ -4480,7 +4394,6 @@ pre {
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-offset-shadow: 0 0 #0000;
--tw-outline-style: solid;
--tw-blur: initial;
--tw-brightness: initial;
--tw-contrast: initial;
@@ -4506,6 +4419,7 @@ pre {
--tw-duration: initial;
--tw-ease: initial;
--tw-content: "";
--tw-outline-style: solid;
}
}
}
+158 -182
View File
@@ -1,194 +1,170 @@
const getA11ySettings = () => {
const settings = localStorage.getItem("a11ySettings");
return settings
? JSON.parse(settings)
: {
disableBlur: false,
disableImages: false,
fontSize: "default",
underlineLinks: false,
zenMode: false,
};
};
window.A11yPanel = (() => {
const FEATURES = {
disableBlur: {
default: false,
apply: (enabled) => {
document.querySelectorAll("script[data-blur-id]").forEach((script) => {
const targetId = script.getAttribute("data-blur-id");
const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300);
if (typeof setBackgroundBlur === "function") {
setBackgroundBlur(targetId, scrollDivisor, enabled, targetId === "menu-blur");
}
});
},
},
const saveA11ySettings = (settings) => {
localStorage.setItem("a11ySettings", JSON.stringify(settings));
};
disableImages: {
default: false,
apply: (enabled) => {
const image = document.getElementById("background-image");
if (image) {
image.style.display = enabled ? "none" : "";
}
},
},
const applyImageState = (imageElement, imageUrl, disableImages) => {
if (!imageElement) return;
if (disableImages) {
imageElement.style.display = "none";
} else {
imageElement.style.display = "";
if (imageUrl && !imageElement.getAttribute("src")) {
imageElement.setAttribute("src", imageUrl);
fontSize: {
default: "default",
apply: (size) => {
document.documentElement.style.fontSize = size === "default" ? "" : size;
},
},
underlineLinks: {
default: false,
apply: (enabled) => {
const existing = document.getElementById("a11y-underline-links");
if (enabled && !existing) {
const style = document.createElement("style");
style.id = "a11y-underline-links";
style.textContent = `
a { text-decoration: underline !important; }
.group-hover-card-title { text-decoration: underline !important; }
.group-hover-card:hover .group-hover-card-title { text-decoration: underline !important; }`;
document.head.appendChild(style);
} else if (!enabled && existing) {
existing.remove();
}
},
},
zenMode: {
default: false,
apply: (enabled) => {
const isActive = document.body?.classList.contains("zen-mode-enable");
if (enabled !== isActive) {
const checkbox = document.querySelector('[id$="zen-mode"]');
if (checkbox && typeof _toggleZenMode === "function") {
_toggleZenMode(checkbox, { scrollToHeader: false });
}
}
},
},
};
let settings = null;
const getSettings = () => {
if (settings) return settings;
const defaults = Object.fromEntries(Object.entries(FEATURES).map(([key, config]) => [key, config.default]));
try {
const saved = localStorage.getItem("a11ySettings");
settings = { ...defaults, ...JSON.parse(saved || "{}") };
} catch {
settings = defaults;
}
}
};
return settings;
};
const applyFontSize = (fontSizePx) => {
const isDefaultSettings = localStorage.getItem("a11ySettings") === null;
if (!isDefaultSettings && fontSizePx !== "default") {
document.documentElement.style.fontSize = fontSizePx;
}
};
const applyUnderlineLinks = (enabled) => {
let styleElement = document.getElementById("a11y-underline-links");
if (enabled) {
if (!styleElement) {
styleElement = document.createElement("style");
styleElement.id = "a11y-underline-links";
styleElement.textContent = "a { text-decoration: underline !important; }";
document.head.appendChild(styleElement);
const updateSetting = (key, value) => {
const current = getSettings();
current[key] = value;
try {
localStorage.setItem("a11ySettings", JSON.stringify(current));
} catch (e) {
console.warn(`a11y.js: can not store settings: ${e}`);
}
} else {
if (styleElement) {
styleElement.remove();
}
}
};
FEATURES[key]?.apply(value);
};
const applyZenMode = (enabled) => {
const body = document.querySelector("body");
const isZenModeActive = body && body.classList.contains("zen-mode-enable");
const initPanel = (panelId) => {
const prefix = panelId.replace("a11y-panel", "");
const current = getSettings();
// Toggle only if current state doesn't match desired state
if (enabled !== isZenModeActive) {
const zenModeCheckbox = document.querySelector('[id$="zen-mode"]');
if (zenModeCheckbox && typeof _toggleZenMode === "function") {
_toggleZenMode(zenModeCheckbox, { scrollToHeader: false });
}
}
};
Object.entries(FEATURES).forEach(([key, config]) => {
const elementId = `${prefix}${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
const element = document.getElementById(elementId) || document.getElementById(`${elementId}-select`);
const applyA11ySettings = () => {
const settings = getA11ySettings();
document.querySelectorAll("script[data-target-id]").forEach((script) => {
const targetId = script.getAttribute("data-target-id");
const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300);
const imageId = script.getAttribute("data-image-id");
const imageUrl = script.getAttribute("data-image-url");
const isMenuBlur = targetId === "menu-blur";
setBackgroundBlur(targetId, scrollDivisor, settings.disableBlur, isMenuBlur);
applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages);
});
applyFontSize(settings.fontSize);
applyUnderlineLinks(settings.underlineLinks);
applyZenMode(settings.zenMode);
};
const updateA11ySetting = (key, value) => {
const settings = getA11ySettings();
settings[key] = value;
saveA11ySettings(settings);
applyA11ySettings();
};
const toggleA11yPanel = (prefix = "") => {
const panel = document.getElementById(`${prefix}a11y-panel`);
const overlay = document.getElementById(`${prefix}a11y-overlay`);
const button = document.getElementById(`${prefix}a11y-toggle`);
if (!panel || !overlay || !button) return;
if (overlay.classList.contains("hidden")) {
overlay.classList.remove("hidden");
panel.classList.remove("hidden");
button.setAttribute("aria-pressed", "true");
button.setAttribute("aria-expanded", "true");
} else {
overlay.classList.add("hidden");
panel.classList.add("hidden");
button.setAttribute("aria-pressed", "false");
button.setAttribute("aria-expanded", "false");
}
};
const initA11yPanel = (prefix = "") => {
const settings = getA11ySettings();
const checkboxBlur = document.getElementById(`${prefix}disable-blur`);
const checkboxImages = document.getElementById(`${prefix}disable-images`);
const checkboxUnderline = document.getElementById(`${prefix}underline-links`);
const checkboxZenMode = document.getElementById(`${prefix}zen-mode`);
const fontSizeSelect = document.getElementById(`${prefix}font-size-select`);
const toggleButton = document.getElementById(`${prefix}a11y-toggle`);
const closeButton = document.getElementById(`${prefix}a11y-close`);
const overlay = document.getElementById(`${prefix}a11y-overlay`);
if (
!checkboxBlur ||
!checkboxImages ||
!checkboxUnderline ||
!checkboxZenMode ||
!fontSizeSelect ||
!toggleButton ||
!closeButton ||
!overlay
) {
console.warn(`One or more a11y elements not found for prefix: ${prefix}`);
return;
}
checkboxBlur.checked = settings.disableBlur;
checkboxImages.checked = settings.disableImages;
checkboxUnderline.checked = settings.underlineLinks;
checkboxZenMode.checked = settings.zenMode;
fontSizeSelect.value = settings.fontSize;
checkboxBlur.addEventListener("change", (e) => updateA11ySetting("disableBlur", e.target.checked));
checkboxImages.addEventListener("change", (e) => updateA11ySetting("disableImages", e.target.checked));
checkboxUnderline.addEventListener("change", (e) => updateA11ySetting("underlineLinks", e.target.checked));
checkboxZenMode.addEventListener("change", (e) => {
// Only save setting, let applyZenMode handle the toggle logic
updateA11ySetting("zenMode", e.target.checked);
});
fontSizeSelect.addEventListener("change", (e) => {
// Remove fontSize from localStorage when default is selected
if (e.target.value === "default") {
const settings = getA11ySettings();
delete settings.fontSize;
saveA11ySettings(settings);
document.documentElement.style.fontSize = "";
} else {
updateA11ySetting("fontSize", e.target.value);
}
});
toggleButton.addEventListener("click", () => toggleA11yPanel(prefix));
closeButton.addEventListener("click", () => toggleA11yPanel(prefix));
overlay.addEventListener("click", (e) => {
if (e.target === overlay) {
toggleA11yPanel(prefix);
}
});
document.querySelectorAll(`.ios-toggle${prefix ? `[id^="${prefix}"]` : ""}`).forEach((toggle) => {
const checkbox = toggle.querySelector('input[type="checkbox"]');
if (!checkbox) return;
const newToggle = toggle.cloneNode(true);
toggle.parentNode.replaceChild(newToggle, toggle);
newToggle.addEventListener("click", () => {
const newCheckbox = newToggle.querySelector('input[type="checkbox"]');
if (newCheckbox) {
newCheckbox.checked = !newCheckbox.checked;
newCheckbox.dispatchEvent(new Event("change", { bubbles: true }));
if (element) {
if (element.type === "checkbox") {
element.checked = current[key];
element.onchange = (e) => updateSetting(key, e.target.checked);
} else if (element.tagName === "SELECT") {
element.value = current[key];
element.onchange = (e) => updateSetting(key, e.target.value);
}
}
});
});
};
document.querySelectorAll("script[data-target-id]").forEach((script) => {
const imageId = script.getAttribute("data-image-id");
const imageUrl = script.getAttribute("data-image-url");
const settings = getA11ySettings();
applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages);
});
const togglePanel = () => {
const panel = document.getElementById(panelId);
const overlay = document.getElementById(`${prefix}a11y-overlay`);
const toggle = document.getElementById(`${prefix}a11y-toggle`);
document.addEventListener("DOMContentLoaded", () => {
applyA11ySettings();
const allPanels = document.querySelectorAll('[id$="a11y-panel"]');
allPanels.forEach((panel) => {
const prefix = panel.id.replace("a11y-panel", "");
initA11yPanel(prefix);
});
});
if (!panel || !overlay) return;
const isHidden = overlay.classList.contains("hidden");
overlay.classList.toggle("hidden");
panel.classList.toggle("hidden");
if (toggle) {
toggle.setAttribute("aria-pressed", String(isHidden));
toggle.setAttribute("aria-expanded", String(isHidden));
}
};
const toggle = document.getElementById(`${prefix}a11y-toggle`);
const close = document.getElementById(`${prefix}a11y-close`);
const overlay = document.getElementById(`${prefix}a11y-overlay`);
if (toggle) toggle.onclick = togglePanel;
if (close) close.onclick = togglePanel;
if (overlay) overlay.onclick = (e) => e.target === overlay && togglePanel();
};
const applyAll = () => {
const current = getSettings();
Object.entries(current).forEach(([key, value]) => {
FEATURES[key]?.apply(value);
});
};
const init = () => {
applyAll();
document.querySelectorAll('[id$="a11y-panel"]').forEach((panel) => {
initPanel(panel.id);
});
};
if (getSettings().disableImages) {
new MutationObserver(() => {
const img = document.getElementById("background-image");
if (img) img.style.display = "none";
}).observe(document, { childList: true, subtree: true });
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
return {
getSettings,
updateSetting,
addFeature: (name, config) => {
FEATURES[name] = config;
FEATURES[name].apply(getSettings()[name] || config.default);
},
};
})();
+3 -16
View File
@@ -1,6 +1,6 @@
function setBackgroundBlur(targetId, scrollDivisor = 300, disableBlur = false, isMenuBlur = false) {
if (!targetId) {
console.error("data-target-id is null");
console.error("data-blur-id is null");
return;
}
const blurElement = document.getElementById(targetId);
@@ -29,24 +29,11 @@ function setBackgroundBlur(targetId, scrollDivisor = 300, disableBlur = false, i
updateBlur();
}
document.querySelectorAll("script[data-target-id]").forEach((script) => {
const targetId = script.getAttribute("data-target-id");
document.querySelectorAll("script[data-blur-id]").forEach((script) => {
const targetId = script.getAttribute("data-blur-id");
const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300);
const isMenuBlur = targetId === "menu-blur";
const settings = JSON.parse(localStorage.getItem("a11ySettings") || "{}");
const disableBlur = settings.disableBlur || false;
setBackgroundBlur(targetId, scrollDivisor, disableBlur, isMenuBlur);
});
// Prevent disableImages FOUC
// Note: I tried putting this in a11y.js but it did not work, and placing it here prevents FOUC
(() => {
const settings = JSON.parse(localStorage.getItem("a11ySettings") || "{}");
if (settings.disableImages) {
document.querySelectorAll("script[data-image-id]").forEach((script) => {
const imageId = script.getAttribute("data-image-id");
const image = imageId && document.getElementById(imageId);
if (image) image.style.display = "none";
});
}
})();
+59 -50
View File
@@ -1,10 +1,6 @@
var scriptBundle = document.getElementById("script-bundle");
var copyText =
scriptBundle && scriptBundle.getAttribute("data-copy") ? scriptBundle.getAttribute("data-copy") : "Copy";
var copiedText =
scriptBundle && scriptBundle.getAttribute("data-copied")
? scriptBundle.getAttribute("data-copied")
: "Copied";
var copyText = scriptBundle?.getAttribute("data-copy") || "Copy";
var copiedText = scriptBundle?.getAttribute("data-copied") || "Copied";
function createCopyButton(highlightDiv) {
const button = document.createElement("button");
@@ -13,51 +9,7 @@ function createCopyButton(highlightDiv) {
button.ariaLabel = copyText;
button.innerText = copyText;
button.addEventListener("click", () => copyCodeToClipboard(button, highlightDiv));
addCopyButtonToDom(button, highlightDiv);
}
async function copyCodeToClipboard(button, highlightDiv) {
const codeToCopy = highlightDiv.querySelector(":last-child").innerText;
try {
result = await navigator.permissions.query({ name: "clipboard-write" });
if (result.state == "granted" || result.state == "prompt") {
await navigator.clipboard.writeText(codeToCopy);
} else {
copyCodeBlockExecCommand(codeToCopy, highlightDiv);
}
} catch (_) {
copyCodeBlockExecCommand(codeToCopy, highlightDiv);
} finally {
codeWasCopied(button);
}
}
function copyCodeBlockExecCommand(codeToCopy, highlightDiv) {
const textArea = document.createElement("textArea");
textArea.contentEditable = "true";
textArea.readOnly = "false";
textArea.className = "copy-textarea";
textArea.value = codeToCopy;
highlightDiv.insertBefore(textArea, highlightDiv.firstChild);
const range = document.createRange();
range.selectNodeContents(textArea);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
textArea.setSelectionRange(0, 999999);
document.execCommand("copy");
highlightDiv.removeChild(textArea);
}
function codeWasCopied(button) {
button.blur();
button.innerText = copiedText;
setTimeout(function () {
button.innerText = copyText;
}, 2000);
}
function addCopyButtonToDom(button, highlightDiv) {
highlightDiv.insertBefore(button, highlightDiv.firstChild);
const wrapper = document.createElement("div");
wrapper.className = "highlight-wrapper";
@@ -65,6 +17,63 @@ function addCopyButtonToDom(button, highlightDiv) {
wrapper.appendChild(highlightDiv);
}
async function copyCodeToClipboard(button, highlightDiv) {
const codeToCopy = getCodeText(highlightDiv);
function fallback(codeToCopy, highlightDiv) {
const textArea = document.createElement("textArea");
textArea.contentEditable = "true";
textArea.readOnly = "false";
textArea.className = "copy-textarea";
textArea.value = codeToCopy;
highlightDiv.insertBefore(textArea, highlightDiv.firstChild);
const range = document.createRange();
range.selectNodeContents(textArea);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
textArea.setSelectionRange(0, 999999);
document.execCommand("copy");
highlightDiv.removeChild(textArea);
}
try {
result = await navigator.permissions.query({ name: "clipboard-write" });
if (result.state == "granted" || result.state == "prompt") {
await navigator.clipboard.writeText(codeToCopy);
} else {
fallback(codeToCopy, highlightDiv);
}
} catch (_) {
fallback(codeToCopy, highlightDiv);
} finally {
button.blur();
button.innerText = copiedText;
setTimeout(function () {
button.innerText = copyText;
}, 2000);
}
}
function getCodeText(highlightDiv) {
const codeBlock = highlightDiv.querySelector("code");
const inlineLines = codeBlock?.querySelectorAll(".cl"); // linenos=inline
const tableCodeCell = highlightDiv?.querySelector(".lntable .lntd:last-child code"); // linenos=table
if (!codeBlock) return "";
if (inlineLines.length > 0) {
const cleanedLines = Array.from(inlineLines).map((line) => line.textContent.replace(/\n$/, ""));
return cleanedLines.join("\n");
}
if (tableCodeCell) {
return tableCodeCell.textContent.trim();
}
return codeBlock.textContent.trim();
}
window.addEventListener("DOMContentLoaded", (event) => {
document.querySelectorAll(".highlight").forEach((highlightDiv) => createCopyButton(highlightDiv));
});
+13 -1
View File
@@ -64,6 +64,16 @@
});
const data = await response.json();
if (!response.ok) {
console.error(`fetch-repo.js: HTTP Error: ${response.status} ${response.statusText}`);
return;
}
if (!data || typeof data !== "object") {
console.error("fetch-repo.js: Invalid or empty data received from remote");
return;
}
Object.entries(mapping).forEach(([dataField, elementSuffix]) => {
const element = document.getElementById(`${repoId}-${elementSuffix}`);
if (element) {
@@ -71,7 +81,9 @@
if (processors[platform]?.[dataField]) {
value = processors[platform][dataField](value);
}
element.innerHTML = value;
if (value != null && value !== "") {
element.innerHTML = value;
}
}
});
} catch (error) {
+555 -520
View File
File diff suppressed because one or more lines are too long