- ui_template_native_menu.ts releaseSelectAfterPick — 창 캡처 pointerdown · keydown · change · 아직 그 select 에 초점일 때만 blur - 시험 test_280_6_select_release 새로 · 옛 가짜 import 두 헬퍼(282-1 · 224-1c)에 새 함수 흉내 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.9 KiB
JavaScript
77 lines
2.9 KiB
JavaScript
/* 280-6 드롭다운 초점 빼기(`ui_template/ui_template_native_menu.ts` `releaseSelectAfterPick`) 단위검증 헬퍼 —
|
|
* 그 자리에서 트랜스파일해 Node 로 돌리고 값을 JSON 으로 냄. 가짜 창 · 가짜 select · 가짜 타이머로 판정. */
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const ts = require(path.join(__dirname, "..", "..", "config", "node_modules", "typescript"));
|
|
|
|
const ROOT = path.join(__dirname, "..", "..");
|
|
const js = ts.transpileModule(
|
|
fs.readFileSync(path.join(ROOT, "ui_template", "ui_template_native_menu.ts"), "utf8"),
|
|
{ compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 } },
|
|
).outputText;
|
|
const box = { exports: {} };
|
|
new Function("exports", "module", "require", js)(box.exports, box, require);
|
|
const m = box.exports;
|
|
|
|
// 가짜 창 — 캡처 듣기 · 타이머(손으로 돌림) · 문서 하나
|
|
function setup() {
|
|
const listeners = [];
|
|
const timers = [];
|
|
const doc = { activeElement: null };
|
|
const win = {
|
|
addEventListener: (type, fn, capture) => listeners.push({ type, fn, capture }),
|
|
setTimeout: (fn) => timers.push(fn),
|
|
};
|
|
m.releaseSelectAfterPick(win);
|
|
const el = (tagName) => {
|
|
const node = { tagName, ownerDocument: doc, blurs: 0 };
|
|
node.blur = () => {
|
|
node.blurs += 1;
|
|
doc.activeElement = null;
|
|
};
|
|
return node;
|
|
};
|
|
const fire = (type, target) =>
|
|
listeners.filter((l) => l.type === type).forEach((l) => l.fn({ type, target }));
|
|
const tick = () => timers.splice(0).forEach((fn) => fn());
|
|
return { listeners, doc, el, fire, tick };
|
|
}
|
|
|
|
// 차례 하나 — 초점을 select 에 두고 입력들을 쏜 뒤 change · (처리) · 한 틱
|
|
function run(inputs, tag = "SELECT", moveFocus = false) {
|
|
const t = setup();
|
|
const target = t.el(tag);
|
|
t.doc.activeElement = target;
|
|
inputs.forEach((type) => t.fire(type, target));
|
|
t.fire("change", target);
|
|
const before = target.blurs; // 한 틱 전엔 안 뺌
|
|
if (moveFocus) t.doc.activeElement = t.el("INPUT");
|
|
t.tick();
|
|
return { before, blurs: target.blurs };
|
|
}
|
|
|
|
const src = (rel) => fs.readFileSync(path.join(ROOT, rel), "utf8");
|
|
const setupOnce = setup();
|
|
|
|
console.log(
|
|
JSON.stringify({
|
|
mouse: run(["pointerdown"]),
|
|
keyboard: run(["keydown"]),
|
|
none: run([]),
|
|
input: run(["pointerdown"], "INPUT"),
|
|
moved: run(["pointerdown"], "SELECT", true),
|
|
mouseThenKey: run(["pointerdown", "keydown"]),
|
|
keyThenMouse: run(["keydown", "pointerdown"]),
|
|
listeners: setupOnce.listeners.map((l) => [l.type, l.capture]),
|
|
wiring: {
|
|
main: /releaseSelectAfterPick\(window\)/.test(src("A00_Common/main.ts")),
|
|
cad: /releaseSelectAfterPick\(frame\.contentWindow\)/.test(
|
|
src("ui_template/cad_host/cad_host.ts"),
|
|
),
|
|
popout: /releaseSelectAfterPick\(next\)/.test(
|
|
src("A00_Common/design/design_profile_popout.ts"),
|
|
),
|
|
},
|
|
}),
|
|
);
|