OPTIMIZE OPTIMIZE

This commit is contained in:
Guy Sandler 2026-08-22 18:08:14 -07:00
parent d40fc01b42
commit 6820ef1163
2 changed files with 53744 additions and 69 deletions

View File

@ -117,6 +117,18 @@ function ensureSubmissionPageButton() {
return Boolean(content.querySelector("#canvasrefined-assignment-return")); return Boolean(content.querySelector("#canvasrefined-assignment-return"));
} }
function isAssignmentPage() {
return /^\/courses\/\d+\/assignments(?:\/\d+)?(?:\/|$)/.test(current_page);
}
function removeSequenceFooter() {
if (!isAssignmentPage()) return false;
const sequenceFooter = document.getElementById("sequence_footer");
if (!sequenceFooter) return false;
sequenceFooter.remove();
return true;
}
function watchSequenceFooter() { function watchSequenceFooter() {
if (!isAssignmentPage()) return; if (!isAssignmentPage()) return;
if (removeSequenceFooter()) return; if (removeSequenceFooter()) return;
@ -170,7 +182,8 @@ function watchNewCanvasButton() {
} }
if (options.hide_new_canvas !== true) return; if (options.hide_new_canvas !== true) return;
removeNewCanvasButton(); removeNewCanvasButton();
newCanvasButtonObserver = new MutationObserver(() => { let newCanvasButtonScheduled = false;
newCanvasButtonObserver = new MutationObserver((mutationList) => {
if (options.hide_new_canvas !== true) { if (options.hide_new_canvas !== true) {
if (newCanvasButtonObserver) { if (newCanvasButtonObserver) {
newCanvasButtonObserver.disconnect(); newCanvasButtonObserver.disconnect();
@ -178,7 +191,18 @@ function watchNewCanvasButton() {
} }
return; return;
} }
removeNewCanvasButton(); // Only scan when nodes were actually added, and coalesce to one pass per frame.
let added = false;
for (const mutation of mutationList) {
if (mutation.addedNodes && mutation.addedNodes.length) { added = true; break; }
}
if (!added || newCanvasButtonScheduled) return;
newCanvasButtonScheduled = true;
requestAnimationFrame(() => {
newCanvasButtonScheduled = false;
if (options.hide_new_canvas !== true) return;
removeNewCanvasButton();
});
}); });
newCanvasButtonObserver.observe(document.documentElement, { childList: true, subtree: true }); newCanvasButtonObserver.observe(document.documentElement, { childList: true, subtree: true });
} }
@ -191,35 +215,27 @@ async function getActiveCustomBackground() {
"customBackgroundScale", "customBackgroundScale",
]); ]);
console.log("[CanvasRefined] getActiveCustomBackground:", syncOpts);
if (syncOpts.customBackgroundNasaDaily === true) { if (syncOpts.customBackgroundNasaDaily === true) {
console.log("[CanvasRefined] Using NASA APOD");
return await getNasaDailyBackground(); return await getNasaDailyBackground();
} }
if (syncOpts.customBackgroundDaily === true) { if (syncOpts.customBackgroundDaily === true) {
console.log("[CanvasRefined] Using Wikimedia Featured");
const dailyPreset = await getDailyBackgroundPreset(); const dailyPreset = await getDailyBackgroundPreset();
if (dailyPreset) { if (dailyPreset) {
console.log("[CanvasRefined] Wikimedia URL:", dailyPreset.url);
return { return {
url: dailyPreset.url, url: dailyPreset.url,
scale: dailyPreset.scale, scale: dailyPreset.scale,
}; };
} }
console.log("[CanvasRefined] Wikimedia returned null");
} }
if (syncOpts.customBackgroundLink && syncOpts.customBackgroundLink !== "") { if (syncOpts.customBackgroundLink && syncOpts.customBackgroundLink !== "") {
console.log("[CanvasRefined] Using custom link");
return { return {
url: syncOpts.customBackgroundLink, url: syncOpts.customBackgroundLink,
scale: syncOpts.customBackgroundScale || 100, scale: syncOpts.customBackgroundScale || 100,
}; };
} }
console.log("[CanvasRefined] No custom background");
return null; return null;
} }
@ -373,6 +389,7 @@ let timeCheck = null;
let reminderCheck = null; let reminderCheck = null;
let betterSidebarLoading = false; let betterSidebarLoading = false;
let dashboardReadyTimer = null; let dashboardReadyTimer = null;
let sidebarReadyTimer = null;
let sidebarBadgeObserver = null; let sidebarBadgeObserver = null;
let sidebarBadgeSyncTimer = null; let sidebarBadgeSyncTimer = null;
let sidebarBadgeWatchRetries = 0; let sidebarBadgeWatchRetries = 0;
@ -526,8 +543,16 @@ function startExtension() {
if (footer) footer.remove(); if (footer) footer.remove();
}; };
removeFooter(); removeFooter();
let footerScheduled = false;
const footerObserver = new MutationObserver(() => { const footerObserver = new MutationObserver(() => {
removeFooter(); // Canvas mutates the DOM constantly; only check for the footer at most once
// per animation frame instead of running a querySelector on every mutation.
if (footerScheduled) return;
footerScheduled = true;
requestAnimationFrame(() => {
footerScheduled = false;
removeFooter();
});
}); });
footerObserver.observe(document.documentElement, { childList: true, subtree: true }); footerObserver.observe(document.documentElement, { childList: true, subtree: true });
@ -578,7 +603,6 @@ function applyOptionsChanges(changes) {
// so any changes made in the menu no longer require a refresh to apply // so any changes made in the menu no longer require a refresh to apply
Object.keys(changes).forEach(key => { Object.keys(changes).forEach(key => {
console.log(key + " changed");
switch (key) { switch (key) {
case "dark_mode": case "dark_mode":
case "dark_preset": case "dark_preset":
@ -793,7 +817,6 @@ async function applyCustomBackground() {
style.id = "canvasrefined-background"; style.id = "canvasrefined-background";
const activeBackground = await getActiveCustomBackground(); const activeBackground = await getActiveCustomBackground();
console.log("[CanvasRefined] activeBackground:", activeBackground);
if (!activeBackground) { if (!activeBackground) {
if (style.isConnected) style.remove(); if (style.isConnected) style.remove();
return; return;
@ -802,7 +825,6 @@ async function applyCustomBackground() {
const backgroundScale = Number(activeBackground.scale) || 100; const backgroundScale = Number(activeBackground.scale) || 100;
const backgroundUrl = JSON.stringify(activeBackground.url); const backgroundUrl = JSON.stringify(activeBackground.url);
const fitToScreen = options.fitImageToScreen === true; const fitToScreen = options.fitImageToScreen === true;
console.log("[CanvasRefined] Applying background:", activeBackground.url, "fitToScreen:", fitToScreen);
style.textContent = ` style.textContent = `
#wrapper { #wrapper {
background-image: url(${backgroundUrl}) !important; background-image: url(${backgroundUrl}) !important;
@ -1010,54 +1032,59 @@ function resetTimer() {
} }
function checkDashboardReady() { function checkDashboardReady() {
const callback = (mutationList) => { const isDashboard = () => current_page == "/" || current_page == "" || /^\/courses\/(\d+)(?:\/|$)/.test(current_page);
for (const mutation of mutationList) {
if (mutation.type !== "childList") continue;
if (current_page == "/" || current_page == "" || current_page.match(/^\/courses\/(\d+)(?:\/|$)/)) {
if (dashboardReadyTimer) continue;
const dashboardCards = document.querySelector("#DashboardCard_Container"); const callback = (mutationList) => {
if (dashboardCards) { // Ignore attribute-only mutations; only structural (childList) changes matter here.
let hasChildList = false;
for (const mutation of mutationList) {
if (mutation.type === "childList") { hasChildList = true; break; }
}
if (!hasChildList) return;
if (isDashboard()) {
// Debounce: a single setup pass per burst of mutations.
if (dashboardReadyTimer) return;
dashboardReadyTimer = setTimeout(() => {
dashboardReadyTimer = null;
const c = document.querySelector("#DashboardCard_Container");
if (c) {
let cards = document.querySelectorAll(".ic-DashboardCard");
changeGradientCards();
setupCardAssignments();
loadCardAssignments();
customizeCards(cards);
insertGrades();
loadDashboardNotes();
setupGPACalc();
showUpdateMsg();
createNasaInfoOverlay();
} }
dashboardReadyTimer = setTimeout(() => { const rightSide = document.querySelector("#right-side");
dashboardReadyTimer = null; if (rightSide && !rightSide.querySelector(".canvasrefined-todosidebar")) {
setupBetterTodo();
setupBetterSidebar(getSidebarLayoutMode());
}
const c = document.querySelector("#DashboardCard_Container");
if (c) {
let cards = document.querySelectorAll(".ic-DashboardCard");
changeGradientCards();
setupCardAssignments();
loadCardAssignments();
customizeCards(cards);
insertGrades();
loadDashboardNotes();
setupGPACalc();
showUpdateMsg();
createNasaInfoOverlay();
}
const rightSide = document.querySelector("#right-side");
if (rightSide && !rightSide.querySelector(".canvasrefined-todosidebar")) {
setupBetterTodo();
setupBetterSidebar(getSidebarLayoutMode());
}
if (options.better_sidebar) {
ensureBetterSidebar();
}
}, 0);
} else {
console.log("I am outside", current_page);
if (options.better_sidebar) { if (options.better_sidebar) {
ensureBetterSidebar(); ensureBetterSidebar();
} }
} }, 0);
} else if (options.better_sidebar) {
// Throttle sidebar setup checks on non-dashboard (course) pages instead
// of calling ensureBetterSidebar() on every mutation burst.
if (sidebarReadyTimer) return;
sidebarReadyTimer = setTimeout(() => {
sidebarReadyTimer = null;
ensureBetterSidebar();
}, 100);
} }
}; };
const observer = new MutationObserver(callback); const observer = new MutationObserver(callback);
observer.observe(document.querySelector('html'), { childList: true, subtree: true }); observer.observe(document.documentElement, { childList: true, subtree: true });
} }
function recieveMessage(request, sender, sendResponse) { function recieveMessage(request, sender, sendResponse) {
@ -3759,18 +3786,17 @@ let darkStyleInserted = false;
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;
if (!darkStyleInserted) { // Reuse the existing #darkcss style if present (never create a duplicate), so a
let style = document.createElement('style'); // document_start dark-mode bootstrap and later updates stay on one element.
style.textContent = css; let style = document.querySelector("#darkcss");
document.documentElement.append(style); if (!style) {
style = document.createElement('style');
style.id = 'darkcss'; style.id = 'darkcss';
style.className = darkOn ? "canvasrefined-darkmode-enabled" : ""; document.documentElement.append(style);
darkStyleInserted = true;
} else {
let style = document.querySelector("#darkcss");
style.textContent = css;
style.className = darkOn ? "canvasrefined-darkmode-enabled" : "";
} }
style.textContent = css;
style.className = darkOn ? "canvasrefined-darkmode-enabled" : "";
darkStyleInserted = true;
runiframeChecker(); runiframeChecker();
} }
@ -3801,6 +3827,9 @@ function autoDarkModeCheck() {
status = currentHour > startHour && currentHour < endHour; status = currentHour > startHour && currentHour < endHour;
} }
if (options.auto_dark === true) { if (options.auto_dark === true) {
// Skip the write (and the storage.onChanged cascade it would trigger) when the
// computed state already matches dark_mode, so the 60s timer is a cheap no-op.
if (status === options.dark_mode) return;
options.dark_mode = status; options.dark_mode = status;
chrome.storage.sync.set({ "dark_mode": status }, toggleDarkMode); chrome.storage.sync.set({ "dark_mode": status }, toggleDarkMode);
} }
@ -3834,19 +3863,27 @@ function runiframeChecker() {
const callback = (mutationList) => { const callback = (mutationList) => {
for (const mutation of mutationList) { for (const mutation of mutationList) {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0 && mutation.addedNodes[0].nodeName == "IFRAME") { if (mutation.type !== 'childList' || !mutation.addedNodes.length) continue;
const frame = mutation.addedNodes[0]; for (const node of mutation.addedNodes) {
const new_style_element = document.createElement("style"); if (node.nodeName !== 'IFRAME') continue;
new_style_element.textContent = generateDarkModeCSS(); // Cross-origin iframes expose no contentDocument; access it safely so we
new_style_element.id = "darkcss"; // don't throw a TypeError into the console on every added iframe.
frame.contentDocument.body.classList.add("canvasrefined--darkmode--enabled"); let doc;
frame.contentDocument.documentElement.prepend(new_style_element); try { doc = node.contentDocument; } catch (_) { continue; }
if (!doc || !doc.documentElement || !doc.body) continue;
try {
const new_style_element = document.createElement("style");
new_style_element.textContent = generateDarkModeCSS();
new_style_element.id = "darkcss";
doc.body.classList.add("canvasrefined--darkmode--enabled");
doc.documentElement.prepend(new_style_element);
} catch (_) { /* cross-origin or detached frame: ignore */ }
} }
} }
}; };
iframeObserver = new MutationObserver(callback); iframeObserver = new MutationObserver(callback);
iframeObserver.observe(document.querySelector('html'), { childList: true, subtree: true }); iframeObserver.observe(document.documentElement, { childList: true, subtree: true });
} }
/* /*

53638
lighthouseReport.json Normal file

File diff suppressed because one or more lines are too long