@tldraw/editor 5.2.1 → 5.3.0-canary.263f9dbe88bb
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/dist-cjs/index.d.ts +45 -8
- package/dist-cjs/index.js +3 -3
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +2 -2
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/EditorManager.js +52 -0
- package/dist-cjs/lib/editor/managers/EditorManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +9 -11
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +5 -9
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +24 -19
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +4 -7
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +1 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +45 -8
- package/dist-esm/index.mjs +3 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +2 -2
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/EditorManager.mjs +32 -0
- package/dist-esm/lib/editor/managers/EditorManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +9 -11
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +5 -9
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +24 -19
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +4 -7
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +1 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +1 -1
- package/src/lib/editor/Editor.ts +4 -2
- package/src/lib/editor/managers/EditorManager.test.ts +51 -0
- package/src/lib/editor/managers/EditorManager.ts +60 -0
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +2 -1
- package/src/lib/editor/managers/FocusManager/FocusManager.ts +10 -14
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +6 -9
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +61 -1
- package/src/lib/editor/managers/TextManager/TextManager.ts +33 -19
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +0 -10
- package/src/lib/editor/managers/TickManager/TickManager.ts +5 -6
- package/src/lib/editor/shapes/ShapeUtil.ts +1 -0
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +2 -2
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/tools/cancelShapeCreationOnLongPress.js +0 -28
- package/dist-cjs/lib/editor/tools/cancelShapeCreationOnLongPress.js.map +0 -7
- package/dist-esm/lib/editor/tools/cancelShapeCreationOnLongPress.mjs +0 -8
- package/dist-esm/lib/editor/tools/cancelShapeCreationOnLongPress.mjs.map +0 -7
- package/src/lib/editor/tools/cancelShapeCreationOnLongPress.ts +0 -31
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BoxModel, TLDefaultHorizontalAlignStyle } from '@tldraw/tlschema'
|
|
2
2
|
import { objectMapKeys } from '@tldraw/utils'
|
|
3
3
|
import type { Editor } from '../../Editor'
|
|
4
|
+
import { EditorManager } from '../EditorManager'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The whole-pixel line-height for a given font size and tldraw's unitless line-height
|
|
@@ -93,6 +94,10 @@ export interface TLMeasureTextSpanOpts {
|
|
|
93
94
|
|
|
94
95
|
const spaceCharacterRegex = /\s/
|
|
95
96
|
|
|
97
|
+
// Iterate by grapheme cluster (e.g. emoji sequences, flags, accented letters)
|
|
98
|
+
// rather than by code point, so a single glyph is measured as one unit.
|
|
99
|
+
const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' })
|
|
100
|
+
|
|
96
101
|
const initialDefaultStyles = Object.freeze({
|
|
97
102
|
'overflow-wrap': 'break-word',
|
|
98
103
|
'word-break': 'auto',
|
|
@@ -103,13 +108,21 @@ const initialDefaultStyles = Object.freeze({
|
|
|
103
108
|
})
|
|
104
109
|
|
|
105
110
|
/** @public */
|
|
106
|
-
export class TextManager {
|
|
111
|
+
export class TextManager extends EditorManager {
|
|
107
112
|
private elm: HTMLDivElement
|
|
108
113
|
private poolElms: PoolItem[] = []
|
|
109
114
|
|
|
110
|
-
constructor(
|
|
115
|
+
constructor(editor: Editor) {
|
|
116
|
+
super(editor)
|
|
111
117
|
this.elm = this.createMeasurementEl()
|
|
112
118
|
this.editor.getContainer().appendChild(this.elm)
|
|
119
|
+
this.register(() => {
|
|
120
|
+
this.elm.remove()
|
|
121
|
+
for (const { el } of this.poolElms) {
|
|
122
|
+
el.remove()
|
|
123
|
+
}
|
|
124
|
+
this.poolElms.length = 0
|
|
125
|
+
})
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
private createMeasurementEl(): HTMLDivElement {
|
|
@@ -178,14 +191,6 @@ export class TextManager {
|
|
|
178
191
|
}
|
|
179
192
|
}
|
|
180
193
|
|
|
181
|
-
dispose() {
|
|
182
|
-
this.elm.remove()
|
|
183
|
-
for (const { el } of this.poolElms) {
|
|
184
|
-
el.remove()
|
|
185
|
-
}
|
|
186
|
-
this.poolElms.length = 0
|
|
187
|
-
}
|
|
188
|
-
|
|
189
194
|
private ensurePoolSize(size: number) {
|
|
190
195
|
if (this.poolElms.length >= size) return
|
|
191
196
|
|
|
@@ -301,15 +306,24 @@ export class TextManager {
|
|
|
301
306
|
for (const childNode of element.childNodes) {
|
|
302
307
|
if (childNode.nodeType !== Node.TEXT_NODE) continue
|
|
303
308
|
|
|
304
|
-
for (const
|
|
305
|
-
// place the range around the
|
|
309
|
+
for (const { segment } of graphemeSegmenter.segment(childNode.textContent ?? '')) {
|
|
310
|
+
// place the range around the grapheme we're interested in
|
|
306
311
|
range.setStart(textNode, idx)
|
|
307
|
-
range.setEnd(textNode, idx +
|
|
312
|
+
range.setEnd(textNode, idx + segment.length)
|
|
308
313
|
// measure the range. some browsers return multiple rects for the
|
|
309
314
|
// first char in a new line - one for the line break, and one for
|
|
310
315
|
// the character itself. we're only interested in the character.
|
|
311
316
|
const rects = range.getClientRects()
|
|
312
|
-
const rect = rects[rects.length - 1]
|
|
317
|
+
const rect = rects[rects.length - 1]
|
|
318
|
+
|
|
319
|
+
// some graphemes produce no layout rectangle (e.g. zero-width
|
|
320
|
+
// spaces or newlines). skip them rather than crashing, but keep
|
|
321
|
+
// advancing the index so later graphemes stay aligned.
|
|
322
|
+
// See https://github.com/tldraw/tldraw/issues/9112.
|
|
323
|
+
if (!rect) {
|
|
324
|
+
idx += segment.length
|
|
325
|
+
continue
|
|
326
|
+
}
|
|
313
327
|
|
|
314
328
|
// calculate the position of the character relative to the element
|
|
315
329
|
const top = rect.top + offsetY
|
|
@@ -317,7 +331,7 @@ export class TextManager {
|
|
|
317
331
|
const right = rect.right + offsetX
|
|
318
332
|
const isRTL = left < prevCharLeftForRTLTest
|
|
319
333
|
|
|
320
|
-
const isSpaceCharacter = spaceCharacterRegex.test(
|
|
334
|
+
const isSpaceCharacter = spaceCharacterRegex.test(segment)
|
|
321
335
|
if (
|
|
322
336
|
// If we're at a word boundary...
|
|
323
337
|
isSpaceCharacter !== prevCharWasSpaceCharacter ||
|
|
@@ -341,7 +355,7 @@ export class TextManager {
|
|
|
341
355
|
// start a new span
|
|
342
356
|
currentSpan = {
|
|
343
357
|
box: { x: left, y: top, w: rect.width, h: rect.height },
|
|
344
|
-
text:
|
|
358
|
+
text: segment,
|
|
345
359
|
}
|
|
346
360
|
prevCharLeftForRTLTest = left
|
|
347
361
|
} else {
|
|
@@ -352,16 +366,16 @@ export class TextManager {
|
|
|
352
366
|
|
|
353
367
|
// otherwise we just need to extend the current span with the next character
|
|
354
368
|
currentSpan.box.w = isRTL ? currentSpan.box.w + rect.width : right - currentSpan.box.x
|
|
355
|
-
currentSpan.text +=
|
|
369
|
+
currentSpan.text += segment
|
|
356
370
|
}
|
|
357
371
|
|
|
358
|
-
if (
|
|
372
|
+
if (segment === '\n') {
|
|
359
373
|
prevCharLeftForRTLTest = 0
|
|
360
374
|
}
|
|
361
375
|
|
|
362
376
|
prevCharWasSpaceCharacter = isSpaceCharacter
|
|
363
377
|
prevCharTop = top
|
|
364
|
-
idx +=
|
|
378
|
+
idx += segment.length
|
|
365
379
|
}
|
|
366
380
|
}
|
|
367
381
|
|
|
@@ -19,7 +19,6 @@ describe('TickManager', () => {
|
|
|
19
19
|
let editor: Mocked<Editor>
|
|
20
20
|
let tickManager: TickManager
|
|
21
21
|
let mockEmit: Mock
|
|
22
|
-
let mockDisposablesAdd: Mock
|
|
23
22
|
|
|
24
23
|
beforeEach(() => {
|
|
25
24
|
vi.clearAllMocks()
|
|
@@ -38,13 +37,9 @@ describe('TickManager', () => {
|
|
|
38
37
|
mockCancelAnimationFrame.mockImplementation(() => {})
|
|
39
38
|
|
|
40
39
|
mockEmit = vi.fn()
|
|
41
|
-
mockDisposablesAdd = vi.fn()
|
|
42
40
|
|
|
43
41
|
editor = {
|
|
44
42
|
emit: mockEmit,
|
|
45
|
-
disposables: {
|
|
46
|
-
add: mockDisposablesAdd,
|
|
47
|
-
},
|
|
48
43
|
} as unknown as Mocked<Editor>
|
|
49
44
|
|
|
50
45
|
tickManager = new TickManager(editor)
|
|
@@ -58,15 +53,10 @@ describe('TickManager', () => {
|
|
|
58
53
|
|
|
59
54
|
describe('constructor and initialization', () => {
|
|
60
55
|
it('should initialize with correct default values', () => {
|
|
61
|
-
expect(tickManager.editor).toBe(editor)
|
|
62
56
|
expect(tickManager.isPaused).toBe(false)
|
|
63
57
|
expect(tickManager.now).toBe(1000)
|
|
64
58
|
})
|
|
65
59
|
|
|
66
|
-
it('should add dispose method to editor disposables', () => {
|
|
67
|
-
expect(mockDisposablesAdd).toHaveBeenCalledWith(tickManager.dispose)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
60
|
it('should start the tick loop on construction', () => {
|
|
71
61
|
expect(mockRequestAnimationFrame).toHaveBeenCalled()
|
|
72
62
|
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { throttleToNextFrame as _throttleToNextFrame, bind } from '@tldraw/utils'
|
|
2
2
|
import type { Editor } from '../../Editor'
|
|
3
|
+
import { EditorManager } from '../EditorManager'
|
|
3
4
|
|
|
4
5
|
const throttleToNextFrame =
|
|
5
6
|
typeof process !== 'undefined' && process.env.NODE_ENV === 'test'
|
|
@@ -13,9 +14,9 @@ const throttleToNextFrame =
|
|
|
13
14
|
: _throttleToNextFrame
|
|
14
15
|
|
|
15
16
|
/** @internal */
|
|
16
|
-
export class TickManager {
|
|
17
|
-
constructor(
|
|
18
|
-
|
|
17
|
+
export class TickManager extends EditorManager {
|
|
18
|
+
constructor(editor: Editor) {
|
|
19
|
+
super(editor)
|
|
19
20
|
this.start()
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -45,11 +46,9 @@ export class TickManager {
|
|
|
45
46
|
this.cancelRaf = throttleToNextFrame(this.tick)
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
// Clear the listener
|
|
49
|
-
@bind
|
|
50
49
|
dispose() {
|
|
51
50
|
this.isPaused = true
|
|
52
|
-
|
|
53
51
|
this.cancelRaf?.()
|
|
52
|
+
super.dispose()
|
|
54
53
|
}
|
|
55
54
|
}
|
|
@@ -4,7 +4,6 @@ import { Vec } from '../../../../primitives/Vec'
|
|
|
4
4
|
import type { Editor } from '../../../Editor'
|
|
5
5
|
import { TLBaseBoxShape } from '../../../shapes/BaseBoxShapeUtil'
|
|
6
6
|
import { TLPointerEventInfo } from '../../../types/event-types'
|
|
7
|
-
import { cancelShapeCreationOnLongPress } from '../../cancelShapeCreationOnLongPress'
|
|
8
7
|
import { StateNode } from '../../StateNode'
|
|
9
8
|
import type { BaseBoxShapeTool } from '../BaseBoxShapeTool'
|
|
10
9
|
|
|
@@ -67,7 +66,8 @@ export class Pointing extends StateNode {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
override onLongPress() {
|
|
70
|
-
|
|
69
|
+
// On a touch (coarse pointer) long-press, cancel the pending shape so it leaves nothing behind.
|
|
70
|
+
if (this.editor.getInstanceState().isCoarsePointer) this.cancel()
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
override onCancel() {
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '5.
|
|
4
|
+
export const version = '5.3.0-canary.263f9dbe88bb'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2026-05-06T16:28:18.473Z',
|
|
7
|
-
minor: '2026-07-01T09:
|
|
8
|
-
patch: '2026-07-
|
|
7
|
+
minor: '2026-07-01T09:30:40.438Z',
|
|
8
|
+
patch: '2026-07-01T09:30:40.438Z',
|
|
9
9
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var cancelShapeCreationOnLongPress_exports = {};
|
|
20
|
-
__export(cancelShapeCreationOnLongPress_exports, {
|
|
21
|
-
cancelShapeCreationOnLongPress: () => cancelShapeCreationOnLongPress
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(cancelShapeCreationOnLongPress_exports);
|
|
24
|
-
function cancelShapeCreationOnLongPress(editor, cancelPendingCreation) {
|
|
25
|
-
if (!editor.getInstanceState().isCoarsePointer) return;
|
|
26
|
-
cancelPendingCreation();
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=cancelShapeCreationOnLongPress.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/lib/editor/tools/cancelShapeCreationOnLongPress.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Editor } from '../Editor'\n\n/**\n * Shared handler for a long-press in a discrete shape-creation tool's pointing\n * state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels\n * any pending creation so the long-press leaves no shape behind (issue #8277).\n * It does not open a context menu \u2014 that is a select-tool surface, reached on\n * touch only from the select tool, and on desktop from a right-click (which the\n * editor routes through the select tool).\n *\n * Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer\n * powers the deliberate \"pause before drag to start a precise arrow\" gesture,\n * which we must not disturb. The bug only manifests on coarse pointers, because\n * that is also where the browser fires `contextmenu` at the long-press mark.\n *\n * The `cancelPendingCreation` callback is the tool's own cleanup \u2014 it knows\n * whether it needs to `bailToMark` a shape it created early or simply transition\n * back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are\n * excluded: their press is their own action, so they handle (or ignore) the\n * long-press themselves.\n *\n * @internal\n */\nexport function cancelShapeCreationOnLongPress(\n\teditor: Editor,\n\tcancelPendingCreation: () => void\n): void {\n\tif (!editor.getInstanceState().isCoarsePointer) return\n\n\tcancelPendingCreation()\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBO,SAAS,+BACf,QACA,uBACO;AACP,MAAI,CAAC,OAAO,iBAAiB,EAAE,gBAAiB;AAEhD,wBAAsB;AACvB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
function cancelShapeCreationOnLongPress(editor, cancelPendingCreation) {
|
|
2
|
-
if (!editor.getInstanceState().isCoarsePointer) return;
|
|
3
|
-
cancelPendingCreation();
|
|
4
|
-
}
|
|
5
|
-
export {
|
|
6
|
-
cancelShapeCreationOnLongPress
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=cancelShapeCreationOnLongPress.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/lib/editor/tools/cancelShapeCreationOnLongPress.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Editor } from '../Editor'\n\n/**\n * Shared handler for a long-press in a discrete shape-creation tool's pointing\n * state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels\n * any pending creation so the long-press leaves no shape behind (issue #8277).\n * It does not open a context menu \u2014 that is a select-tool surface, reached on\n * touch only from the select tool, and on desktop from a right-click (which the\n * editor routes through the select tool).\n *\n * Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer\n * powers the deliberate \"pause before drag to start a precise arrow\" gesture,\n * which we must not disturb. The bug only manifests on coarse pointers, because\n * that is also where the browser fires `contextmenu` at the long-press mark.\n *\n * The `cancelPendingCreation` callback is the tool's own cleanup \u2014 it knows\n * whether it needs to `bailToMark` a shape it created early or simply transition\n * back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are\n * excluded: their press is their own action, so they handle (or ignore) the\n * long-press themselves.\n *\n * @internal\n */\nexport function cancelShapeCreationOnLongPress(\n\teditor: Editor,\n\tcancelPendingCreation: () => void\n): void {\n\tif (!editor.getInstanceState().isCoarsePointer) return\n\n\tcancelPendingCreation()\n}\n"],
|
|
5
|
-
"mappings": "AAuBO,SAAS,+BACf,QACA,uBACO;AACP,MAAI,CAAC,OAAO,iBAAiB,EAAE,gBAAiB;AAEhD,wBAAsB;AACvB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { Editor } from '../Editor'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Shared handler for a long-press in a discrete shape-creation tool's pointing
|
|
5
|
-
* state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels
|
|
6
|
-
* any pending creation so the long-press leaves no shape behind (issue #8277).
|
|
7
|
-
* It does not open a context menu — that is a select-tool surface, reached on
|
|
8
|
-
* touch only from the select tool, and on desktop from a right-click (which the
|
|
9
|
-
* editor routes through the select tool).
|
|
10
|
-
*
|
|
11
|
-
* Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer
|
|
12
|
-
* powers the deliberate "pause before drag to start a precise arrow" gesture,
|
|
13
|
-
* which we must not disturb. The bug only manifests on coarse pointers, because
|
|
14
|
-
* that is also where the browser fires `contextmenu` at the long-press mark.
|
|
15
|
-
*
|
|
16
|
-
* The `cancelPendingCreation` callback is the tool's own cleanup — it knows
|
|
17
|
-
* whether it needs to `bailToMark` a shape it created early or simply transition
|
|
18
|
-
* back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are
|
|
19
|
-
* excluded: their press is their own action, so they handle (or ignore) the
|
|
20
|
-
* long-press themselves.
|
|
21
|
-
*
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
export function cancelShapeCreationOnLongPress(
|
|
25
|
-
editor: Editor,
|
|
26
|
-
cancelPendingCreation: () => void
|
|
27
|
-
): void {
|
|
28
|
-
if (!editor.getInstanceState().isCoarsePointer) return
|
|
29
|
-
|
|
30
|
-
cancelPendingCreation()
|
|
31
|
-
}
|