mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 09:11:06 +00:00
feat: final fixes and chores
This commit is contained in:
@@ -1469,6 +1469,35 @@ html.transparencyEffects
|
|||||||
color: var(--text-primary) !important;
|
color: var(--text-primary) !important;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Engage lesson/course Lexical editor ships inline light-mode colours on canvas + text nodes.
|
||||||
|
[class*="Canvas__canvas___"] {
|
||||||
|
background-color: transparent !important;
|
||||||
|
background-image: none !important;
|
||||||
|
color: var(--text-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="LexicalEditor__editor-container___"],
|
||||||
|
[class*="LexicalEditor__editor-inner___"],
|
||||||
|
[class*="LexicalEditor__editor-input___"],
|
||||||
|
[class*="LexicalEditor__editor-paragraph___"],
|
||||||
|
[class*="LexicalEditor__editor-text-bold___"],
|
||||||
|
[class*="LexicalEditor__editor-text-italic___"],
|
||||||
|
[class*="LexicalEditor__editor-text-underline___"],
|
||||||
|
[class*="TextModuleBody__lexicalEditor___"] {
|
||||||
|
color: var(--text-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="Module__module___"],
|
||||||
|
[class*="Module__content___"] {
|
||||||
|
background: transparent !important;
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark [class*="LexicalEditor__editor-input___"] img[data-lexical-decorator] {
|
||||||
|
filter: invert(1) hue-rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
.course .composer {
|
.course .composer {
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
Binary file not shown.
@@ -128,8 +128,8 @@ function onCustomSidebarCaptureClick(event: MouseEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const key = li.dataset.key;
|
const key = li.dataset.key;
|
||||||
if (!key) return;
|
const path = li.dataset.path;
|
||||||
const item = sidebarState.findByKey(key);
|
const item = sidebarState.resolveItem(key, path);
|
||||||
if (item) sidebarState.activateItem(item, menuEl);
|
if (item) sidebarState.activateItem(item, menuEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
* @jest-environment jsdom
|
* @jest-environment jsdom
|
||||||
*/
|
*/
|
||||||
import { getPagePathFromHash, parseNativeMenu } from "./parseNativeMenu";
|
import {
|
||||||
|
findNativeMenuEntry,
|
||||||
|
getPagePathFromHash,
|
||||||
|
parseNativeMenu,
|
||||||
|
} from "./parseNativeMenu";
|
||||||
|
|
||||||
describe("parseNativeMenu", () => {
|
describe("parseNativeMenu", () => {
|
||||||
it("parses top-level items and nested folders", () => {
|
it("parses top-level items and nested folders", () => {
|
||||||
@@ -67,4 +71,46 @@ describe("parseNativeMenu", () => {
|
|||||||
|
|
||||||
expect(items.map((i) => i.key)).toEqual(["home"]);
|
expect(items.map((i) => i.key)).toEqual(["home"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("findNativeMenuEntry prefers path over duplicate data-key", () => {
|
||||||
|
document.body.innerHTML = `
|
||||||
|
<div id="menu">
|
||||||
|
<ul>
|
||||||
|
<li class="item hasChildren" data-key="courses" data-path="/courses">
|
||||||
|
<label>Courses</label>
|
||||||
|
<div class="sub"><ul>
|
||||||
|
<li class="item hasChildren" data-key="4804:11066">
|
||||||
|
<label>English</label>
|
||||||
|
<div class="sub"><ul>
|
||||||
|
<li class="item" data-key="4804:11066" data-path="/courses/4804:11066">
|
||||||
|
<label>Course</label>
|
||||||
|
</li>
|
||||||
|
<li class="item" data-key="4804:11066" data-path="/assessments/4804:11066">
|
||||||
|
<label>Assessments</label>
|
||||||
|
</li>
|
||||||
|
</ul></div>
|
||||||
|
</li>
|
||||||
|
</ul></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const menu = document.getElementById("menu")!;
|
||||||
|
const course = findNativeMenuEntry(menu, {
|
||||||
|
key: "4804:11066",
|
||||||
|
id: null,
|
||||||
|
path: "/courses/4804:11066",
|
||||||
|
label: "Course",
|
||||||
|
});
|
||||||
|
const assessments = findNativeMenuEntry(menu, {
|
||||||
|
key: "4804:11066",
|
||||||
|
id: null,
|
||||||
|
path: "/assessments/4804:11066",
|
||||||
|
label: "Assessments",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(course?.dataset.path).toBe("/courses/4804:11066");
|
||||||
|
expect(assessments?.dataset.path).toBe("/assessments/4804:11066");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,13 +97,6 @@ export function findNativeMenuEntry(
|
|||||||
if (byId instanceof HTMLElement) return byId;
|
if (byId instanceof HTMLElement) return byId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.key) {
|
|
||||||
const byKey = list.querySelector(
|
|
||||||
`li[data-key="${CSS.escape(item.key)}"], section[data-key="${CSS.escape(item.key)}"]`,
|
|
||||||
);
|
|
||||||
if (byKey instanceof HTMLElement) return byKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.path) {
|
if (item.path) {
|
||||||
const byPath = list.querySelector(
|
const byPath = list.querySelector(
|
||||||
`li[data-path="${CSS.escape(item.path)}"], section[data-path="${CSS.escape(item.path)}"]`,
|
`li[data-path="${CSS.escape(item.path)}"], section[data-path="${CSS.escape(item.path)}"]`,
|
||||||
@@ -111,6 +104,13 @@ export function findNativeMenuEntry(
|
|||||||
if (byPath instanceof HTMLElement) return byPath;
|
if (byPath instanceof HTMLElement) return byPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.key) {
|
||||||
|
const byKey = list.querySelector(
|
||||||
|
`li[data-key="${CSS.escape(item.key)}"], section[data-key="${CSS.escape(item.key)}"]`,
|
||||||
|
);
|
||||||
|
if (byKey instanceof HTMLElement) return byKey;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.label) {
|
if (item.label) {
|
||||||
const candidates = list.querySelectorAll<HTMLElement>(
|
const candidates = list.querySelectorAll<HTMLElement>(
|
||||||
"li.item, section.item",
|
"li.item, section.item",
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ export function clearNativeDrillActive(menu: HTMLElement) {
|
|||||||
.forEach((node) => node.classList.remove("active"));
|
.forEach((node) => node.classList.remove("active"));
|
||||||
}
|
}
|
||||||
|
|
||||||
function findItemByPath(
|
export function findItemByPath(
|
||||||
items: SidebarItem[],
|
items: SidebarItem[],
|
||||||
path: string,
|
path: string,
|
||||||
): SidebarItem | null {
|
): SidebarItem | null {
|
||||||
@@ -119,14 +119,14 @@ function findItemByPath(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findItemByKey(
|
function findItemByKeyInList(
|
||||||
items: SidebarItem[],
|
items: SidebarItem[],
|
||||||
key: string,
|
key: string,
|
||||||
): SidebarItem | null {
|
): SidebarItem | null {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
if (item.key === key) return item;
|
if (item.key === key) return item;
|
||||||
if (item.children.length) {
|
if (item.children.length) {
|
||||||
const nested = findItemByKey(item.children, key);
|
const nested = findItemByKeyInList(item.children, key);
|
||||||
if (nested) return nested;
|
if (nested) return nested;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -383,7 +383,24 @@ class SidebarState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findByKey(key: string) {
|
findByKey(key: string) {
|
||||||
return findItemByKey(this.items, key);
|
for (let i = this.drillStack.length - 1; i >= 0; i--) {
|
||||||
|
const hit = this.drillStack[i].items.find((item) => item.key === key);
|
||||||
|
if (hit) return hit;
|
||||||
|
}
|
||||||
|
return findItemByKeyInList(this.items, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
findByPath(path: string) {
|
||||||
|
return findItemByPath(this.items, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveItem(key: string | undefined, path: string | undefined) {
|
||||||
|
if (path) {
|
||||||
|
const byPath = this.findByPath(path);
|
||||||
|
if (byPath) return byPath;
|
||||||
|
}
|
||||||
|
if (key) return this.findByKey(key);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ export type WhatsNewRelease = {
|
|||||||
|
|
||||||
export const WHATS_NEW_CHANGELOG: WhatsNewRelease[] = [
|
export const WHATS_NEW_CHANGELOG: WhatsNewRelease[] = [
|
||||||
{
|
{
|
||||||
"title": "3.7.3 – Timetable sync into Calendars, Sidebar Customisation & Bugfix Bundle",
|
"title": "3.7.3 – Timetable sync into Calendars, Sidebar Customisation, new loading animations & Bugfix Bundle",
|
||||||
"items": [
|
"items": [
|
||||||
|
"Added a few new loading screens you will see when opening SEQTA with BetterSEQTA",
|
||||||
"Added an option in the Timetable to sync to Google Calendar and Outlook Calendar",
|
"Added an option in the Timetable to sync to Google Calendar and Outlook Calendar",
|
||||||
"Added a new sidebar customisation page in the settings menu to change the sidebar layout, icons, and more.",
|
"Added a new sidebar customisation page in the settings menu to change the sidebar layout, icons, and more.",
|
||||||
"Added extension feedback in settings.",
|
"Added extension feedback in settings.",
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
import { __resetBrowserStorageMock } from "./mocks/webextension-polyfill";
|
import { __resetBrowserStorageMock } from "./mocks/webextension-polyfill";
|
||||||
|
|
||||||
|
if (typeof globalThis.CSS === "undefined") {
|
||||||
|
Object.defineProperty(globalThis, "CSS", {
|
||||||
|
value: {
|
||||||
|
escape(value: string) {
|
||||||
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
__resetBrowserStorageMock();
|
__resetBrowserStorageMock();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user