mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 17:21:05 +00:00
feat: final fixes and chores
This commit is contained in:
@@ -128,8 +128,8 @@ function onCustomSidebarCaptureClick(event: MouseEvent) {
|
||||
}
|
||||
|
||||
const key = li.dataset.key;
|
||||
if (!key) return;
|
||||
const item = sidebarState.findByKey(key);
|
||||
const path = li.dataset.path;
|
||||
const item = sidebarState.resolveItem(key, path);
|
||||
if (item) sidebarState.activateItem(item, menuEl);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
import { getPagePathFromHash, parseNativeMenu } from "./parseNativeMenu";
|
||||
import {
|
||||
findNativeMenuEntry,
|
||||
getPagePathFromHash,
|
||||
parseNativeMenu,
|
||||
} from "./parseNativeMenu";
|
||||
|
||||
describe("parseNativeMenu", () => {
|
||||
it("parses top-level items and nested folders", () => {
|
||||
@@ -67,4 +71,46 @@ describe("parseNativeMenu", () => {
|
||||
|
||||
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 (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) {
|
||||
const byPath = list.querySelector(
|
||||
`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 (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) {
|
||||
const candidates = list.querySelectorAll<HTMLElement>(
|
||||
"li.item, section.item",
|
||||
|
||||
@@ -105,7 +105,7 @@ export function clearNativeDrillActive(menu: HTMLElement) {
|
||||
.forEach((node) => node.classList.remove("active"));
|
||||
}
|
||||
|
||||
function findItemByPath(
|
||||
export function findItemByPath(
|
||||
items: SidebarItem[],
|
||||
path: string,
|
||||
): SidebarItem | null {
|
||||
@@ -119,14 +119,14 @@ function findItemByPath(
|
||||
return null;
|
||||
}
|
||||
|
||||
function findItemByKey(
|
||||
function findItemByKeyInList(
|
||||
items: SidebarItem[],
|
||||
key: string,
|
||||
): SidebarItem | null {
|
||||
for (const item of items) {
|
||||
if (item.key === key) return item;
|
||||
if (item.children.length) {
|
||||
const nested = findItemByKey(item.children, key);
|
||||
const nested = findItemByKeyInList(item.children, key);
|
||||
if (nested) return nested;
|
||||
}
|
||||
}
|
||||
@@ -383,7 +383,24 @@ class SidebarState {
|
||||
}
|
||||
|
||||
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[] = [
|
||||
{
|
||||
"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": [
|
||||
"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 a new sidebar customisation page in the settings menu to change the sidebar layout, icons, and more.",
|
||||
"Added extension feedback in settings.",
|
||||
|
||||
Reference in New Issue
Block a user