mirror of
https://github.com/GuySandler/CanvasRefined.git
synced 2026-09-22 21:05:10 +02:00
dark mode fixes
This commit is contained in:
parent
2db66dbaed
commit
5447891608
@ -1435,4 +1435,30 @@ div[class*='view-tabs__container']:has(#currentTab, #pastTab),
|
|||||||
.notification_account_content a {
|
.notification_account_content a {
|
||||||
color: var(--bclinks) !important;
|
color: var(--bclinks) !important;
|
||||||
}
|
}
|
||||||
|
/* Grades page: opening the comment tray marks the row with
|
||||||
|
.selected-assignment, which Canvas paints light blue (#e0ebf5) with a
|
||||||
|
.3s background transition — reads as a white row in dark mode. Repaint
|
||||||
|
it as the theme's raised surface so the highlight stays visible but
|
||||||
|
dark. */
|
||||||
|
#grades_summary tr.selected-assignment {
|
||||||
|
background-color: var(--bcbackground-2) !important;
|
||||||
|
}
|
||||||
|
/* Grades page (…/courses/:id/grades): the comment chip in each assignment
|
||||||
|
row (speech-bubble icon + count, .toggle_comments_link) keeps Canvas's
|
||||||
|
light-gray pill background and border in dark mode; repaint it as a
|
||||||
|
theme chip. */
|
||||||
|
.toggle_comments_link,
|
||||||
|
.toggle_comments_link:hover {
|
||||||
|
background: var(--bcbackground-2) !important;
|
||||||
|
border-color: var(--bcborders) !important;
|
||||||
|
}
|
||||||
|
/* Grades page "late"/"missing" status pills: InstUI renders the inner pill
|
||||||
|
as a white chip with colored text. The emotion class hashes change between
|
||||||
|
Canvas releases, so match the stable "-pill" fragment scoped under the
|
||||||
|
server-rendered status cell. */
|
||||||
|
td.status [class*="-pill"],
|
||||||
|
td.status [class*="-pill"]:hover {
|
||||||
|
background: var(--bcbackground-2) !important;
|
||||||
|
color: var(--bctext-1) !important;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
@ -4843,6 +4843,88 @@ function generateDarkModeCSS() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let darkStyleInserted = false;
|
let darkStyleInserted = false;
|
||||||
|
// --- Submission tray dark-mode fixer ---------------------------------------
|
||||||
|
// The comment chip on the grades page (…/grades) opens an InstUI
|
||||||
|
// "Submission Comments Tray". Its "Attempt N Feedback" card, close-button
|
||||||
|
// glyph, and some labels arrive with Canvas's light surface and dark ink
|
||||||
|
// through emotion classes whose hashes change between Canvas releases, so
|
||||||
|
// they can't be themed from the static dark stylesheet. Instead, watch for
|
||||||
|
// the tray and recolor at runtime, scoped strictly to elements inside it.
|
||||||
|
// Touched elements are tagged (data-crdarkfix) so turning dark mode off can
|
||||||
|
// restore the original colors.
|
||||||
|
let submissionTrayObserver = null;
|
||||||
|
let submissionTrayFixScheduled = false;
|
||||||
|
|
||||||
|
function crApplySubmissionTrayFix(el, props) {
|
||||||
|
const applied = el.dataset.crdarkfix ? el.dataset.crdarkfix.split(" ") : [];
|
||||||
|
for (const prop of Object.keys(props)) {
|
||||||
|
if (!applied.includes(prop)) applied.push(prop);
|
||||||
|
el.style.setProperty(prop, props[prop], "important");
|
||||||
|
}
|
||||||
|
el.dataset.crdarkfix = applied.join(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixSubmissionTrayColors(root) {
|
||||||
|
const preset = options.dark_preset;
|
||||||
|
if (!preset) return;
|
||||||
|
const light = (r, g, b) => r >= 225 && g >= 225 && b >= 225;
|
||||||
|
const darkInk = (r, g, b) => r <= 70 && g <= 70 && b <= 70;
|
||||||
|
const rgb = (str) => { const m = str && str.match(/rgb\((\d+), ?(\d+), ?(\d+)/); return m ? [+m[1], +m[2], +m[3]] : null; };
|
||||||
|
root.querySelectorAll("*").forEach(el => {
|
||||||
|
if (el instanceof HTMLImageElement || el instanceof HTMLVideoElement) return;
|
||||||
|
const cs = getComputedStyle(el);
|
||||||
|
const bg = rgb(cs.backgroundColor);
|
||||||
|
if (bg && light(bg[0], bg[1], bg[2])) {
|
||||||
|
// light card/surface -> theme surface with readable text
|
||||||
|
crApplySubmissionTrayFix(el, {
|
||||||
|
"background-color": preset["background-2"],
|
||||||
|
"color": preset["text-0"]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const c = rgb(cs.color);
|
||||||
|
if (c && darkInk(c[0], c[1], c[2])) {
|
||||||
|
// dark ink on dark tray (headings, icon glyphs)
|
||||||
|
crApplySubmissionTrayFix(el, { "color": preset["text-0"] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bc = rgb(cs.borderColor);
|
||||||
|
if (bc && light(bc[0], bc[1], bc[2])) {
|
||||||
|
crApplySubmissionTrayFix(el, { "border-color": preset["borders"] });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupSubmissionTrayWatcher() {
|
||||||
|
if (submissionTrayObserver) return;
|
||||||
|
const run = () => {
|
||||||
|
submissionTrayFixScheduled = false;
|
||||||
|
if (options.dark_mode !== true && options.device_dark !== true) return;
|
||||||
|
const tray = document.querySelector('[data-testid="submission-tray"]');
|
||||||
|
if (tray) fixSubmissionTrayColors(tray);
|
||||||
|
};
|
||||||
|
// Canvas mutates the DOM constantly; debounce to one run per frame (same
|
||||||
|
// pattern as the footer observer in startExtension). Comments load into
|
||||||
|
// the tray asynchronously, so re-run whenever the tray subtree changes.
|
||||||
|
submissionTrayObserver = new MutationObserver(() => {
|
||||||
|
if (submissionTrayFixScheduled) return;
|
||||||
|
submissionTrayFixScheduled = true;
|
||||||
|
requestAnimationFrame(run);
|
||||||
|
});
|
||||||
|
submissionTrayObserver.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardownSubmissionTrayFixes() {
|
||||||
|
if (submissionTrayObserver) {
|
||||||
|
submissionTrayObserver.disconnect();
|
||||||
|
submissionTrayObserver = null;
|
||||||
|
}
|
||||||
|
document.querySelectorAll("[data-crdarkfix]").forEach(el => {
|
||||||
|
(el.dataset.crdarkfix || "").split(" ").forEach(prop => el.style.removeProperty(prop));
|
||||||
|
delete el.dataset.crdarkfix;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function toggleDarkMode() {
|
function toggleDarkMode() {
|
||||||
const css = generateDarkModeCSS();
|
const css = generateDarkModeCSS();
|
||||||
const darkOn = options.dark_mode === true || options.device_dark === true;
|
const darkOn = options.dark_mode === true || options.device_dark === true;
|
||||||
@ -4857,6 +4939,14 @@ function toggleDarkMode() {
|
|||||||
style.textContent = css;
|
style.textContent = css;
|
||||||
style.className = darkOn ? "canvasrefined-darkmode-enabled" : "";
|
style.className = darkOn ? "canvasrefined-darkmode-enabled" : "";
|
||||||
darkStyleInserted = true;
|
darkStyleInserted = true;
|
||||||
|
// The InstUI submission tray is themed at runtime (emotion class hashes
|
||||||
|
// change between Canvas releases); keep the watcher in sync with the
|
||||||
|
// current mode, and undo inline fixes when dark mode turns off.
|
||||||
|
if (darkOn) {
|
||||||
|
setupSubmissionTrayWatcher();
|
||||||
|
} else {
|
||||||
|
teardownSubmissionTrayFixes();
|
||||||
|
}
|
||||||
runiframeChecker();
|
runiframeChecker();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user