Files
Aislo/resources/tester/helper_180_3_b07_guide_toggle.cjs
T

102 lines
3.2 KiB
JavaScript

/* 180-3 B07 안내선 보이기 / 숨기기 단추 헬퍼 — `…_UI_GuideToggle.ts` 를 Node 로 돌려 JSON 한 벌로.
* 공용 단추(`ui_template_elements`)는 진짜 · 화면 그릇만 흉내(helper_153 꼴).
*/
const fs = require("fs");
const path = require("path");
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
const ROOT = path.join(__dirname, "..", "..");
const cache = new Map();
class FakeNode {
constructor(tag) {
this.tagName = tag.toUpperCase();
this.children = [];
this.dataset = {};
this.attrs = {};
this.listeners = {};
this._text = "";
this._classes = new Set();
this.disabled = false;
this.title = "";
const self = this;
this.classList = {
add: (...names) => names.forEach((n) => self._classes.add(n)),
contains: (name) => self._classes.has(name),
};
}
set className(value) {
this._classes = new Set(String(value).split(/\s+/).filter(Boolean));
}
get className() {
return [...this._classes].join(" ");
}
set textContent(value) {
this._text = String(value);
this.children = [];
}
get textContent() {
return this._text + this.children.map((c) => c.textContent).join("");
}
setAttribute(key, value) {
this.attrs[key] = String(value);
}
append(...kids) {
kids.forEach((k) => this.children.push(k));
}
addEventListener(type, handler) {
(this.listeners[type] ||= []).push(handler);
}
click() {
if (!this.disabled) (this.listeners.click || []).forEach((handler) => handler({}));
}
}
globalThis.document = { createElement: (tag) => new FakeNode(tag) };
function loadTs(file) {
const full = path.resolve(file);
if (cache.has(full)) return cache.get(full);
const js = ts.transpileModule(fs.readFileSync(full, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const box = { exports: {} };
cache.set(full, box.exports);
const localRequire = (request) => {
if (request === "@ui/ui_template_elements")
return loadTs(path.join(ROOT, "ui_template", "ui_template_elements.ts"));
if (request.startsWith(".")) {
const target = path.join(path.dirname(full), `${request}.ts`);
return fs.existsSync(target) ? loadTs(target) : {};
}
return {};
};
new Function("exports", "module", "require", js)(box.exports, box, localRequire);
cache.set(full, box.exports);
return box.exports;
}
const { buildGuideToggle, guideShown } = loadTs(
path.join(ROOT, "B07_DesignDetail", "B07_DesignDetail_UI_GuideToggle.ts"),
);
const sent = [];
const button = buildGuideToggle((visible) => sent.push(visible));
const view = () => ({
text: button.textContent,
cls: button.className,
pressed: button.attrs["aria-pressed"],
shown: guideShown(),
});
const out = { first: view() };
button.click();
out.hidden = view();
button.click();
out.again = view();
button.click();
out.last = view();
// 화면을 다시 세워 새 단추를 만들어도 숨김 유지(모듈 값)
const rebuilt = buildGuideToggle((visible) => sent.push(visible));
out.rebuilt = { text: rebuilt.textContent, pressed: rebuilt.attrs["aria-pressed"] };
out.sent = sent;
process.stdout.write(JSON.stringify(out));