feat: initialise Lildra browser extension

This commit is contained in:
git
2026-07-27 18:33:38 +10:00
commit e6e5336209
9 changed files with 240 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
(() => {
"use strict";
const VERSION = "0.2.3";
const ROOT_CLASS = "lildra-active";
const STYLE_ID = "lildra-layout-style";
const HEADER_ID = "lildra-page-header";
const FOOTER_ID = "lildra-product-footer";
function removeLildra() {
document.documentElement.classList.remove(ROOT_CLASS);
document.getElementById(STYLE_ID)?.remove();
document.getElementById(HEADER_ID)?.remove();
document.getElementById(FOOTER_ID)?.remove();
}
// Toggle off when run a second time.
if (document.documentElement.classList.contains(ROOT_CLASS)) {
removeLildra();
return;
}
function getPageTitle() {
const candidates = [
document.querySelector("#breadcrumbs [aria-current='page'] .ellipsible")?.textContent,
document.querySelector("#breadcrumbs [aria-current='page']")?.textContent,
document.querySelector(".mobile-header-title div:last-child")?.textContent,
document.querySelector("#wiki_page_show .page-title")?.textContent,
document.querySelector("#content h1.page-title")?.textContent
];
const found = candidates
.map((value) => value?.trim())
.find((value) => value && value.length > 0);
if (found) return found;
// Canvas document titles normally end with ": Course name".
const browserTitle = document.title.trim();
const separator = browserTitle.lastIndexOf(":");
return separator > 0 ? browserTitle.slice(0, separator).trim() : browserTitle;
}
const style = document.createElement("style");
style.id = STYLE_ID;
style.textContent = `
/* Hide Canvas/QLearn navigation only. */
html.${ROOT_CLASS} #header,
html.${ROOT_CLASS} #mobile-header,
html.${ROOT_CLASS} #mobileContextNavContainer,
html.${ROOT_CLASS} .ic-app-nav-toggle-and-crumbs,
html.${ROOT_CLASS} #left-side {
display: none !important;
}
/* Remove navigation offsets while keeping a normal, centred reading width. */
html.${ROOT_CLASS} #wrapper {
margin-left: 0 !important;
padding-top: 42px !important;
}
html.${ROOT_CLASS} body.primary-nav-expanded #wrapper,
html.${ROOT_CLASS} body.course-menu-expanded #wrapper,
html.${ROOT_CLASS} body.with-left-side #wrapper {
margin-left: 0 !important;
}
html.${ROOT_CLASS} #main {
display: block !important;
width: 100% !important;
max-width: none !important;
margin: 0 !important;
}
html.${ROOT_CLASS} #not_right_side {
display: block !important;
width: min(1100px, calc(100% - 32px)) !important;
max-width: 1100px !important;
margin: 0 auto !important;
float: none !important;
}
html.${ROOT_CLASS} #content-wrapper,
html.${ROOT_CLASS} #content {
width: 100% !important;
max-width: none !important;
margin-left: 0 !important;
margin-right: 0 !important;
}
/* Small fixed title bar. */
html.${ROOT_CLASS} #${HEADER_ID} {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 2147483646 !important;
box-sizing: border-box !important;
height: 42px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
padding: 0 18px !important;
margin: 0 !important;
overflow: hidden !important;
white-space: nowrap !important;
text-overflow: ellipsis !important;
text-align: center !important;
background: #ffffff !important;
border-bottom: 1px solid rgba(0, 0, 0, 0.14) !important;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07) !important;
color: #1d2733 !important;
font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif !important;
font-size: 16px !important;
font-weight: 700 !important;
line-height: 1 !important;
}
html.${ROOT_CLASS} #${FOOTER_ID} {
position: fixed !important;
right: 14px !important;
bottom: 9px !important;
z-index: 2147483646 !important;
padding: 4px 7px !important;
border-radius: 4px !important;
background: rgba(255, 255, 255, 0.9) !important;
color: #5f259f !important;
font-family: Lato, "Helvetica Neue", Helvetica, Arial, sans-serif !important;
font-size: 12px !important;
font-weight: 700 !important;
line-height: 1 !important;
pointer-events: none !important;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
}
@media (max-width: 700px) {
html.${ROOT_CLASS} #wrapper {
padding-top: 38px !important;
}
html.${ROOT_CLASS} #${HEADER_ID} {
height: 38px !important;
padding: 0 12px !important;
font-size: 14px !important;
}
}
`;
const header = document.createElement("div");
header.id = HEADER_ID;
header.setAttribute("role", "banner");
header.textContent = getPageTitle();
const footer = document.createElement("div");
footer.id = FOOTER_ID;
footer.textContent = `Lildra v${VERSION}`;
document.documentElement.appendChild(style);
document.body.appendChild(header);
document.body.appendChild(footer);
document.documentElement.classList.add(ROOT_CLASS);
})();