@hypen-space/web 0.4.980 → 0.5.3
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.
- package/README.md +20 -13
- package/dist/canvas/accessibility.d.ts +118 -11
- package/dist/canvas/accessibility.js +470 -108
- package/dist/canvas/accessibility.js.map +1 -1
- package/dist/canvas/dispatch.d.ts +24 -0
- package/dist/canvas/dispatch.js +62 -0
- package/dist/canvas/dispatch.js.map +1 -0
- package/dist/canvas/editing.d.ts +178 -0
- package/dist/canvas/editing.js +590 -0
- package/dist/canvas/editing.js.map +1 -0
- package/dist/canvas/events.d.ts +28 -23
- package/dist/canvas/events.js +90 -103
- package/dist/canvas/events.js.map +1 -1
- package/dist/canvas/focus.d.ts +78 -0
- package/dist/canvas/focus.js +182 -0
- package/dist/canvas/focus.js.map +1 -0
- package/dist/canvas/index.d.ts +3 -2
- package/dist/canvas/index.js +3 -2
- package/dist/canvas/index.js.map +1 -1
- package/dist/canvas/layout.js +68 -98
- package/dist/canvas/layout.js.map +1 -1
- package/dist/canvas/paint.d.ts +16 -3
- package/dist/canvas/paint.js +449 -110
- package/dist/canvas/paint.js.map +1 -1
- package/dist/canvas/renderer.d.ts +28 -4
- package/dist/canvas/renderer.js +201 -81
- package/dist/canvas/renderer.js.map +1 -1
- package/dist/canvas/selection.js +31 -177
- package/dist/canvas/selection.js.map +1 -1
- package/dist/canvas/text-geometry.d.ts +72 -0
- package/dist/canvas/text-geometry.js +244 -0
- package/dist/canvas/text-geometry.js.map +1 -0
- package/dist/canvas/text.js +44 -18
- package/dist/canvas/text.js.map +1 -1
- package/dist/canvas/types.d.ts +10 -1
- package/dist/canvas/utils.d.ts +0 -23
- package/dist/canvas/utils.js +3 -67
- package/dist/canvas/utils.js.map +1 -1
- package/dist/canvas/variants.d.ts +52 -0
- package/dist/canvas/variants.js +156 -0
- package/dist/canvas/variants.js.map +1 -0
- package/dist/dom/a11y-styles.d.ts +20 -0
- package/dist/dom/a11y-styles.js +61 -0
- package/dist/dom/a11y-styles.js.map +1 -0
- package/dist/dom/applicators/aria.d.ts +19 -0
- package/dist/dom/applicators/aria.js +36 -0
- package/dist/dom/applicators/aria.js.map +1 -0
- package/dist/dom/applicators/events.d.ts +7 -0
- package/dist/dom/applicators/events.js +36 -8
- package/dist/dom/applicators/events.js.map +1 -1
- package/dist/dom/applicators/font.d.ts +11 -6
- package/dist/dom/applicators/font.js +16 -27
- package/dist/dom/applicators/font.js.map +1 -1
- package/dist/dom/applicators/index.js +51 -45
- package/dist/dom/applicators/index.js.map +1 -1
- package/dist/dom/canvas/index.js +2 -2
- package/dist/dom/canvas/index.js.map +1 -1
- package/dist/dom/components/app.js +2 -2
- package/dist/dom/components/app.js.map +1 -1
- package/dist/dom/components/audio.js +2 -2
- package/dist/dom/components/audio.js.map +1 -1
- package/dist/dom/components/avatar.js +3 -4
- package/dist/dom/components/avatar.js.map +1 -1
- package/dist/dom/components/badge.js +3 -4
- package/dist/dom/components/badge.js.map +1 -1
- package/dist/dom/components/button.js +2 -2
- package/dist/dom/components/button.js.map +1 -1
- package/dist/dom/components/card.js +2 -2
- package/dist/dom/components/card.js.map +1 -1
- package/dist/dom/components/center.js +2 -2
- package/dist/dom/components/center.js.map +1 -1
- package/dist/dom/components/checkbox.js +4 -5
- package/dist/dom/components/checkbox.js.map +1 -1
- package/dist/dom/components/column.js +2 -2
- package/dist/dom/components/column.js.map +1 -1
- package/dist/dom/components/container.js +2 -2
- package/dist/dom/components/container.js.map +1 -1
- package/dist/dom/components/divider.js +2 -2
- package/dist/dom/components/divider.js.map +1 -1
- package/dist/dom/components/grid.js +10 -10
- package/dist/dom/components/grid.js.map +1 -1
- package/dist/dom/components/heading.js +4 -6
- package/dist/dom/components/heading.js.map +1 -1
- package/dist/dom/components/hypenapp.d.ts +25 -1
- package/dist/dom/components/hypenapp.js +215 -247
- package/dist/dom/components/hypenapp.js.map +1 -1
- package/dist/dom/components/icon.js +4 -5
- package/dist/dom/components/icon.js.map +1 -1
- package/dist/dom/components/image.js +2 -2
- package/dist/dom/components/image.js.map +1 -1
- package/dist/dom/components/index.d.ts +2 -2
- package/dist/dom/components/index.js +9 -2
- package/dist/dom/components/index.js.map +1 -1
- package/dist/dom/components/input.js +2 -2
- package/dist/dom/components/input.js.map +1 -1
- package/dist/dom/components/link.js +2 -2
- package/dist/dom/components/link.js.map +1 -1
- package/dist/dom/components/list.js +2 -2
- package/dist/dom/components/list.js.map +1 -1
- package/dist/dom/components/paragraph.js +3 -4
- package/dist/dom/components/paragraph.js.map +1 -1
- package/dist/dom/components/progressbar.js +3 -3
- package/dist/dom/components/progressbar.js.map +1 -1
- package/dist/dom/components/route.js +2 -2
- package/dist/dom/components/route.js.map +1 -1
- package/dist/dom/components/router.js +2 -2
- package/dist/dom/components/router.js.map +1 -1
- package/dist/dom/components/row.js +10 -10
- package/dist/dom/components/row.js.map +1 -1
- package/dist/dom/components/select.js +3 -4
- package/dist/dom/components/select.js.map +1 -1
- package/dist/dom/components/slider.js +2 -2
- package/dist/dom/components/slider.js.map +1 -1
- package/dist/dom/components/spacer.js +2 -2
- package/dist/dom/components/spacer.js.map +1 -1
- package/dist/dom/components/spinner.js +27 -13
- package/dist/dom/components/spinner.js.map +1 -1
- package/dist/dom/components/stack.js +10 -10
- package/dist/dom/components/stack.js.map +1 -1
- package/dist/dom/components/switch.js +5 -6
- package/dist/dom/components/switch.js.map +1 -1
- package/dist/dom/components/tabs.d.ts +27 -0
- package/dist/dom/components/tabs.js +69 -0
- package/dist/dom/components/tabs.js.map +1 -0
- package/dist/dom/components/text.js +4 -7
- package/dist/dom/components/text.js.map +1 -1
- package/dist/dom/components/textarea.js +2 -2
- package/dist/dom/components/textarea.js.map +1 -1
- package/dist/dom/components/video.js +2 -2
- package/dist/dom/components/video.js.map +1 -1
- package/dist/dom/components/visuallyhidden.d.ts +9 -0
- package/dist/dom/components/visuallyhidden.js +26 -0
- package/dist/dom/components/visuallyhidden.js.map +1 -0
- package/dist/dom/debug.js +6 -8
- package/dist/dom/debug.js.map +1 -1
- package/dist/dom/index.d.ts +0 -1
- package/dist/dom/index.js +0 -1
- package/dist/dom/index.js.map +1 -1
- package/dist/dom/operability.d.ts +100 -0
- package/dist/dom/operability.js +298 -0
- package/dist/dom/operability.js.map +1 -0
- package/dist/dom/renderer.d.ts +98 -5
- package/dist/dom/renderer.js +400 -66
- package/dist/dom/renderer.js.map +1 -1
- package/dist/dom/route-focus.d.ts +42 -0
- package/dist/dom/route-focus.js +88 -0
- package/dist/dom/route-focus.js.map +1 -0
- package/dist/dom/semantics.d.ts +35 -0
- package/dist/dom/semantics.js +184 -0
- package/dist/dom/semantics.js.map +1 -0
- package/dist/variants.d.ts +90 -0
- package/dist/variants.js +206 -0
- package/dist/variants.js.map +1 -0
- package/package.json +2 -2
- package/src/canvas/QUICKSTART.md +16 -11
- package/src/canvas/README.md +63 -34
- package/src/canvas/accessibility.ts +507 -115
- package/src/canvas/dispatch.ts +78 -0
- package/src/canvas/editing.ts +697 -0
- package/src/canvas/events.ts +104 -115
- package/src/canvas/focus.ts +216 -0
- package/src/canvas/index.ts +8 -9
- package/src/canvas/layout.ts +68 -103
- package/src/canvas/paint.ts +509 -109
- package/src/canvas/renderer.ts +239 -99
- package/src/canvas/selection.ts +52 -210
- package/src/canvas/text-geometry.ts +311 -0
- package/src/canvas/text.ts +45 -18
- package/src/canvas/types.ts +28 -1
- package/src/canvas/utils.ts +3 -69
- package/src/canvas/variants.ts +172 -0
- package/src/dom/README.md +8 -7
- package/src/dom/a11y-styles.ts +65 -0
- package/src/dom/applicators/aria.ts +41 -0
- package/src/dom/applicators/events.ts +39 -7
- package/src/dom/applicators/font.ts +16 -29
- package/src/dom/applicators/index.ts +61 -46
- package/src/dom/canvas/index.ts +2 -2
- package/src/dom/components/app.ts +2 -2
- package/src/dom/components/audio.ts +2 -2
- package/src/dom/components/avatar.ts +3 -4
- package/src/dom/components/badge.ts +3 -4
- package/src/dom/components/button.ts +2 -2
- package/src/dom/components/card.ts +2 -2
- package/src/dom/components/center.ts +2 -2
- package/src/dom/components/checkbox.ts +4 -5
- package/src/dom/components/column.ts +2 -2
- package/src/dom/components/container.ts +2 -2
- package/src/dom/components/divider.ts +2 -2
- package/src/dom/components/grid.ts +10 -10
- package/src/dom/components/heading.ts +4 -6
- package/src/dom/components/hypenapp.ts +246 -274
- package/src/dom/components/icon.ts +4 -5
- package/src/dom/components/image.ts +2 -2
- package/src/dom/components/index.ts +10 -3
- package/src/dom/components/input.ts +2 -2
- package/src/dom/components/link.ts +2 -2
- package/src/dom/components/list.ts +2 -2
- package/src/dom/components/paragraph.ts +3 -4
- package/src/dom/components/progressbar.ts +3 -3
- package/src/dom/components/route.ts +2 -2
- package/src/dom/components/router.ts +2 -2
- package/src/dom/components/row.ts +10 -10
- package/src/dom/components/select.ts +3 -4
- package/src/dom/components/slider.ts +2 -2
- package/src/dom/components/spacer.ts +2 -2
- package/src/dom/components/spinner.ts +34 -16
- package/src/dom/components/stack.ts +10 -10
- package/src/dom/components/switch.ts +5 -6
- package/src/dom/components/tabs.ts +76 -0
- package/src/dom/components/text.ts +4 -7
- package/src/dom/components/textarea.ts +2 -2
- package/src/dom/components/video.ts +2 -2
- package/src/dom/components/visuallyhidden.ts +30 -0
- package/src/dom/debug.ts +6 -8
- package/src/dom/index.ts +0 -8
- package/src/dom/operability.ts +312 -0
- package/src/dom/renderer.ts +457 -66
- package/src/dom/route-focus.ts +98 -0
- package/src/dom/semantics.ts +199 -0
- package/src/variants.ts +249 -0
- package/dist/canvas/input.d.ts +0 -76
- package/dist/canvas/input.js +0 -207
- package/dist/canvas/input.js.map +0 -1
- package/dist/client.d.ts +0 -36
- package/dist/client.js +0 -47
- package/dist/client.js.map +0 -1
- package/src/canvas/input.ts +0 -251
- package/src/client.ts +0 -88
package/dist/canvas/selection.js
CHANGED
|
@@ -4,13 +4,7 @@
|
|
|
4
4
|
* Enables click-to-place-cursor, drag-to-select, double-click-word,
|
|
5
5
|
* triple-click-line, and Ctrl/Cmd+C copy for canvas-rendered text.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { measureText } from "./text.js";
|
|
9
|
-
import { createFontString } from "./utils.js";
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// Selection state
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
const HIGHLIGHT_COLOR = "rgba(59, 130, 246, 0.35)";
|
|
7
|
+
import { SELECTION_HIGHLIGHT_COLOR, nodeTextGeometry, pointToOffset, rangeToRects, resolveNodeText, } from "./text-geometry.js";
|
|
14
8
|
// ---------------------------------------------------------------------------
|
|
15
9
|
// SelectionManager
|
|
16
10
|
// ---------------------------------------------------------------------------
|
|
@@ -147,7 +141,7 @@ export class SelectionManager {
|
|
|
147
141
|
const node = this.findNodeById(pos.nodeId);
|
|
148
142
|
if (!node)
|
|
149
143
|
return;
|
|
150
|
-
const text =
|
|
144
|
+
const text = resolveNodeText(node);
|
|
151
145
|
const start = wordBoundaryBefore(text, pos.offset);
|
|
152
146
|
const end = wordBoundaryAfter(text, pos.offset);
|
|
153
147
|
this.selection = {
|
|
@@ -159,7 +153,7 @@ export class SelectionManager {
|
|
|
159
153
|
const node = this.findNodeById(nodeId);
|
|
160
154
|
if (!node)
|
|
161
155
|
return;
|
|
162
|
-
const text =
|
|
156
|
+
const text = resolveNodeText(node);
|
|
163
157
|
this.selection = {
|
|
164
158
|
anchor: { nodeId, offset: 0 },
|
|
165
159
|
focus: { nodeId, offset: text.length },
|
|
@@ -171,7 +165,7 @@ export class SelectionManager {
|
|
|
171
165
|
const node = this.findNodeById(this.selection.anchor.nodeId);
|
|
172
166
|
if (!node)
|
|
173
167
|
return null;
|
|
174
|
-
const text =
|
|
168
|
+
const text = resolveNodeText(node);
|
|
175
169
|
const [start, end] = normalizeRange(this.selection);
|
|
176
170
|
return text.slice(start, end);
|
|
177
171
|
}
|
|
@@ -186,27 +180,41 @@ export class SelectionManager {
|
|
|
186
180
|
return null;
|
|
187
181
|
return this.hitTestTextNode(this.rootNode, point);
|
|
188
182
|
}
|
|
189
|
-
hitTestTextNode(node, point) {
|
|
183
|
+
hitTestTextNode(node, point, scrollX = 0, scrollY = 0) {
|
|
190
184
|
if (!node.visible || !node.layout)
|
|
191
185
|
return null;
|
|
186
|
+
const layout = node.layout;
|
|
187
|
+
const x = layout.x - scrollX;
|
|
188
|
+
const y = layout.y - scrollY;
|
|
189
|
+
const inBounds = point.x >= x && point.x <= x + layout.width &&
|
|
190
|
+
point.y >= y && point.y <= y + layout.height;
|
|
191
|
+
// A clipping container confines its subtree to its own box — when the
|
|
192
|
+
// point is outside, no descendant text can be visible under it.
|
|
193
|
+
if (!inBounds) {
|
|
194
|
+
const overflow = node.props.overflow;
|
|
195
|
+
if (overflow === "hidden" || overflow === "scroll" || overflow === "auto") {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const childScrollX = scrollX + (node.scrollState?.scrollX ?? 0);
|
|
200
|
+
const childScrollY = scrollY + (node.scrollState?.scrollY ?? 0);
|
|
192
201
|
// Check children first (front-to-back)
|
|
193
202
|
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
194
|
-
const result = this.hitTestTextNode(node.children[i], point);
|
|
203
|
+
const result = this.hitTestTextNode(node.children[i], point, childScrollX, childScrollY);
|
|
195
204
|
if (result)
|
|
196
205
|
return result;
|
|
197
206
|
}
|
|
198
207
|
// Only text nodes are selectable
|
|
199
208
|
if (node.type !== "text")
|
|
200
209
|
return null;
|
|
201
|
-
|
|
202
|
-
if (!bounds)
|
|
203
|
-
return null;
|
|
204
|
-
if (point.x < bounds.x || point.x > bounds.x + bounds.width ||
|
|
205
|
-
point.y < bounds.y || point.y > bounds.y + bounds.height) {
|
|
210
|
+
if (!inBounds)
|
|
206
211
|
return null;
|
|
207
|
-
}
|
|
208
212
|
// Map point to character offset within this text node
|
|
209
|
-
const
|
|
213
|
+
const ctx = this.canvas.getContext("2d");
|
|
214
|
+
if (!ctx)
|
|
215
|
+
return null;
|
|
216
|
+
const geometry = nodeTextGeometry(node, resolveNodeText(node), x + layout.contentX, y + layout.contentY);
|
|
217
|
+
const offset = pointToOffset(ctx, geometry, point);
|
|
210
218
|
return { nodeId: node.id, offset };
|
|
211
219
|
}
|
|
212
220
|
// -------------------------------------------------------------------------
|
|
@@ -223,9 +231,11 @@ export class SelectionManager {
|
|
|
223
231
|
const [start, end] = normalizeRange(this.selection);
|
|
224
232
|
if (start === end)
|
|
225
233
|
return; // caret only, no highlight
|
|
226
|
-
const
|
|
234
|
+
const layout = node.layout;
|
|
235
|
+
const geometry = nodeTextGeometry(node, resolveNodeText(node), layout.x + layout.contentX, layout.y + layout.contentY);
|
|
236
|
+
const rects = rangeToRects(ctx, geometry, start, end);
|
|
227
237
|
ctx.save();
|
|
228
|
-
ctx.fillStyle =
|
|
238
|
+
ctx.fillStyle = SELECTION_HIGHLIGHT_COLOR;
|
|
229
239
|
for (const r of rects) {
|
|
230
240
|
ctx.fillRect(r.x, r.y, r.width, r.height);
|
|
231
241
|
}
|
|
@@ -251,18 +261,6 @@ export class SelectionManager {
|
|
|
251
261
|
// ---------------------------------------------------------------------------
|
|
252
262
|
// Pure helpers
|
|
253
263
|
// ---------------------------------------------------------------------------
|
|
254
|
-
function resolveText(node) {
|
|
255
|
-
const raw = node.props[0] || node.props.text || "";
|
|
256
|
-
let text = String(raw);
|
|
257
|
-
const tt = node.props.textTransform || "none";
|
|
258
|
-
if (tt === "uppercase")
|
|
259
|
-
text = text.toUpperCase();
|
|
260
|
-
else if (tt === "lowercase")
|
|
261
|
-
text = text.toLowerCase();
|
|
262
|
-
else if (tt === "capitalize")
|
|
263
|
-
text = text.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
264
|
-
return text;
|
|
265
|
-
}
|
|
266
264
|
function normalizeRange(sel) {
|
|
267
265
|
const a = sel.anchor.offset;
|
|
268
266
|
const b = sel.focus.offset;
|
|
@@ -299,150 +297,6 @@ function findById(node, id) {
|
|
|
299
297
|
return null;
|
|
300
298
|
}
|
|
301
299
|
// ---------------------------------------------------------------------------
|
|
302
|
-
// Geometry: map a canvas point to a character offset
|
|
303
|
-
// ---------------------------------------------------------------------------
|
|
304
|
-
/**
|
|
305
|
-
* Given a point inside a text node's bounds, return the character index
|
|
306
|
-
* that the point falls on.
|
|
307
|
-
*/
|
|
308
|
-
function pointToOffset(canvas, node, bounds, point) {
|
|
309
|
-
const ctx = canvas.getContext("2d");
|
|
310
|
-
if (!ctx)
|
|
311
|
-
return 0;
|
|
312
|
-
const props = node.props;
|
|
313
|
-
const text = resolveText(node);
|
|
314
|
-
const layout = node.layout;
|
|
315
|
-
const fontSize = parseFloat(props.fontSize) || 16;
|
|
316
|
-
const fontWeight = props.fontWeight || "normal";
|
|
317
|
-
const fontFamily = props.fontFamily || "system-ui, sans-serif";
|
|
318
|
-
const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;
|
|
319
|
-
const textAlign = props.textAlign || "left";
|
|
320
|
-
const fontStyle = { fontSize, fontWeight, fontFamily, lineHeight };
|
|
321
|
-
const font = createFontString(fontSize, fontWeight, fontFamily);
|
|
322
|
-
ctx.save();
|
|
323
|
-
ctx.font = font;
|
|
324
|
-
const metrics = measureText(ctx, text, fontStyle, layout.contentWidth);
|
|
325
|
-
const contentX = bounds.x + layout.contentX;
|
|
326
|
-
const contentY = bounds.y + layout.contentY;
|
|
327
|
-
// Find which line the point falls on
|
|
328
|
-
const relY = point.y - contentY;
|
|
329
|
-
let lineIndex = Math.floor(relY / metrics.lineHeight);
|
|
330
|
-
lineIndex = Math.max(0, Math.min(lineIndex, metrics.lines.length - 1));
|
|
331
|
-
// Calculate character offset before this line
|
|
332
|
-
let charsBefore = 0;
|
|
333
|
-
for (let i = 0; i < lineIndex; i++) {
|
|
334
|
-
charsBefore += metrics.lines[i].length;
|
|
335
|
-
// Account for space/newline between lines (word wrap eats the space)
|
|
336
|
-
if (i < metrics.lines.length - 1) {
|
|
337
|
-
const nextLineStart = text.indexOf(metrics.lines[i + 1], charsBefore);
|
|
338
|
-
if (nextLineStart > charsBefore)
|
|
339
|
-
charsBefore = nextLineStart;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
const line = metrics.lines[lineIndex];
|
|
343
|
-
// Calculate line X offset (for text-align)
|
|
344
|
-
let lineX = contentX;
|
|
345
|
-
if (textAlign === "center") {
|
|
346
|
-
const lw = ctx.measureText(line).width;
|
|
347
|
-
lineX = contentX + (layout.contentWidth - lw) / 2;
|
|
348
|
-
}
|
|
349
|
-
else if (textAlign === "right") {
|
|
350
|
-
const lw = ctx.measureText(line).width;
|
|
351
|
-
lineX = contentX + layout.contentWidth - lw;
|
|
352
|
-
}
|
|
353
|
-
// Binary search for the character at point.x
|
|
354
|
-
const relX = point.x - lineX;
|
|
355
|
-
let best = 0;
|
|
356
|
-
for (let i = 0; i <= line.length; i++) {
|
|
357
|
-
const w = ctx.measureText(line.slice(0, i)).width;
|
|
358
|
-
if (w <= relX) {
|
|
359
|
-
best = i;
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
// Check if we're closer to this char or the previous
|
|
363
|
-
const prevW = ctx.measureText(line.slice(0, i - 1)).width;
|
|
364
|
-
if (relX - prevW < w - relX) {
|
|
365
|
-
best = i - 1;
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
best = i;
|
|
369
|
-
}
|
|
370
|
-
break;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
ctx.restore();
|
|
374
|
-
return charsBefore + best;
|
|
375
|
-
}
|
|
376
|
-
// ---------------------------------------------------------------------------
|
|
377
|
-
// Geometry: compute highlight rectangles for a selection range
|
|
378
|
-
// ---------------------------------------------------------------------------
|
|
379
|
-
/**
|
|
380
|
-
* Return a list of rectangles to paint as the selection highlight for
|
|
381
|
-
* characters [start, end) within a text node.
|
|
382
|
-
*/
|
|
383
|
-
function getSelectionRects(ctx, node, start, end) {
|
|
384
|
-
const props = node.props;
|
|
385
|
-
const layout = node.layout;
|
|
386
|
-
const text = resolveText(node);
|
|
387
|
-
const fontSize = parseFloat(props.fontSize) || 16;
|
|
388
|
-
const fontWeight = props.fontWeight || "normal";
|
|
389
|
-
const fontFamily = props.fontFamily || "system-ui, sans-serif";
|
|
390
|
-
const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;
|
|
391
|
-
const textAlign = props.textAlign || "left";
|
|
392
|
-
const fontStyle = { fontSize, fontWeight, fontFamily, lineHeight };
|
|
393
|
-
const font = createFontString(fontSize, fontWeight, fontFamily);
|
|
394
|
-
ctx.save();
|
|
395
|
-
ctx.font = font;
|
|
396
|
-
const metrics = measureText(ctx, text, fontStyle, layout.contentWidth);
|
|
397
|
-
const x = layout.x + layout.contentX;
|
|
398
|
-
const y = layout.y + layout.contentY;
|
|
399
|
-
const rects = [];
|
|
400
|
-
// Map lines to character ranges
|
|
401
|
-
let charOffset = 0;
|
|
402
|
-
for (let i = 0; i < metrics.lines.length; i++) {
|
|
403
|
-
const line = metrics.lines[i];
|
|
404
|
-
const lineStart = charOffset;
|
|
405
|
-
const lineEnd = charOffset + line.length;
|
|
406
|
-
// Find actual position in original text for this line
|
|
407
|
-
if (i > 0) {
|
|
408
|
-
const idx = text.indexOf(line, charOffset);
|
|
409
|
-
if (idx > charOffset)
|
|
410
|
-
charOffset = idx;
|
|
411
|
-
}
|
|
412
|
-
const actualLineStart = charOffset;
|
|
413
|
-
const actualLineEnd = charOffset + line.length;
|
|
414
|
-
// Does this line overlap with the selection?
|
|
415
|
-
if (actualLineEnd <= start || actualLineStart >= end) {
|
|
416
|
-
charOffset = actualLineEnd;
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
// Clamp selection to this line
|
|
420
|
-
const selStart = Math.max(0, start - actualLineStart);
|
|
421
|
-
const selEnd = Math.min(line.length, end - actualLineStart);
|
|
422
|
-
// Calculate line X offset (text-align)
|
|
423
|
-
let lineX = x;
|
|
424
|
-
const lineWidth = ctx.measureText(line).width;
|
|
425
|
-
if (textAlign === "center") {
|
|
426
|
-
lineX = x + (layout.contentWidth - lineWidth) / 2;
|
|
427
|
-
}
|
|
428
|
-
else if (textAlign === "right") {
|
|
429
|
-
lineX = x + layout.contentWidth - lineWidth;
|
|
430
|
-
}
|
|
431
|
-
// Measure selection bounds within this line
|
|
432
|
-
const startX = ctx.measureText(line.slice(0, selStart)).width;
|
|
433
|
-
const endX = ctx.measureText(line.slice(0, selEnd)).width;
|
|
434
|
-
rects.push({
|
|
435
|
-
x: lineX + startX,
|
|
436
|
-
y: y + i * metrics.lineHeight,
|
|
437
|
-
width: endX - startX,
|
|
438
|
-
height: metrics.lineHeight,
|
|
439
|
-
});
|
|
440
|
-
charOffset = actualLineEnd;
|
|
441
|
-
}
|
|
442
|
-
ctx.restore();
|
|
443
|
-
return rects;
|
|
444
|
-
}
|
|
445
|
-
// ---------------------------------------------------------------------------
|
|
446
300
|
// Clipboard fallback
|
|
447
301
|
// ---------------------------------------------------------------------------
|
|
448
302
|
function fallbackCopy(text) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/canvas/selection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4B9C,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,eAAe,GAAG,0BAA0B,CAAC;AAEnD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAoB;IAC1B,QAAQ,GAAuB,IAAI,CAAC;IACpC,aAAa,CAAa;IAElC,mDAAmD;IACnD,SAAS,GAAyB,IAAI,CAAC;IAEvC,gBAAgB;IACR,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,GAAG,CAAC,CAAC;IACf,aAAa,GAAG,CAAC,CAAC;IAClB,eAAe,GAAG,EAAE,CAAC;IAE7B,iBAAiB;IACT,cAAc,CAA2B;IACzC,cAAc,CAA2B;IACzC,YAAY,CAA2B;IACvC,YAAY,CAA8B;IAElD,YAAY,MAAyB,EAAE,aAAyB;QAC9D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED,WAAW,CAAC,IAAwB;QAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,4EAA4E;IAC5E,eAAe;IACf,4EAA4E;IAEpE,cAAc;QACpB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3D,0DAA0D;QAC1D,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,gBAAgB,CACrE,SAAS,EACT,IAAI,CAAC,YAA6B,CACnC,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,iBAAiB;IACjB,4EAA4E;IAEpE,WAAW,CAAC,CAAa;QAC/B,4EAA4E;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACjD,OAAO;YACL,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI;YACxB,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG;SACxB,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,CAAa;QAC/B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,kBAAkB;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;YACD,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,IACE,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,GAAG;YAC9B,IAAI,CAAC,eAAe,KAAK,GAAG,CAAC,MAAM,EACnC,CAAC;YACD,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC;QAElC,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,4BAA4B;YAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;YAChC,wCAAwC;YACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,IAAI,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,WAAW,CAAC,CAAa;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvD,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC;YAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,EAAc;QAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,SAAS,CAAC,CAAgB;QAChC,MAAM,MAAM,GACV,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;QAC5C,MAAM,WAAW,GACf,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;QAE5C,IAAI,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACpC,IAAI,IAAI,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBACpE,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBAC7C,gEAAgE;oBAChE,YAAY,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,EAAE,CAAC;gBAChB,YAAY,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,UAAU,CAAC,GAAiB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG;YACf,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;YAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE;SAC3C,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,MAAc;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG;YACf,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE;YAC7B,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;IACJ,CAAC;IAED,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,gDAAgD;IAChD,4EAA4E;IAE5E;;OAEG;IACK,WAAW,CAAC,KAAY;QAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IAEO,eAAe,CACrB,IAAiB,EACjB,KAAY;QAEZ,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAE/C,uCAAuC;QACvC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC7D,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IACE,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK;YACvD,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EACxD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,sDAAsD;QACtD,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/D,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC;IAED,4EAA4E;IAC5E,wCAAwC;IACxC,4EAA4E;IAE5E;;OAEG;IACH,cAAc,CAAC,GAA6B,EAAE,IAAiB;QAC7D,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE;YAAE,OAAO;QAErD,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,CAAC,2BAA2B;QAEtD,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAEvD,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,SAAS,GAAG,eAAe,CAAC;QAChC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,4EAA4E;IAC5E,UAAU;IACV,4EAA4E;IAEpE,YAAY,CAAC,EAAU;QAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,mBAAmB,CACxE,SAAS,EACT,IAAI,CAAC,YAA6B,CACnC,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;CACF;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,SAAS,WAAW,CAAC,IAAiB;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IACnD,IAAI,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACvB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC;IAC9C,IAAI,EAAE,KAAK,WAAW;QAAE,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;SAC7C,IAAI,EAAE,KAAK,WAAW;QAAE,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;SAClD,IAAI,EAAE,KAAK,YAAY;QAAE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACnF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,GAAkB;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,MAAc;IACtD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IACzC,+BAA+B;IAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAC5C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,MAAc;IACrD,IAAI,CAAC,GAAG,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IACnD,kCAAkC;IAClC,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,IAAiB,EAAE,EAAU;IAC7C,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,qDAAqD;AACrD,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,aAAa,CACpB,MAAyB,EACzB,IAAiB,EACjB,MAA+D,EAC/D,KAAY;IAEZ,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC;IAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC;IAC5B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC;IAChD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,uBAAuB,CAAC;IAC/D,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,QAAQ,GAAG,GAAG,CAAC;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC;IAE5C,MAAM,SAAS,GAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;IAC9E,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAEhE,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAEhB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE5C,qCAAqC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,QAAQ,CAAC;IAChC,IAAI,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAEvE,8CAA8C;IAC9C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACvC,qEAAqE;QACrE,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YACtE,IAAI,aAAa,GAAG,WAAW;gBAAE,WAAW,GAAG,aAAa,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEtC,2CAA2C;IAC3C,IAAI,KAAK,GAAG,QAAQ,CAAC;IACrB,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QACvC,KAAK,GAAG,QAAQ,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;SAAM,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QACvC,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC;IAC9C,CAAC;IAED,6CAA6C;IAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC;IAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClD,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YACd,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC1D,IAAI,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;gBAC5B,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,CAAC,CAAC;YACX,CAAC;YACD,MAAM;QACR,CAAC;IACH,CAAC;IAED,GAAG,CAAC,OAAO,EAAE,CAAC;IACd,OAAO,WAAW,GAAG,IAAI,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAE9E;;;GAGG;AACH,SAAS,iBAAiB,CACxB,GAA6B,EAC7B,IAAiB,EACjB,KAAa,EACb,GAAW;IAEX,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC;IAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC;IAChD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,uBAAuB,CAAC;IAC/D,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,QAAQ,GAAG,GAAG,CAAC;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC;IAE5C,MAAM,SAAS,GAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;IAC9E,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAEhE,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAEhB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;IAErC,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,gCAAgC;IAChC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,UAAU,CAAC;QAC7B,MAAM,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAEzC,sDAAsD;QACtD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC3C,IAAI,GAAG,GAAG,UAAU;gBAAE,UAAU,GAAG,GAAG,CAAC;QACzC,CAAC;QACD,MAAM,eAAe,GAAG,UAAU,CAAC;QACnC,MAAM,aAAa,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;QAE/C,6CAA6C;QAC7C,IAAI,aAAa,IAAI,KAAK,IAAI,eAAe,IAAI,GAAG,EAAE,CAAC;YACrD,UAAU,GAAG,aAAa,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,eAAe,CAAC,CAAC;QAE5D,uCAAuC;QACvC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;QAC9C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3B,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QACpD,CAAC;aAAM,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;YACjC,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9C,CAAC;QAED,4CAA4C;QAC5C,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9D,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAE1D,KAAK,CAAC,IAAI,CAAC;YACT,CAAC,EAAE,KAAK,GAAG,MAAM;YACjB,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,UAAU;YAC7B,KAAK,EAAE,IAAI,GAAG,MAAM;YACpB,MAAM,EAAE,OAAO,CAAC,UAAU;SAC3B,CAAC,CAAC;QAEH,UAAU,GAAG,aAAa,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,OAAO,EAAE,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/canvas/selection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAC;AA4B5B,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAoB;IAC1B,QAAQ,GAAuB,IAAI,CAAC;IACpC,aAAa,CAAa;IAElC,mDAAmD;IACnD,SAAS,GAAyB,IAAI,CAAC;IAEvC,gBAAgB;IACR,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,GAAG,CAAC,CAAC;IACf,aAAa,GAAG,CAAC,CAAC;IAClB,eAAe,GAAG,EAAE,CAAC;IAE7B,iBAAiB;IACT,cAAc,CAA2B;IACzC,cAAc,CAA2B;IACzC,YAAY,CAA2B;IACvC,YAAY,CAA8B;IAElD,YAAY,MAAyB,EAAE,aAAyB;QAC9D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED,WAAW,CAAC,IAAwB;QAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,4EAA4E;IAC5E,eAAe;IACf,4EAA4E;IAEpE,cAAc;QACpB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3D,0DAA0D;QAC1D,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,gBAAgB,CACrE,SAAS,EACT,IAAI,CAAC,YAA6B,CACnC,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,iBAAiB;IACjB,4EAA4E;IAEpE,WAAW,CAAC,CAAa;QAC/B,4EAA4E;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;QACjD,OAAO;YACL,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI;YACxB,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG;SACxB,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,CAAa;QAC/B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,kBAAkB;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;gBACtB,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;YACD,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,IACE,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,GAAG;YAC9B,IAAI,CAAC,eAAe,KAAK,GAAG,CAAC,MAAM,EACnC,CAAC;YACD,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC;QAElC,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YAC1B,4BAA4B;YAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;YAChC,wCAAwC;YACxC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,wCAAwC;YACxC,IAAI,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,WAAW,CAAC,CAAa;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvD,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC;YAC3B,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,EAAc;QAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,SAAS,CAAC,CAAgB;QAChC,MAAM,MAAM,GACV,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;QAC5C,MAAM,WAAW,GACf,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;QAE5C,IAAI,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YACpC,IAAI,IAAI,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBACpE,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBAC7C,gEAAgE;oBAChE,YAAY,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,EAAE,CAAC;gBAChB,YAAY,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,WAAW,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClC,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,UAAU,CAAC,GAAiB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG;YACf,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;YAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE;SAC3C,CAAC;IACJ,CAAC;IAEO,SAAS,CAAC,MAAc;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG;YACf,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE;YAC7B,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;IACJ,CAAC;IAED,eAAe;QACb,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,gDAAgD;IAChD,4EAA4E;IAE5E;;OAEG;IACK,WAAW,CAAC,KAAY;QAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACpD,CAAC;IAEO,eAAe,CACrB,IAAiB,EACjB,KAAY,EACZ,UAAkB,CAAC,EACnB,UAAkB,CAAC;QAEnB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;QAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;QAC7B,MAAM,QAAQ,GACZ,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK;YAC3C,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAE/C,sEAAsE;QACtE,gEAAgE;QAChE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;YACrC,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC1E,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;QAEhE,uCAAuC;QACvC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;YACzF,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,sDAAsD;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,QAAQ,GAAG,gBAAgB,CAC/B,IAAI,EACJ,eAAe,CAAC,IAAI,CAAC,EACrB,CAAC,GAAG,MAAM,CAAC,QAAQ,EACnB,CAAC,GAAG,MAAM,CAAC,QAAQ,CACpB,CAAC;QACF,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC;IAED,4EAA4E;IAC5E,wCAAwC;IACxC,4EAA4E;IAE5E;;OAEG;IACH,cAAc,CAAC,GAA6B,EAAE,IAAiB;QAC7D,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE;YAAE,OAAO;QAErD,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,KAAK,KAAK,GAAG;YAAE,OAAO,CAAC,2BAA2B;QAEtD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC;QAC5B,MAAM,QAAQ,GAAG,gBAAgB,CAC/B,IAAI,EACJ,eAAe,CAAC,IAAI,CAAC,EACrB,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,EAC1B,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAC3B,CAAC;QACF,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAEtD,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,SAAS,GAAG,yBAAyB,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,4EAA4E;IAC5E,UAAU;IACV,4EAA4E;IAEpE,YAAY,CAAC,EAAU;QAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,mBAAmB,CACxE,SAAS,EACT,IAAI,CAAC,YAA6B,CACnC,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;CACF;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,SAAS,cAAc,CAAC,GAAkB;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,MAAc;IACtD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1C,sBAAsB;IACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IACzC,+BAA+B;IAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAC5C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,MAAc;IACrD,IAAI,CAAC,GAAG,MAAM,CAAC;IACf,sBAAsB;IACtB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IACnD,kCAAkC;IAClC,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,EAAE,CAAC;IAClD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,QAAQ,CAAC,IAAiB,EAAE,EAAU;IAC7C,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Geometry
|
|
3
|
+
*
|
|
4
|
+
* Pure point↔offset↔rect math shared by static-text selection
|
|
5
|
+
* (SelectionManager), input caret placement, and selection/caret painting.
|
|
6
|
+
* Everything is parameterized by an explicit {@link TextGeometry} — no
|
|
7
|
+
* node-type assumptions — so the same math serves Text, Input, and Textarea.
|
|
8
|
+
*
|
|
9
|
+
* Font sizes go through `cssLengthToPx` (matching paint.ts) so geometry
|
|
10
|
+
* lines up with painted glyphs even for `rem`-valued props.
|
|
11
|
+
*/
|
|
12
|
+
import type { FontStyle, Point, Rectangle, VirtualNode } from "./types.js";
|
|
13
|
+
/** Selection highlight color shared by static text and input painting. */
|
|
14
|
+
export declare const SELECTION_HIGHLIGHT_COLOR = "rgba(59, 130, 246, 0.35)";
|
|
15
|
+
export interface TextGeometry {
|
|
16
|
+
/** Already-resolved text (node text or input value, post-transform). */
|
|
17
|
+
text: string;
|
|
18
|
+
font: FontStyle;
|
|
19
|
+
textAlign: "left" | "center" | "right";
|
|
20
|
+
verticalAlign: "top" | "middle" | "bottom";
|
|
21
|
+
/** Content-box origin in the coordinate space of queried points / returned rects. */
|
|
22
|
+
contentX: number;
|
|
23
|
+
contentY: number;
|
|
24
|
+
contentWidth: number;
|
|
25
|
+
contentHeight: number;
|
|
26
|
+
/** Width used for line wrapping; undefined = single line (no wrap). */
|
|
27
|
+
wrapWidth?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a node's displayed text, applying `textTransform` the same way
|
|
31
|
+
* paint does — geometry must measure what is actually drawn.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveNodeText(node: VirtualNode): string;
|
|
34
|
+
/** Font style from node props with paint.ts parity defaults. */
|
|
35
|
+
export declare function nodeFontStyle(props: Record<string, any>): FontStyle;
|
|
36
|
+
/**
|
|
37
|
+
* Build a TextGeometry for a node whose content box starts at
|
|
38
|
+
* (contentX, contentY) in the caller's coordinate space. Wrapping and
|
|
39
|
+
* vertical alignment are caller decisions: static text wraps at content
|
|
40
|
+
* width and is top-aligned (paintText parity); single-line inputs don't
|
|
41
|
+
* wrap and are middle-aligned (paintInput parity).
|
|
42
|
+
*/
|
|
43
|
+
export declare function nodeTextGeometry(node: VirtualNode, text: string, contentX: number, contentY: number, opts?: {
|
|
44
|
+
verticalAlign?: TextGeometry["verticalAlign"];
|
|
45
|
+
wrap?: boolean;
|
|
46
|
+
}): TextGeometry;
|
|
47
|
+
/**
|
|
48
|
+
* Character range each wrapped line covers in the original text. Word wrap
|
|
49
|
+
* eats the separator between lines, so line N+1's start is re-anchored with
|
|
50
|
+
* indexOf — same bookkeeping the selection code has always used.
|
|
51
|
+
*/
|
|
52
|
+
export interface LineRange {
|
|
53
|
+
start: number;
|
|
54
|
+
end: number;
|
|
55
|
+
line: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function lineRanges(text: string, lines: string[]): LineRange[];
|
|
58
|
+
/**
|
|
59
|
+
* Map a point to the character offset it falls on.
|
|
60
|
+
*/
|
|
61
|
+
export declare function pointToOffset(ctx: CanvasRenderingContext2D, g: TextGeometry, point: Point): number;
|
|
62
|
+
/**
|
|
63
|
+
* Rectangles covering characters [start, end) — one per wrapped line the
|
|
64
|
+
* range touches. Used for selection highlights.
|
|
65
|
+
*/
|
|
66
|
+
export declare function rangeToRects(ctx: CanvasRenderingContext2D, g: TextGeometry, start: number, end: number): Rectangle[];
|
|
67
|
+
/**
|
|
68
|
+
* Caret rectangle for a character offset. At a wrap boundary the caret
|
|
69
|
+
* sits at the end of the earlier line (matching browser end-of-line
|
|
70
|
+
* placement for soft wraps).
|
|
71
|
+
*/
|
|
72
|
+
export declare function offsetToCaretRect(ctx: CanvasRenderingContext2D, g: TextGeometry, offset: number): Rectangle;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text Geometry
|
|
3
|
+
*
|
|
4
|
+
* Pure point↔offset↔rect math shared by static-text selection
|
|
5
|
+
* (SelectionManager), input caret placement, and selection/caret painting.
|
|
6
|
+
* Everything is parameterized by an explicit {@link TextGeometry} — no
|
|
7
|
+
* node-type assumptions — so the same math serves Text, Input, and Textarea.
|
|
8
|
+
*
|
|
9
|
+
* Font sizes go through `cssLengthToPx` (matching paint.ts) so geometry
|
|
10
|
+
* lines up with painted glyphs even for `rem`-valued props.
|
|
11
|
+
*/
|
|
12
|
+
import { measureText } from "./text.js";
|
|
13
|
+
import { createFontString, cssLengthToPx } from "./utils.js";
|
|
14
|
+
/** Selection highlight color shared by static text and input painting. */
|
|
15
|
+
export const SELECTION_HIGHLIGHT_COLOR = "rgba(59, 130, 246, 0.35)";
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a node's displayed text, applying `textTransform` the same way
|
|
18
|
+
* paint does — geometry must measure what is actually drawn.
|
|
19
|
+
*/
|
|
20
|
+
export function resolveNodeText(node) {
|
|
21
|
+
const raw = node.props[0] || node.props.text || "";
|
|
22
|
+
let text = String(raw);
|
|
23
|
+
const tt = node.props.textTransform || "none";
|
|
24
|
+
if (tt === "uppercase")
|
|
25
|
+
text = text.toUpperCase();
|
|
26
|
+
else if (tt === "lowercase")
|
|
27
|
+
text = text.toLowerCase();
|
|
28
|
+
else if (tt === "capitalize")
|
|
29
|
+
text = text.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
/** Font style from node props with paint.ts parity defaults. */
|
|
33
|
+
export function nodeFontStyle(props) {
|
|
34
|
+
const fontSize = cssLengthToPx(props.fontSize) ?? 16;
|
|
35
|
+
return {
|
|
36
|
+
fontSize,
|
|
37
|
+
fontWeight: props.fontWeight || "normal",
|
|
38
|
+
fontFamily: props.fontFamily || "system-ui, sans-serif",
|
|
39
|
+
lineHeight: cssLengthToPx(props.lineHeight) ?? fontSize * 1.2,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build a TextGeometry for a node whose content box starts at
|
|
44
|
+
* (contentX, contentY) in the caller's coordinate space. Wrapping and
|
|
45
|
+
* vertical alignment are caller decisions: static text wraps at content
|
|
46
|
+
* width and is top-aligned (paintText parity); single-line inputs don't
|
|
47
|
+
* wrap and are middle-aligned (paintInput parity).
|
|
48
|
+
*/
|
|
49
|
+
export function nodeTextGeometry(node, text, contentX, contentY, opts) {
|
|
50
|
+
const layout = node.layout;
|
|
51
|
+
return {
|
|
52
|
+
text,
|
|
53
|
+
font: nodeFontStyle(node.props),
|
|
54
|
+
textAlign: (node.props.textAlign || "left"),
|
|
55
|
+
verticalAlign: opts?.verticalAlign ?? "top",
|
|
56
|
+
contentX,
|
|
57
|
+
contentY,
|
|
58
|
+
contentWidth: layout.contentWidth,
|
|
59
|
+
contentHeight: layout.contentHeight,
|
|
60
|
+
wrapWidth: (opts?.wrap ?? true) ? layout.contentWidth : undefined,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function lineRanges(text, lines) {
|
|
64
|
+
const ranges = [];
|
|
65
|
+
let charOffset = 0;
|
|
66
|
+
for (let i = 0; i < lines.length; i++) {
|
|
67
|
+
if (i > 0) {
|
|
68
|
+
if (lines[i] === "") {
|
|
69
|
+
// A blank line (from a hard "\n\n" or a trailing Enter) can't be
|
|
70
|
+
// re-anchored with indexOf — it sits just past its newline.
|
|
71
|
+
if (text[charOffset] === "\n")
|
|
72
|
+
charOffset += 1;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const idx = text.indexOf(lines[i], charOffset);
|
|
76
|
+
if (idx > charOffset)
|
|
77
|
+
charOffset = idx;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
ranges.push({ start: charOffset, end: charOffset + lines[i].length, line: lines[i] });
|
|
81
|
+
charOffset += lines[i].length;
|
|
82
|
+
}
|
|
83
|
+
return ranges;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Line layout for geometry purposes. Wrapping goes through `measureText`
|
|
87
|
+
* (pretext-aware) per hard-break paragraph. Single-line text (`wrapWidth`
|
|
88
|
+
* undefined) deliberately does NOT: line-layout engines strip trailing
|
|
89
|
+
* whitespace at line ends, which would pin the caret before a just-typed
|
|
90
|
+
* space until the next visible character arrives. A single-line input's
|
|
91
|
+
* "line" is the raw text, spaces and all — `ctx.measureText` advances
|
|
92
|
+
* include them.
|
|
93
|
+
*
|
|
94
|
+
* For wrapped text, each paragraph's stripped whitespace tail is
|
|
95
|
+
* re-attached to its last line for the same reason — a textarea caret must
|
|
96
|
+
* sit after a just-typed space, including one typed right before a newline.
|
|
97
|
+
* (Blank lines from "\n" come from measureText itself.)
|
|
98
|
+
*/
|
|
99
|
+
function layoutLines(ctx, g) {
|
|
100
|
+
const lineHeight = g.font.lineHeight || g.font.fontSize * 1.2;
|
|
101
|
+
if (g.wrapWidth === undefined) {
|
|
102
|
+
return { lines: [g.text], lineHeight, height: lineHeight };
|
|
103
|
+
}
|
|
104
|
+
const lines = [];
|
|
105
|
+
for (const paragraph of g.text.split("\n")) {
|
|
106
|
+
if (paragraph === "") {
|
|
107
|
+
lines.push("");
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const m = measureText(ctx, paragraph, g.font, g.wrapWidth);
|
|
111
|
+
const paragraphLines = [...m.lines];
|
|
112
|
+
// Re-attach the paragraph's trailing whitespace (stripped by wrap
|
|
113
|
+
// layout) so the caret can sit after it.
|
|
114
|
+
const ranges = lineRanges(paragraph, paragraphLines);
|
|
115
|
+
const lastEnd = ranges.length > 0 ? ranges[ranges.length - 1].end : 0;
|
|
116
|
+
const tail = paragraph.slice(lastEnd);
|
|
117
|
+
if (tail.length > 0 && tail.trim() === "") {
|
|
118
|
+
paragraphLines[paragraphLines.length - 1] += tail;
|
|
119
|
+
}
|
|
120
|
+
lines.push(...paragraphLines);
|
|
121
|
+
}
|
|
122
|
+
if (lines.length === 0)
|
|
123
|
+
lines.push("");
|
|
124
|
+
return { lines, lineHeight, height: lines.length * lineHeight };
|
|
125
|
+
}
|
|
126
|
+
function alignedStartY(g, totalHeight) {
|
|
127
|
+
if (g.verticalAlign === "middle")
|
|
128
|
+
return g.contentY + (g.contentHeight - totalHeight) / 2;
|
|
129
|
+
if (g.verticalAlign === "bottom")
|
|
130
|
+
return g.contentY + g.contentHeight - totalHeight;
|
|
131
|
+
return g.contentY;
|
|
132
|
+
}
|
|
133
|
+
function alignedLineX(ctx, g, line) {
|
|
134
|
+
if (g.textAlign === "center") {
|
|
135
|
+
return g.contentX + (g.contentWidth - ctx.measureText(line).width) / 2;
|
|
136
|
+
}
|
|
137
|
+
if (g.textAlign === "right") {
|
|
138
|
+
return g.contentX + g.contentWidth - ctx.measureText(line).width;
|
|
139
|
+
}
|
|
140
|
+
return g.contentX;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Map a point to the character offset it falls on.
|
|
144
|
+
*/
|
|
145
|
+
export function pointToOffset(ctx, g, point) {
|
|
146
|
+
ctx.save();
|
|
147
|
+
ctx.font = createFontString(g.font.fontSize, g.font.fontWeight, g.font.fontFamily);
|
|
148
|
+
const metrics = layoutLines(ctx, g);
|
|
149
|
+
const startY = alignedStartY(g, metrics.height);
|
|
150
|
+
const relY = point.y - startY;
|
|
151
|
+
let lineIndex = Math.floor(relY / metrics.lineHeight);
|
|
152
|
+
lineIndex = Math.max(0, Math.min(lineIndex, metrics.lines.length - 1));
|
|
153
|
+
const ranges = lineRanges(g.text, metrics.lines);
|
|
154
|
+
const { start: lineStart, line } = ranges[lineIndex];
|
|
155
|
+
const relX = point.x - alignedLineX(ctx, g, line);
|
|
156
|
+
// Prefix widths are monotonic in prefix length, so bisect for the longest
|
|
157
|
+
// prefix that fits, then snap to whichever side of the boundary glyph is
|
|
158
|
+
// closer. A point left of the line start clamps to 0.
|
|
159
|
+
let best = 0;
|
|
160
|
+
if (relX > 0) {
|
|
161
|
+
let lo = 0;
|
|
162
|
+
let hi = line.length;
|
|
163
|
+
while (lo < hi) {
|
|
164
|
+
const mid = (lo + hi + 1) >> 1;
|
|
165
|
+
if (ctx.measureText(line.slice(0, mid)).width <= relX) {
|
|
166
|
+
lo = mid;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
hi = mid - 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
best = lo;
|
|
173
|
+
if (lo < line.length) {
|
|
174
|
+
const w = ctx.measureText(line.slice(0, lo)).width;
|
|
175
|
+
const nextW = ctx.measureText(line.slice(0, lo + 1)).width;
|
|
176
|
+
best = relX - w < nextW - relX ? lo : lo + 1;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
ctx.restore();
|
|
180
|
+
return lineStart + best;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Rectangles covering characters [start, end) — one per wrapped line the
|
|
184
|
+
* range touches. Used for selection highlights.
|
|
185
|
+
*/
|
|
186
|
+
export function rangeToRects(ctx, g, start, end) {
|
|
187
|
+
if (start >= end)
|
|
188
|
+
return [];
|
|
189
|
+
ctx.save();
|
|
190
|
+
ctx.font = createFontString(g.font.fontSize, g.font.fontWeight, g.font.fontFamily);
|
|
191
|
+
const metrics = layoutLines(ctx, g);
|
|
192
|
+
const startY = alignedStartY(g, metrics.height);
|
|
193
|
+
const ranges = lineRanges(g.text, metrics.lines);
|
|
194
|
+
const rects = [];
|
|
195
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
196
|
+
const { start: lineStart, end: lineEnd, line } = ranges[i];
|
|
197
|
+
if (lineEnd <= start || lineStart >= end)
|
|
198
|
+
continue;
|
|
199
|
+
const selStart = Math.max(0, start - lineStart);
|
|
200
|
+
const selEnd = Math.min(line.length, end - lineStart);
|
|
201
|
+
const lineX = alignedLineX(ctx, g, line);
|
|
202
|
+
const fromX = ctx.measureText(line.slice(0, selStart)).width;
|
|
203
|
+
const toX = ctx.measureText(line.slice(0, selEnd)).width;
|
|
204
|
+
rects.push({
|
|
205
|
+
x: lineX + fromX,
|
|
206
|
+
y: startY + i * metrics.lineHeight,
|
|
207
|
+
width: toX - fromX,
|
|
208
|
+
height: metrics.lineHeight,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
ctx.restore();
|
|
212
|
+
return rects;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Caret rectangle for a character offset. At a wrap boundary the caret
|
|
216
|
+
* sits at the end of the earlier line (matching browser end-of-line
|
|
217
|
+
* placement for soft wraps).
|
|
218
|
+
*/
|
|
219
|
+
export function offsetToCaretRect(ctx, g, offset) {
|
|
220
|
+
ctx.save();
|
|
221
|
+
ctx.font = createFontString(g.font.fontSize, g.font.fontWeight, g.font.fontFamily);
|
|
222
|
+
const metrics = layoutLines(ctx, g);
|
|
223
|
+
const startY = alignedStartY(g, metrics.height);
|
|
224
|
+
const ranges = lineRanges(g.text, metrics.lines);
|
|
225
|
+
const clamped = Math.max(0, Math.min(offset, g.text.length));
|
|
226
|
+
let lineIndex = ranges.length - 1;
|
|
227
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
228
|
+
if (clamped <= ranges[i].end) {
|
|
229
|
+
lineIndex = i;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const { start: lineStart, line } = ranges[lineIndex];
|
|
234
|
+
const col = Math.max(0, Math.min(clamped - lineStart, line.length));
|
|
235
|
+
const x = alignedLineX(ctx, g, line) + ctx.measureText(line.slice(0, col)).width;
|
|
236
|
+
ctx.restore();
|
|
237
|
+
return {
|
|
238
|
+
x,
|
|
239
|
+
y: startY + lineIndex * metrics.lineHeight,
|
|
240
|
+
width: 1,
|
|
241
|
+
height: metrics.lineHeight,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=text-geometry.js.map
|