@wasao/kagemusha 0.2.0 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +103 -453
  2. package/dist/commands/capture.js +57 -35
  3. package/dist/commands/capture.js.map +1 -1
  4. package/dist/commands/edit.d.ts +1 -1
  5. package/dist/commands/edit.d.ts.map +1 -1
  6. package/dist/commands/edit.js +46 -8
  7. package/dist/commands/edit.js.map +1 -1
  8. package/dist/commands/init.d.ts.map +1 -1
  9. package/dist/commands/init.js +82 -83
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/login.d.ts.map +1 -1
  12. package/dist/commands/login.js +14 -18
  13. package/dist/commands/login.js.map +1 -1
  14. package/dist/editor/inject-script/annotations.d.ts +11 -0
  15. package/dist/editor/inject-script/annotations.d.ts.map +1 -0
  16. package/dist/editor/inject-script/annotations.js +409 -0
  17. package/dist/editor/inject-script/annotations.js.map +1 -0
  18. package/dist/editor/inject-script/bridge.d.ts +13 -0
  19. package/dist/editor/inject-script/bridge.d.ts.map +1 -0
  20. package/dist/editor/inject-script/bridge.js +33 -0
  21. package/dist/editor/inject-script/bridge.js.map +1 -0
  22. package/dist/editor/inject-script/crop.d.ts +9 -0
  23. package/dist/editor/inject-script/crop.d.ts.map +1 -0
  24. package/dist/editor/inject-script/crop.js +236 -0
  25. package/dist/editor/inject-script/crop.js.map +1 -0
  26. package/dist/editor/inject-script/dom.d.ts +7 -0
  27. package/dist/editor/inject-script/dom.d.ts.map +1 -0
  28. package/dist/editor/inject-script/dom.js +32 -0
  29. package/dist/editor/inject-script/dom.js.map +1 -0
  30. package/dist/editor/inject-script/index.d.ts +2 -0
  31. package/dist/editor/inject-script/index.d.ts.map +1 -0
  32. package/dist/editor/inject-script/index.js +56 -0
  33. package/dist/editor/inject-script/index.js.map +1 -0
  34. package/dist/editor/inject-script/record.d.ts +5 -0
  35. package/dist/editor/inject-script/record.d.ts.map +1 -0
  36. package/dist/editor/inject-script/record.js +398 -0
  37. package/dist/editor/inject-script/record.js.map +1 -0
  38. package/dist/editor/inject-script/selector.d.ts +6 -0
  39. package/dist/editor/inject-script/selector.d.ts.map +1 -0
  40. package/dist/editor/inject-script/selector.js +112 -0
  41. package/dist/editor/inject-script/selector.js.map +1 -0
  42. package/dist/editor/inject-script/state.d.ts +27 -0
  43. package/dist/editor/inject-script/state.d.ts.map +1 -0
  44. package/dist/editor/inject-script/state.js +26 -0
  45. package/dist/editor/inject-script/state.js.map +1 -0
  46. package/dist/editor/inject-script/svg.d.ts +7 -0
  47. package/dist/editor/inject-script/svg.d.ts.map +1 -0
  48. package/dist/editor/inject-script/svg.js +39 -0
  49. package/dist/editor/inject-script/svg.js.map +1 -0
  50. package/dist/editor/inject-script/toolbar.d.ts +14 -0
  51. package/dist/editor/inject-script/toolbar.d.ts.map +1 -0
  52. package/dist/editor/inject-script/toolbar.js +240 -0
  53. package/dist/editor/inject-script/toolbar.js.map +1 -0
  54. package/dist/editor/inject-script/types.d.ts +102 -0
  55. package/dist/editor/inject-script/types.d.ts.map +1 -0
  56. package/dist/editor/inject-script/types.js +5 -0
  57. package/dist/editor/inject-script/types.js.map +1 -0
  58. package/dist/editor/inject-script.js +1248 -699
  59. package/dist/index.js +9 -2
  60. package/dist/index.js.map +1 -1
  61. package/dist/lib/canonical.d.ts +35 -3
  62. package/dist/lib/canonical.d.ts.map +1 -1
  63. package/dist/lib/canonical.js +85 -25
  64. package/dist/lib/canonical.js.map +1 -1
  65. package/dist/lib/crawl.js +1 -1
  66. package/dist/lib/crawl.js.map +1 -1
  67. package/dist/lib/diff.d.ts +23 -4
  68. package/dist/lib/diff.d.ts.map +1 -1
  69. package/dist/lib/diff.js +5 -6
  70. package/dist/lib/diff.js.map +1 -1
  71. package/dist/lib/page-ready.d.ts +18 -0
  72. package/dist/lib/page-ready.d.ts.map +1 -0
  73. package/dist/lib/page-ready.js +19 -0
  74. package/dist/lib/page-ready.js.map +1 -0
  75. package/dist/lib/playwright-launch.d.ts +4 -0
  76. package/dist/lib/playwright-launch.d.ts.map +1 -0
  77. package/dist/lib/playwright-launch.js +11 -0
  78. package/dist/lib/playwright-launch.js.map +1 -0
  79. package/dist/lib/screenshot.d.ts +4 -1
  80. package/dist/lib/screenshot.d.ts.map +1 -1
  81. package/dist/lib/screenshot.js +37 -7
  82. package/dist/lib/screenshot.js.map +1 -1
  83. package/dist/lib/staging.d.ts +0 -1
  84. package/dist/lib/staging.d.ts.map +1 -1
  85. package/dist/lib/staging.js +0 -3
  86. package/dist/lib/staging.js.map +1 -1
  87. package/dist/types.d.ts +5 -0
  88. package/dist/types.d.ts.map +1 -1
  89. package/package.json +22 -12
  90. package/templates/notify-slack.jq +30 -0
  91. package/dist/editor/inject-script.d.ts +0 -2
  92. package/dist/editor/inject-script.d.ts.map +0 -1
  93. package/dist/editor/inject-script.js.map +0 -1
@@ -0,0 +1,33 @@
1
+ // Node ↔ page bridge. The Node side calls these via `page.evaluate` /
2
+ // `page.exposeFunction` to load existing data and to receive the saved
3
+ // payload. The GUI port will replace this with an IPC layer but keep the
4
+ // payload shape identical.
5
+ import { loadAnnotations, serializeAnnotations } from "./annotations.js";
6
+ import { loadCapture, serializeCapture } from "./crop.js";
7
+ import { showErrorToast } from "./dom.js";
8
+ import { loadSteps, serializeSteps } from "./record.js";
9
+ import { state } from "./state.js";
10
+ import { setCaptureMode } from "./toolbar.js";
11
+ const save = () => {
12
+ if (state.captureMode === "crop" && !state.captureCrop) {
13
+ showErrorToast("Crop mode is active but no area is drawn.\nDrag to define an area, or switch to Full Page.");
14
+ return;
15
+ }
16
+ const decorations = serializeAnnotations();
17
+ const capture = serializeCapture();
18
+ const beforeCapture = serializeSteps();
19
+ window.__kagemusha_save(JSON.stringify({ decorations, capture, beforeCapture }));
20
+ };
21
+ export const initBridge = () => {
22
+ window.__kagemusha_loadAnnotations = (decorations) => {
23
+ loadAnnotations(decorations);
24
+ };
25
+ window.__kagemusha_loadCapture = (capture) => {
26
+ loadCapture(capture, (mode) => setCaptureMode(mode));
27
+ };
28
+ window.__kagemusha_loadSteps = (steps) => {
29
+ loadSteps(steps);
30
+ };
31
+ return { save };
32
+ };
33
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../src/editor/inject-script/bridge.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,uEAAuE;AACvE,yEAAyE;AACzE,2BAA2B;AAE3B,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAY9C,MAAM,IAAI,GAAG,GAAS,EAAE;IACvB,IAAI,KAAK,CAAC,WAAW,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACxD,cAAc,CACb,4FAA4F,CAC5F,CAAC;QACF,OAAO;IACR,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,aAAa,GAAG,cAAc,EAAE,CAAC;IAEvC,MAAM,CAAC,gBAAgB,CACtB,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CACvD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAyB,EAAE;IACpD,MAAM,CAAC,2BAA2B,GAAG,CAAC,WAAyB,EAAE,EAAE;QAClE,eAAe,CAAC,WAAW,CAAC,CAAC;IAC9B,CAAC,CAAC;IACF,MAAM,CAAC,uBAAuB,GAAG,CAAC,OAAoB,EAAE,EAAE;QACzD,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC;IACF,MAAM,CAAC,qBAAqB,GAAG,CAAC,KAAsB,EAAE,EAAE;QACzD,SAAS,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,CAAC;AACjB,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CaptureSpec } from "./types.js";
2
+ export declare const redrawCropVisual: () => void;
3
+ export declare const initCrop: () => void;
4
+ export declare const handleMouseDown: (e: MouseEvent) => boolean;
5
+ export declare const handleMouseMove: (e: MouseEvent) => boolean;
6
+ export declare const handleMouseUp: (e: MouseEvent) => boolean;
7
+ export declare const loadCapture: (capture: CaptureSpec, setMode: (m: "fullPage" | "crop") => void) => void;
8
+ export declare const serializeCapture: () => CaptureSpec;
9
+ //# sourceMappingURL=crop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crop.d.ts","sourceRoot":"","sources":["../../../src/editor/inject-script/crop.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,YAAY,CAAC;AAsD1D,eAAO,MAAM,gBAAgB,QA/BJ,IA+BmB,CAAC;AAG7C,eAAO,MAAM,QAAQ,QAAO,IAO3B,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,GAAG,UAAU,KAAG,OA0C/C,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,GAAG,UAAU,KAAG,OAmE/C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,GAAG,UAAU,KAAG,OAuB7C,CAAC;AAIF,eAAO,MAAM,WAAW,GACvB,SAAS,WAAW,EACpB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,KACvC,IAuBF,CAAC;AAIF,eAAO,MAAM,gBAAgB,QAAO,WAenC,CAAC"}
@@ -0,0 +1,236 @@
1
+ // Crop mode — defines the capture region (= what kagemusha actually
2
+ // screenshots). User drags to create a rectangle, with 8 handles (corners +
3
+ // edges) for resize and a body region for move. Coordinates live in raw
4
+ // page CSS pixels — same coordinate system the host page uses, so no
5
+ // translation is needed when capture replays the saved crop.
6
+ import { getMousePos } from "./dom.js";
7
+ import { HANDLE_SIZE, MIN_CROP, SVG_NS, state } from "./state.js";
8
+ import { getCaptureGroup } from "./svg.js";
9
+ import { registerCropHooks } from "./toolbar.js";
10
+ const HANDLE_POSITIONS = [
11
+ { handle: "nw", pos: (c) => ({ cx: c.x, cy: c.y }) },
12
+ { handle: "n", pos: (c) => ({ cx: c.x + c.w / 2, cy: c.y }) },
13
+ { handle: "ne", pos: (c) => ({ cx: c.x + c.w, cy: c.y }) },
14
+ { handle: "e", pos: (c) => ({ cx: c.x + c.w, cy: c.y + c.h / 2 }) },
15
+ { handle: "se", pos: (c) => ({ cx: c.x + c.w, cy: c.y + c.h }) },
16
+ { handle: "s", pos: (c) => ({ cx: c.x + c.w / 2, cy: c.y + c.h }) },
17
+ { handle: "sw", pos: (c) => ({ cx: c.x, cy: c.y + c.h }) },
18
+ { handle: "w", pos: (c) => ({ cx: c.x, cy: c.y + c.h / 2 }) },
19
+ ];
20
+ const clearVisual = () => {
21
+ getCaptureGroup().replaceChildren();
22
+ };
23
+ const redrawVisual = () => {
24
+ if (state.captureMode !== "crop" || !state.captureCrop) {
25
+ clearVisual();
26
+ return;
27
+ }
28
+ clearVisual();
29
+ const g = getCaptureGroup();
30
+ const c = state.captureCrop;
31
+ const r = document.createElementNS(SVG_NS, "rect");
32
+ r.setAttribute("x", String(c.x));
33
+ r.setAttribute("y", String(c.y));
34
+ r.setAttribute("width", String(c.w));
35
+ r.setAttribute("height", String(c.h));
36
+ r.setAttribute("class", "capture-crop-box");
37
+ g.appendChild(r);
38
+ for (const { handle, pos } of HANDLE_POSITIONS) {
39
+ const { cx, cy } = pos(c);
40
+ const h = document.createElementNS(SVG_NS, "rect");
41
+ h.setAttribute("x", String(cx - HANDLE_SIZE / 2));
42
+ h.setAttribute("y", String(cy - HANDLE_SIZE / 2));
43
+ h.setAttribute("width", String(HANDLE_SIZE));
44
+ h.setAttribute("height", String(HANDLE_SIZE));
45
+ h.setAttribute("class", `crop-handle ${handle}`);
46
+ h.dataset.handle = handle;
47
+ g.appendChild(h);
48
+ }
49
+ };
50
+ // Re-export so the bridge / load layer can request a redraw after loading.
51
+ export const redrawCropVisual = redrawVisual;
52
+ // Hook crop visuals into toolbar's enter/exit transitions.
53
+ export const initCrop = () => {
54
+ registerCropHooks(
55
+ // onEnter: redraw existing selection (if any)
56
+ () => redrawVisual(),
57
+ // onExit: clear visualization
58
+ () => clearVisual());
59
+ };
60
+ // --- Mouse handlers (called by index.ts dispatcher when tool === "crop") ---
61
+ export const handleMouseDown = (e) => {
62
+ if (state.tool !== "crop")
63
+ return false;
64
+ e.preventDefault();
65
+ const p = getMousePos(e);
66
+ const target = e.target;
67
+ const handleAttr = target.dataset?.handle;
68
+ if (handleAttr && state.captureCrop) {
69
+ state.cropDragState = {
70
+ kind: "resize",
71
+ handle: handleAttr,
72
+ sx: p.x,
73
+ sy: p.y,
74
+ orig: { ...state.captureCrop },
75
+ };
76
+ return true;
77
+ }
78
+ if (target?.classList?.contains("capture-crop-box") && state.captureCrop) {
79
+ state.cropDragState = {
80
+ kind: "move",
81
+ sx: p.x,
82
+ sy: p.y,
83
+ orig: { ...state.captureCrop },
84
+ };
85
+ return true;
86
+ }
87
+ // Otherwise: drag-to-create new crop (replaces existing)
88
+ state.cropDragState = { kind: "create", sx: p.x, sy: p.y };
89
+ state.captureCrop = null;
90
+ clearVisual();
91
+ const r = document.createElementNS(SVG_NS, "rect");
92
+ r.setAttribute("x", String(p.x));
93
+ r.setAttribute("y", String(p.y));
94
+ r.setAttribute("width", "0");
95
+ r.setAttribute("height", "0");
96
+ r.setAttribute("class", "capture-crop-box");
97
+ getCaptureGroup().appendChild(r);
98
+ return true;
99
+ };
100
+ export const handleMouseMove = (e) => {
101
+ const cds = state.cropDragState;
102
+ if (!cds)
103
+ return false;
104
+ const p = getMousePos(e);
105
+ if (cds.kind === "create") {
106
+ const x = Math.min(cds.sx, p.x);
107
+ const y = Math.min(cds.sy, p.y);
108
+ const w = Math.abs(p.x - cds.sx);
109
+ const h = Math.abs(p.y - cds.sy);
110
+ const r = getCaptureGroup().firstChild;
111
+ if (r) {
112
+ r.setAttribute("x", String(x));
113
+ r.setAttribute("y", String(y));
114
+ r.setAttribute("width", String(w));
115
+ r.setAttribute("height", String(h));
116
+ }
117
+ return true;
118
+ }
119
+ if (cds.kind === "move") {
120
+ const dx = p.x - cds.sx;
121
+ const dy = p.y - cds.sy;
122
+ state.captureCrop = {
123
+ x: cds.orig.x + dx,
124
+ y: cds.orig.y + dy,
125
+ w: cds.orig.w,
126
+ h: cds.orig.h,
127
+ };
128
+ redrawVisual();
129
+ return true;
130
+ }
131
+ // resize
132
+ const dx = p.x - cds.sx;
133
+ const dy = p.y - cds.sy;
134
+ const o = cds.orig;
135
+ let nx = o.x;
136
+ let ny = o.y;
137
+ let nw = o.w;
138
+ let nh = o.h;
139
+ const h = cds.handle;
140
+ if (h.includes("w")) {
141
+ nx = o.x + dx;
142
+ nw = o.w - dx;
143
+ }
144
+ if (h.includes("e")) {
145
+ nw = o.w + dx;
146
+ }
147
+ if (h.includes("n")) {
148
+ ny = o.y + dy;
149
+ nh = o.h - dy;
150
+ }
151
+ if (h.includes("s")) {
152
+ nh = o.h + dy;
153
+ }
154
+ if (nw < MIN_CROP) {
155
+ if (h.includes("w"))
156
+ nx = o.x + (o.w - MIN_CROP);
157
+ nw = MIN_CROP;
158
+ }
159
+ if (nh < MIN_CROP) {
160
+ if (h.includes("n"))
161
+ ny = o.y + (o.h - MIN_CROP);
162
+ nh = MIN_CROP;
163
+ }
164
+ state.captureCrop = { x: nx, y: ny, w: nw, h: nh };
165
+ redrawVisual();
166
+ return true;
167
+ };
168
+ export const handleMouseUp = (e) => {
169
+ const cds = state.cropDragState;
170
+ if (!cds)
171
+ return false;
172
+ if (cds.kind === "create") {
173
+ const p = getMousePos(e);
174
+ const w = Math.abs(p.x - cds.sx);
175
+ const h = Math.abs(p.y - cds.sy);
176
+ if (w < 5 || h < 5) {
177
+ state.cropDragState = null;
178
+ redrawVisual();
179
+ return true;
180
+ }
181
+ state.captureCrop = {
182
+ x: Math.min(cds.sx, p.x),
183
+ y: Math.min(cds.sy, p.y),
184
+ w,
185
+ h,
186
+ };
187
+ }
188
+ // move / resize already applied during mousemove
189
+ state.cropDragState = null;
190
+ redrawVisual();
191
+ return true;
192
+ };
193
+ // --- Load (= bridge calls this from definitions.json) ---
194
+ export const loadCapture = (capture, setMode) => {
195
+ if (!capture || !["fullPage", "crop"].includes(capture.mode)) {
196
+ // Unknown / legacy mode (e.g. removed "selector") — fall back to fullPage
197
+ setMode("fullPage");
198
+ return;
199
+ }
200
+ if (capture.mode === "fullPage") {
201
+ setMode("fullPage");
202
+ return;
203
+ }
204
+ if (capture.mode === "crop") {
205
+ // crop is stored in page CSS pixels (not DPR-scaled). No toolbar
206
+ // offset — the toolbar is an overlay, host content stays at its
207
+ // native position.
208
+ const sx = capture.crop.start.x;
209
+ const sy = capture.crop.start.y;
210
+ const ex = capture.crop.end.x;
211
+ const ey = capture.crop.end.y;
212
+ state.captureCrop = { x: sx, y: sy, w: ex - sx, h: ey - sy };
213
+ state.captureMode = "crop";
214
+ setMode("crop");
215
+ redrawVisual();
216
+ }
217
+ };
218
+ // Serialize current crop selection back to definitions.json shape.
219
+ // Returns null if no crop is set or mode is fullPage.
220
+ export const serializeCapture = () => {
221
+ if (state.captureMode === "crop" && state.captureCrop) {
222
+ const c = state.captureCrop;
223
+ return {
224
+ mode: "crop",
225
+ crop: {
226
+ start: { x: Math.round(c.x), y: Math.round(c.y) },
227
+ end: {
228
+ x: Math.round(c.x + c.w),
229
+ y: Math.round(c.y + c.h),
230
+ },
231
+ },
232
+ };
233
+ }
234
+ return { mode: "fullPage" };
235
+ };
236
+ //# sourceMappingURL=crop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crop.js","sourceRoot":"","sources":["../../../src/editor/inject-script/crop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const getMousePos: (e: MouseEvent) => {
2
+ x: number;
3
+ y: number;
4
+ };
5
+ export declare const measureSvgTextWidth: (svg: SVGElement, text: string, fontSize: number, svgNs: string) => number;
6
+ export declare const showErrorToast: (message: string, ms?: number) => void;
7
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../../src/editor/inject-script/dom.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,GAAI,GAAG,UAAU,KAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAGhE,CAAC;AAEH,eAAO,MAAM,mBAAmB,GAC/B,KAAK,UAAU,EACf,MAAM,MAAM,EACZ,UAAU,MAAM,EAChB,OAAO,MAAM,KACX,MASF,CAAC;AAMF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,EAAE,WAAS,KAAG,IAa3D,CAAC"}
@@ -0,0 +1,32 @@
1
+ // DOM helpers shared by all modules. Pure-ish — depends only on the document
2
+ // global, no internal editor state.
3
+ export const getMousePos = (e) => ({
4
+ x: e.pageX,
5
+ y: e.pageY,
6
+ });
7
+ export const measureSvgTextWidth = (svg, text, fontSize, svgNs) => {
8
+ const tmp = document.createElementNS(svgNs, "text");
9
+ tmp.setAttribute("font-size", String(fontSize));
10
+ tmp.setAttribute("font-family", "-apple-system, sans-serif");
11
+ tmp.textContent = text;
12
+ svg.appendChild(tmp);
13
+ const width = tmp.getBBox().width;
14
+ tmp.remove();
15
+ return width;
16
+ };
17
+ // In-page error toast — `window.alert()` would be auto-dismissed by
18
+ // Playwright's default dialog handler (= the user sees a flash they can't
19
+ // read). We render our own non-blocking toast under <html> so it can't be
20
+ // inert'd by host SPAs (same reason as the toolbar).
21
+ export const showErrorToast = (message, ms = 5000) => {
22
+ const toast = document.createElement("div");
23
+ toast.setAttribute("style", "position:fixed;top:72px;left:50%;transform:translateX(-50%);" +
24
+ "background:#dc2626;color:#fff;padding:12px 20px;border-radius:8px;" +
25
+ "font-family:-apple-system,sans-serif;font-size:14px;line-height:1.4;" +
26
+ "z-index:var(--kg-z-top);box-shadow:0 4px 12px rgba(0,0,0,0.3);" +
27
+ "max-width:480px;white-space:pre-wrap;text-align:center;");
28
+ toast.textContent = message;
29
+ document.documentElement.appendChild(toast);
30
+ setTimeout(() => toast.remove(), ms);
31
+ };
32
+ //# sourceMappingURL=dom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom.js","sourceRoot":"","sources":["../../../src/editor/inject-script/dom.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,oCAAoC;AAEpC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAa,EAA4B,EAAE,CAAC,CAAC;IACxE,CAAC,EAAE,CAAC,CAAC,KAAK;IACV,CAAC,EAAE,CAAC,CAAC,KAAK;CACV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAClC,GAAe,EACf,IAAY,EACZ,QAAgB,EAChB,KAAa,EACJ,EAAE;IACX,MAAM,GAAG,GAAG,QAAQ,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,GAAG,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChD,GAAG,CAAC,YAAY,CAAC,aAAa,EAAE,2BAA2B,CAAC,CAAC;IAC7D,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACrB,MAAM,KAAK,GAAI,GAAsB,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC;IACtD,GAAG,CAAC,MAAM,EAAE,CAAC;IACb,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,oEAAoE;AACpE,0EAA0E;AAC1E,0EAA0E;AAC1E,qDAAqD;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,GAAG,IAAI,EAAQ,EAAE;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,CAAC,YAAY,CACjB,OAAO,EACP,8DAA8D;QAC7D,oEAAoE;QACpE,sEAAsE;QACtE,gEAAgE;QAChE,yDAAyD,CAC1D,CAAC;IACF,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5C,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/editor/inject-script/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ // Editor entry point. Bundled by esbuild into a single IIFE
2
+ // (dist/editor/inject-script.js) and injected by edit.ts via page.evaluate.
3
+ //
4
+ // Bootstrap order:
5
+ // 1. SVG layer (= must exist before annotation/crop modules touch it)
6
+ // 2. Toolbar (= depends on svg ref for the cropping/drawing classes)
7
+ // 3. Crop hooks (= register enter/exit callbacks on the toolbar)
8
+ // 4. Bridge (= expose window.__kagemusha_* functions)
9
+ // 5. Mouse + keyboard dispatcher
10
+ import * as annotations from "./annotations.js";
11
+ import { initBridge } from "./bridge.js";
12
+ import * as crop from "./crop.js";
13
+ import { initRecord } from "./record.js";
14
+ import { initSvgLayer } from "./svg.js";
15
+ import { initToolbar } from "./toolbar.js";
16
+ // Prevent inject-time elements (toolbar / svg / hint / panel) from
17
+ // extending document.documentElement.scrollHeight. Some SPAs run
18
+ // responsive layout calculations based on documentH; if the value
19
+ // differs between edit and capture, modals can land at different Y
20
+ // positions. Forcing <html> overflow:hidden caps scrollHeight at the
21
+ // viewport height — matching capture-time behavior.
22
+ document.documentElement.style.overflow = "hidden";
23
+ const { svg } = initSvgLayer();
24
+ let bridgeSave = () => { };
25
+ initToolbar({
26
+ onToolChange: () => {
27
+ // Toolbar already updates state.tool and svg classes. Nothing extra
28
+ // to do here right now, but the hook is here so the future record
29
+ // module can detach listeners on tool change.
30
+ },
31
+ onSave: () => bridgeSave(),
32
+ onDelete: () => annotations.deleteSelected(),
33
+ }, svg);
34
+ crop.initCrop();
35
+ initRecord(svg);
36
+ ({ save: bridgeSave } = initBridge());
37
+ // --- Mouse dispatcher ---
38
+ // Single mousedown handler on the SVG layer; route to crop if the current
39
+ // tool is crop, otherwise to annotations.
40
+ svg.addEventListener("mousedown", (e) => {
41
+ if (crop.handleMouseDown(e))
42
+ return;
43
+ annotations.handleMouseDown(e);
44
+ });
45
+ document.addEventListener("mousemove", (e) => {
46
+ if (crop.handleMouseMove(e))
47
+ return;
48
+ annotations.handleMouseMove(e);
49
+ });
50
+ document.addEventListener("mouseup", (e) => {
51
+ if (crop.handleMouseUp(e))
52
+ return;
53
+ annotations.handleMouseUp(e);
54
+ });
55
+ document.addEventListener("keydown", (e) => annotations.handleKeyDown(e));
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/editor/inject-script/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,4EAA4E;AAC5E,EAAE;AACF,mBAAmB;AACnB,yEAAyE;AACzE,0EAA0E;AAC1E,mEAAmE;AACnE,4DAA4D;AAC5D,mCAAmC;AAEnC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,mEAAmE;AACnE,iEAAiE;AACjE,kEAAkE;AAClE,mEAAmE;AACnE,qEAAqE;AACrE,oDAAoD;AACpD,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAEnD,MAAM,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,CAAC;AAE/B,IAAI,UAAU,GAAe,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtC,WAAW,CACV;IACC,YAAY,EAAE,GAAG,EAAE;QAClB,oEAAoE;QACpE,kEAAkE;QAClE,8CAA8C;IAC/C,CAAC;IACD,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;IAC1B,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,cAAc,EAAE;CAC5C,EACD,GAAG,CACH,CAAC;AAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;AAChB,UAAU,CAAC,GAAG,CAAC,CAAC;AAChB,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;AAEtC,2BAA2B;AAC3B,0EAA0E;AAC1E,0CAA0C;AAE1C,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAa,EAAE,EAAE;IACnD,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAAE,OAAO;IACpC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAa,EAAE,EAAE;IACxD,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QAAE,OAAO;IACpC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAa,EAAE,EAAE;IACtD,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAAE,OAAO;IAClC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAgB,EAAE,EAAE,CACzD,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAC5B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CaptureAction } from "./types.js";
2
+ export declare const initRecord: (svg: SVGElement) => void;
3
+ export declare const loadSteps: (steps: CaptureAction[]) => void;
4
+ export declare const serializeSteps: () => CaptureAction[];
5
+ //# sourceMappingURL=record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../src/editor/inject-script/record.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6WhD,eAAO,MAAM,UAAU,GAAI,KAAK,UAAU,KAAG,IAmC5C,CAAC;AAGF,eAAO,MAAM,SAAS,GAAI,OAAO,aAAa,EAAE,KAAG,IAGlD,CAAC;AAGF,eAAO,MAAM,cAAc,QAAO,aAAa,EAA8B,CAAC"}