- 까닭 = 패널을 세운 뒤 단추 줄을 붙이는 화면은 쪼갬 · [?] [<] [>] 자리를 못 찾음 - 고침 = 공용 좌측 패널이 단추 줄이 붙는 때를 지켜보다 한 번 쪼갬 · 붙으면 지켜보기 끊음 - 시험 = 늦게 붙인 줄 · 먼저 붙인 줄 [?] 한 벌(새) · 280-2 헬퍼 대역에 538-3 고침 모듈 더함(낡음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
142 lines
4.1 KiB
JavaScript
142 lines
4.1 KiB
JavaScript
/* 요구 359-2 · 360-2 — 좌측 패널 [?] 자리. `ui_template_overlay.ts` 를 트랜스파일해 가짜 DOM 위에서
|
|
* 액션 줄을 ① 패널 세우기 전(E05 꼴) ② 세운 뒤(E03 · E04 · E06 · E07 꼴)에 붙여 쪼갬 · [?] 를 JSON 한 벌로 냄.
|
|
*/
|
|
const path = require("path");
|
|
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
|
|
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
|
|
class FakeNode {
|
|
constructor(tag) {
|
|
this.tagName = tag;
|
|
this.children = [];
|
|
this.parent = null;
|
|
this.style = {};
|
|
this._classes = new Set();
|
|
const self = this;
|
|
this.classList = {
|
|
add: (...n) => n.forEach((x) => self._classes.add(x)),
|
|
remove: (...n) => n.forEach((x) => self._classes.delete(x)),
|
|
toggle: (n, f) =>
|
|
(f === undefined ? !self._classes.has(n) : !!f)
|
|
? self._classes.add(n)
|
|
: self._classes.delete(n),
|
|
contains: (n) => self._classes.has(n),
|
|
};
|
|
}
|
|
set className(v) {
|
|
this._classes = new Set(String(v).split(/\s+/).filter(Boolean));
|
|
}
|
|
get className() {
|
|
return [...this._classes].join(" ");
|
|
}
|
|
get parentElement() {
|
|
return this.parent;
|
|
}
|
|
get firstChild() {
|
|
return this.children[0] ?? null;
|
|
}
|
|
get childElementCount() {
|
|
return this.children.length;
|
|
}
|
|
_adopt(kid) {
|
|
if (kid.parent) kid.parent.children = kid.parent.children.filter((c) => c !== kid);
|
|
kid.parent = this;
|
|
return kid;
|
|
}
|
|
append(...kids) {
|
|
kids.forEach((k) => this.children.push(this._adopt(k)));
|
|
mutated();
|
|
}
|
|
prepend(...kids) {
|
|
this.children.unshift(...kids.map((k) => this._adopt(k)));
|
|
mutated();
|
|
}
|
|
setAttribute() {}
|
|
addEventListener() {}
|
|
querySelector(selector) {
|
|
const cls = selector.slice(1);
|
|
let hit = null;
|
|
const walk = (n) =>
|
|
n.children.forEach((k) => {
|
|
if (!hit && k._classes.has(cls)) hit = k;
|
|
if (!hit) walk(k);
|
|
});
|
|
walk(this);
|
|
return hit;
|
|
}
|
|
}
|
|
// 진짜 MutationObserver 처럼 바뀐 뒤 한꺼번에 — `flush()` 가 부름(지켜보는 것만 · 끊으면 안 부름)
|
|
const observers = new Set();
|
|
let dirty = false;
|
|
function mutated() {
|
|
dirty = true;
|
|
}
|
|
function flush() {
|
|
while (dirty) {
|
|
dirty = false;
|
|
[...observers].forEach((o) => o.cb());
|
|
}
|
|
}
|
|
globalThis.MutationObserver = class {
|
|
constructor(cb) {
|
|
this.cb = cb;
|
|
}
|
|
observe() {
|
|
observers.add(this);
|
|
}
|
|
disconnect() {
|
|
observers.delete(this);
|
|
}
|
|
};
|
|
globalThis.document = { createElement: (tag) => new FakeNode(tag) };
|
|
globalThis.window = { innerWidth: 1600 };
|
|
|
|
const { loadTs } = makeLoader({
|
|
root: ROOT,
|
|
stubs: {
|
|
"./ui_template_locale": { t: (key) => key },
|
|
"./ui_template_help": {
|
|
placeHelpButton: (actions) => {
|
|
const button = new FakeNode("button");
|
|
button.className = "ui-help-btn";
|
|
actions.prepend(button);
|
|
},
|
|
},
|
|
"./ui_template_overlay_drag": { makePanelDraggable: () => ({ refresh() {} }) },
|
|
"/b_workflow_nav": { fetchWorkflowState: async () => ({}) },
|
|
"/b_page_state": { readByKey: () => null, writeByKey: () => undefined },
|
|
"/device_context": { SIZE_BREAKS: { expanded: 840 } },
|
|
},
|
|
});
|
|
const overlay = loadTs(path.join(ROOT, "ui_template", "ui_template_overlay.ts"));
|
|
|
|
function mount(late) {
|
|
const panel = new FakeNode("div");
|
|
const actions = new FakeNode("div");
|
|
actions.className = "ui-sidebar-actions";
|
|
panel.append(new FakeNode("p"));
|
|
if (!late) panel.append(actions);
|
|
const { root } = overlay.createWorkflowOverlays({
|
|
title: "t",
|
|
optionsContent: panel,
|
|
showProjectName: false,
|
|
});
|
|
const before = !!actions.querySelector(".ui-help-btn");
|
|
if (late) panel.append(actions);
|
|
flush();
|
|
const body = root.querySelector(".ui-workflow-overlay__body");
|
|
return {
|
|
before,
|
|
help: actions.querySelector(".ui-help-btn") ? 1 : 0,
|
|
split: body.classList.contains("ui-sidebar-split"),
|
|
scroll: !!panel.querySelector(".ui-sidebar-scroll"),
|
|
lastIsActions: panel.children[panel.children.length - 1] === actions,
|
|
watching: observers.size,
|
|
};
|
|
}
|
|
|
|
const early = mount(false);
|
|
const late = mount(true);
|
|
process.stdout.write(JSON.stringify({ early, late }));
|