feat: add task-manager workspace layout

This commit is contained in:
2026-07-21 00:54:46 +09:00
parent 4a54977341
commit f1fe65ebe4
7 changed files with 859 additions and 72 deletions

View File

@@ -190,6 +190,47 @@ async function readShell() {
const element = document.getElementById(id);
return element ? { present: true, disabled: element.disabled === true, text: element.textContent.trim() } : { present: false };
};
const rectangle = element => {
if (!element) return null;
const bounds = element.getBoundingClientRect();
const style = getComputedStyle(element);
return {
left: bounds.left,
top: bounds.top,
right: bounds.right,
bottom: bounds.bottom,
width: bounds.width,
height: bounds.height,
display: style.display,
visibility: style.visibility
};
};
const isVisible = (element, bounds) => Boolean(element && bounds &&
element.hidden !== true && !element.closest("[hidden]") &&
bounds.width > 0 && bounds.height > 0 &&
bounds.right > 0 && bounds.bottom > 0 &&
bounds.left < document.documentElement.clientWidth &&
bounds.top < document.documentElement.clientHeight &&
bounds.display !== "none" && bounds.visibility !== "hidden");
const workspaceRegion = document.getElementById("workspace-region");
const navigationToggle = document.getElementById("workspace-nav-toggle");
const stockTab = document.getElementById("workspace-stock-tab");
const catalogTab = document.getElementById("workspace-catalog-tab");
const stockWorkspace = document.getElementById("stock-workspace");
const catalogWorkspace = document.getElementById("catalog-workspace");
const schedule = document.querySelector(".playlist-panel");
const workspaceBounds = rectangle(workspaceRegion);
const scheduleBounds = rectangle(schedule);
const scheduleCenter = scheduleBounds ? {
x: scheduleBounds.left + scheduleBounds.width / 2,
y: scheduleBounds.top + scheduleBounds.height / 2
} : null;
const scheduleHit = scheduleCenter &&
scheduleCenter.x >= 0 && scheduleCenter.y >= 0 &&
scheduleCenter.x < document.documentElement.clientWidth &&
scheduleCenter.y < document.documentElement.clientHeight
? document.elementFromPoint(scheduleCenter.x, scheduleCenter.y)
: null;
return {
url: location.href,
readyState: document.readyState,
@@ -204,6 +245,28 @@ async function readShell() {
next: button("playout-next"),
takeOut: button("playout-take-out")
},
layout: {
activeWorkspace: workspaceRegion?.dataset?.activeWorkspace || null,
navigationExpanded: navigationToggle?.getAttribute("aria-expanded") === "true" &&
workspaceRegion?.classList.contains("nav-collapsed") !== true,
stockTabCurrent: stockTab?.getAttribute("aria-current") || null,
catalogTabCurrent: catalogTab?.getAttribute("aria-current") || null,
stockWorkspaceVisible: isVisible(stockWorkspace, rectangle(stockWorkspace)) &&
stockWorkspace?.getAttribute("aria-hidden") === "false" &&
stockWorkspace?.hasAttribute("inert") !== true,
catalogWorkspaceHidden: catalogWorkspace?.hidden === true &&
catalogWorkspace?.getAttribute("aria-hidden") === "true" &&
catalogWorkspace?.hasAttribute("inert") === true,
workspace: workspaceBounds,
schedule: scheduleBounds,
workspaceToScheduleWidthRatio: workspaceBounds && scheduleBounds &&
scheduleBounds.width > 0
? workspaceBounds.width / scheduleBounds.width
: null,
scheduleVisible: isVisible(schedule, scheduleBounds),
scheduleHitTestVisible: Boolean(scheduleHit &&
(scheduleHit === schedule || schedule?.contains(scheduleHit)))
},
visibleDialogs: Array.from(document.querySelectorAll("[role='dialog'], [role='alertdialog']"))
.filter(element => !element.hidden && !element.closest("[hidden]")).map(element => element.id || element.getAttribute("aria-label") || "dialog"),
postMessageGuardInstalled: window.chrome?.webview?.postMessage === probe?.wrapper,
@@ -220,6 +283,19 @@ function assertShell(shell) {
shell.postMessageGuardInstalled !== true || shell.observedMessagesAfterGuard.length !== 0 || shell.blockedMessages.length !== 0) {
fail("KNOWN_FAILURE", "The package shell did not remain rendered DryRun/IDLE with zero guarded native intents.");
}
const layout = shell.layout;
if (!layout || layout.activeWorkspace !== "stock" ||
layout.navigationExpanded !== true ||
layout.stockTabCurrent !== "page" || layout.catalogTabCurrent !== "false" ||
layout.stockWorkspaceVisible !== true || layout.catalogWorkspaceHidden !== true) {
fail("KNOWN_FAILURE", "The package did not render the expanded navigation with stock as the sole initial workspace.");
}
if (layout.scheduleVisible !== true || layout.scheduleHitTestVisible !== true ||
!Number.isFinite(layout.workspaceToScheduleWidthRatio) ||
layout.workspaceToScheduleWidthRatio < 1.8 ||
layout.workspaceToScheduleWidthRatio > 2.2) {
fail("KNOWN_FAILURE", "The package did not render a visible right schedule beside the approximately 2:1 workspace layout.");
}
for (const [name, control] of Object.entries(shell.controls || {})) {
if (!control?.present) fail("KNOWN_FAILURE", `Required shell control ${name} is missing.`);
}