feat: consolidate legacy parity migration baseline

This commit is contained in:
2026-07-20 22:06:12 +09:00
parent 5eb4054120
commit 4a54977341
66 changed files with 5391 additions and 460 deletions

View File

@@ -23,6 +23,7 @@ test("legacy shell exposes the original stock, cut, playlist and playout control
"moving-average-5",
"moving-average-20",
"cut-list",
"cut-drag-feedback",
"playlist-drop-zone",
"playlist-rows",
"playlist-enable-all",
@@ -63,7 +64,8 @@ test("legacy stock double click is represented by pointer-down facts", () => {
assert.match(app, /event\.shiftKey/);
const cutFactory = app.slice(app.indexOf("function createCutElement"), app.indexOf("function renderCuts"));
assert.doesNotMatch(cutFactory, /dblclick/);
assert.match(cutFactory, /if \(playlistMutationLocked\) return/);
assert.match(cutFactory, /allowAppend: !playlistMutationLocked/);
assert.match(cutFactory, /if \(!playlistMutationLocked\)/);
assert.match(app, /send\("clear-cut-selection", \{\}\)/);
assert.match(app, /event\.target !== cutList/);
assert.match(app, /button\.addEventListener\("keydown"/);
@@ -80,12 +82,85 @@ test("cut rows are reconciled in place while the legacy pointer drag remains cap
assert.match(cutFactory, /addEventListener\("pointermove", onCutPointerMove\)/);
assert.match(cutFactory, /addEventListener\("lostpointercapture", onCutPointerCancel\)/);
assert.match(cutFactory, /const cutDragLocked = isOperatorMutationLocked\(state\)/);
assert.match(cutFactory, /!isCutSelectionLocked\(state\)/);
assert.match(cutFactory, /element\.draggable = false/);
assert.match(cutFactory, /dataset\.cutDragEnabled = cutSelectionEnabled/);
assert.match(cutFactory, /dataset\.cutDragEnabled = cutSelectionEnabled && !cutDragLocked/);
assert.doesNotMatch(cutFactory, /addEventListener\("dragstart"/);
assert.doesNotMatch(app, /cutList\.replaceChildren/);
});
test("program keeps cut selection active while append drag stays locked", () => {
const sourceStart = app.indexOf("function isCutSelectionLocked");
const sourceEnd = app.indexOf("function dragDropPosition", sourceStart);
assert.ok(sourceStart >= 0 && sourceEnd > sourceStart);
const isCutSelectionLocked = new Function(`
${app.slice(sourceStart, sourceEnd)}
return isCutSelectionLocked;
`)();
assert.equal(isCutSelectionLocked({
isBusy: false,
fixedSectionBatch: null,
playout: {
phase: "program",
isBusy: false,
outcomeUnknown: false,
isPlayCompletionPending: false,
isTakeOutCompletionPending: false
}
}), false);
assert.equal(isCutSelectionLocked({
isBusy: false,
fixedSectionBatch: null,
playout: {
phase: "program",
isBusy: true,
outcomeUnknown: false,
isPlayCompletionPending: false,
isTakeOutCompletionPending: false
}
}), true);
});
test("cut drag feedback follows the pointer and exposes allowed target state", () => {
const sourceStart = app.indexOf("function showCutDragFeedback");
const sourceEnd = app.indexOf("function beginCutDragGesture", sourceStart);
assert.ok(sourceStart >= 0 && sourceEnd > sourceStart);
const feedback = {
hidden: true,
dataset: {},
offsetWidth: 120,
offsetHeight: 30,
classList: {
values: new Set(),
toggle(name, enabled) {
if (enabled) this.values.add(name);
else this.values.delete(name);
}
},
style: {}
};
const show = new Function("cutDragFeedback", "document", `
${app.slice(sourceStart, sourceEnd)}
return showCutDragFeedback;
`)(feedback, { documentElement: { clientWidth: 800, clientHeight: 600 } });
show({ clientX: 100, clientY: 80 }, false);
assert.equal(feedback.hidden, false);
assert.equal(feedback.dataset.dropAllowed, "false");
assert.equal(feedback.style.left, "114px");
assert.equal(feedback.style.top, "94px");
assert.equal(feedback.classList.values.has("allowed"), false);
show({ clientX: 790, clientY: 590 }, true);
assert.equal(feedback.dataset.dropAllowed, "true");
assert.equal(feedback.style.left, "676px");
assert.equal(feedback.style.top, "566px");
assert.equal(feedback.classList.values.has("allowed"), true);
assert.match(styles, /\.cut-drag-feedback \{[^}]*pointer-events: none/);
assert.match(styles, /\.cut-drag-feedback\.allowed/);
});
test("state rendering preserves stock and playlist focus like native controls", () => {
assert.match(app, /dataset\.resultIndex/);
assert.match(app, /dataset\.rowId/);
@@ -1074,8 +1149,10 @@ test("UC1 tree render preserves state but resets Expand and first root on tab re
let renderedTreeTabId = null;
let treeInteractionLocked = false;
let treeFocusOwnedBeforeRender = false;
let themeResultClickTimer = null;
const treeUiStateByTab = new Map();
const pendingTreeResetTabs = new Set();
function clearDelayedClick() {}
${app.slice(helperStart, helperEnd)}
return { beginTreeRender, finishTreeRender, selectTreeNode };
`)(categoryTree, catalogExpandAll, document, { getActiveModal() { return null; } });
@@ -1444,7 +1521,7 @@ test("FSell and VI dialogs send opaque native intents and never own file or stoc
});
test("separator rows preserve the original drag gesture", () => {
assert.match(app, /element\.dataset\.cutDragEnabled = cutSelectionEnabled \? "true" : "false"/);
assert.match(app, /element\.dataset\.cutDragEnabled = cutSelectionEnabled && !cutDragLocked/);
assert.match(app, /element\.draggable = false/);
assert.doesNotMatch(app, /cutDragEnabled = !row\.isSeparator/);
});