- spreadsheet.ts — `inspect` 선택이면 문맥을 window.__aisloSheet 에 걺(M02 [스프레드시트 시험] 단추 전용 · destroy 때 뗌 · 1단계 검증 뒤 지움) - 시험 틀 — ssScenario()(페이지 안 한 번에 한글 · 가리키기 · 재계산 · 되돌리기 · Delete · Ctrl+Enter · 수식 입력줄 · F2) · 가짜 격자 data-addr · 진짜 분수 값 보임 · 오류 모음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6KXAabDTenEU7hrDQmCKY
126 lines
4.5 KiB
JavaScript
126 lines
4.5 KiB
JavaScript
/* 스프레드시트 D 화면 시험 틀 입구 — 견본 통합문서를 띄우고 window.ss* 로 수치를 꺼냄(ORCA eval).
|
|
* 번들: node helper_spreadsheet_d_bundle.cjs harness → tmp/spreadsheet_d/harness.js */
|
|
const { createSpreadsheet } = require("../../../A00_Common/spreadsheet/spreadsheet");
|
|
const sample = require("../../../A00_Common/spreadsheet/spreadsheet_sample.json");
|
|
|
|
const host = document.getElementById("host");
|
|
window.ssSelect = null;
|
|
window.ssChanges = 0;
|
|
window.ssSample = JSON.parse(JSON.stringify(sample));
|
|
window.ss = createSpreadsheet(host, JSON.parse(JSON.stringify(sample)), {
|
|
onChange: () => window.ssChanges++,
|
|
onSelect: (s) => (window.ssSelect = s),
|
|
inspect: true,
|
|
});
|
|
window.ssCreate = createSpreadsheet;
|
|
/** 칸 입력 값(A1) */
|
|
window.ssCell = (a1, sheet = "s1") =>
|
|
window.ss.getDoc().시트.find((s) => s.id === sheet).칸[a1] ?? null;
|
|
|
|
/* 한 번에 도는 시나리오 — 탭이 새로 읽혀도 끊기지 않게 페이지 안에서 합성 사건으로 조작하고 수치를 모음.
|
|
* (믿음 입력 — 진짜 키 · 마우스 · 한글 — 은 ORCA keypress · type · mouse 로 따로 잼) */
|
|
window.ssScenario = () => {
|
|
const ta = () => document.querySelector(".ss-input");
|
|
const at = (a1) => {
|
|
const d = document.querySelector(`[data-a1="${a1}"]`).getBoundingClientRect();
|
|
return {
|
|
clientX: d.left + d.width / 2,
|
|
clientY: d.top + d.height / 2,
|
|
bubbles: true,
|
|
button: 0,
|
|
};
|
|
};
|
|
const grid = () => document.querySelector(".ss-grid-host");
|
|
const click = (a1, extra = {}) => {
|
|
grid().dispatchEvent(new MouseEvent("mousedown", { ...at(a1), ...extra }));
|
|
window.dispatchEvent(new MouseEvent("mouseup", at(a1)));
|
|
};
|
|
const dragTo = (from, to) => {
|
|
grid().dispatchEvent(new MouseEvent("mousedown", from));
|
|
window.dispatchEvent(new MouseEvent("mousemove", to));
|
|
window.dispatchEvent(new MouseEvent("mouseup", to));
|
|
};
|
|
const key = (k, o = {}) =>
|
|
document.activeElement.dispatchEvent(
|
|
new KeyboardEvent("keydown", { key: k, bubbles: true, cancelable: true, ...o }),
|
|
);
|
|
const type = (text) => {
|
|
const t = document.activeElement;
|
|
t.setRangeText(text, t.selectionStart, t.selectionEnd, "end");
|
|
t.dispatchEvent(new Event("input", { bubbles: true }));
|
|
};
|
|
const shown = (a1) => document.querySelector(`[data-a1="${a1}"]`).textContent;
|
|
const sel = () => `${ssSelect.칸}|${ssSelect.범위}`;
|
|
const out = {};
|
|
// 한글 첫 글자 — compositionstart 로 편집 시작 · 같은 textarea 그대로
|
|
click("L2");
|
|
ta().dispatchEvent(new CompositionEvent("compositionstart", { data: "" }));
|
|
out.imeEditing =
|
|
document.querySelector(".ss").classList.contains("ss--editing") &&
|
|
document.activeElement === ta();
|
|
type("한");
|
|
key("Enter");
|
|
out.ime = [ssCell("L2"), sel()];
|
|
// 수 · 식 · 참조 가리키기(방향키 + 누르기) · 재계산
|
|
click("L3");
|
|
type("2");
|
|
key("Enter");
|
|
type("=");
|
|
key("ArrowUp");
|
|
out.pointKey = ta().value;
|
|
type("*");
|
|
click("J5");
|
|
out.pointClick = [
|
|
ta().value,
|
|
[...document.querySelectorAll(".fg-ref")].map((x) => x.dataset.ref),
|
|
];
|
|
key("Enter");
|
|
out.calc = [ssCell("L4"), shown("L4")];
|
|
click("L3");
|
|
type("5");
|
|
key("Enter");
|
|
out.recalc = shown("L4");
|
|
// 되돌리기 · 다시
|
|
key("z", { ctrlKey: true });
|
|
out.undo = [ssCell("L3"), shown("L4")];
|
|
key("y", { ctrlKey: true });
|
|
out.redo = [ssCell("L3"), shown("L4")];
|
|
// Delete(서식 남김) · 되돌림
|
|
click("B4");
|
|
key("Delete");
|
|
out.del = ssCell("B4");
|
|
key("z", { ctrlKey: true });
|
|
out.delUndo = ssCell("B4");
|
|
// 병합 · Shift/Ctrl 방향
|
|
click("A4");
|
|
key("ArrowRight", { shiftKey: true });
|
|
key("ArrowRight", { shiftKey: true });
|
|
out.shift = sel();
|
|
click("A3");
|
|
key("ArrowDown", { ctrlKey: true });
|
|
out.ctrl = sel();
|
|
// 끌어 고르기 · Ctrl+Enter
|
|
dragTo(at("P2"), at("Q3"));
|
|
out.drag = sel();
|
|
type("=L3+1");
|
|
key("Enter", { ctrlKey: true });
|
|
out.ctrlEnter = ["P2", "Q2", "P3", "Q3"].map((k) => ssCell(k)?.식);
|
|
// 수식 입력줄로 고치기
|
|
click("N2");
|
|
const bar = document.querySelector(".ss-formula");
|
|
bar.focus();
|
|
bar.value = "=J4*10";
|
|
bar.dispatchEvent(new Event("input", { bubbles: true }));
|
|
key("Enter");
|
|
out.bar = [ssCell("N2"), shown("N2"), sel()];
|
|
// F2 — 방향키가 글자 자리만
|
|
click("N2");
|
|
key("F2");
|
|
const before = sel();
|
|
key("ArrowLeft");
|
|
out.f2 = [before === sel(), document.querySelector(".ss").classList.contains("ss--editing")];
|
|
key("Escape");
|
|
out.errors = window.ssErrors;
|
|
return JSON.stringify(out);
|
|
};
|