@rtif-sdk/web 1.0.0

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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/block-drag-handler.d.ts +189 -0
  4. package/dist/block-drag-handler.d.ts.map +1 -0
  5. package/dist/block-drag-handler.js +745 -0
  6. package/dist/block-drag-handler.js.map +1 -0
  7. package/dist/block-renderer.d.ts +402 -0
  8. package/dist/block-renderer.d.ts.map +1 -0
  9. package/dist/block-renderer.js +424 -0
  10. package/dist/block-renderer.js.map +1 -0
  11. package/dist/clipboard.d.ts +178 -0
  12. package/dist/clipboard.d.ts.map +1 -0
  13. package/dist/clipboard.js +432 -0
  14. package/dist/clipboard.js.map +1 -0
  15. package/dist/command-bus.d.ts +113 -0
  16. package/dist/command-bus.d.ts.map +1 -0
  17. package/dist/command-bus.js +70 -0
  18. package/dist/command-bus.js.map +1 -0
  19. package/dist/composition.d.ts +220 -0
  20. package/dist/composition.d.ts.map +1 -0
  21. package/dist/composition.js +271 -0
  22. package/dist/composition.js.map +1 -0
  23. package/dist/content-extraction.d.ts +69 -0
  24. package/dist/content-extraction.d.ts.map +1 -0
  25. package/dist/content-extraction.js +228 -0
  26. package/dist/content-extraction.js.map +1 -0
  27. package/dist/content-handler-file.d.ts +40 -0
  28. package/dist/content-handler-file.d.ts.map +1 -0
  29. package/dist/content-handler-file.js +91 -0
  30. package/dist/content-handler-file.js.map +1 -0
  31. package/dist/content-handler-image.d.ts +82 -0
  32. package/dist/content-handler-image.d.ts.map +1 -0
  33. package/dist/content-handler-image.js +120 -0
  34. package/dist/content-handler-image.js.map +1 -0
  35. package/dist/content-handler-url.d.ts +129 -0
  36. package/dist/content-handler-url.d.ts.map +1 -0
  37. package/dist/content-handler-url.js +244 -0
  38. package/dist/content-handler-url.js.map +1 -0
  39. package/dist/content-handlers.d.ts +67 -0
  40. package/dist/content-handlers.d.ts.map +1 -0
  41. package/dist/content-handlers.js +263 -0
  42. package/dist/content-handlers.js.map +1 -0
  43. package/dist/content-pipeline.d.ts +383 -0
  44. package/dist/content-pipeline.d.ts.map +1 -0
  45. package/dist/content-pipeline.js +232 -0
  46. package/dist/content-pipeline.js.map +1 -0
  47. package/dist/cursor-nav.d.ts +149 -0
  48. package/dist/cursor-nav.d.ts.map +1 -0
  49. package/dist/cursor-nav.js +230 -0
  50. package/dist/cursor-nav.js.map +1 -0
  51. package/dist/cursor-rect.d.ts +65 -0
  52. package/dist/cursor-rect.d.ts.map +1 -0
  53. package/dist/cursor-rect.js +98 -0
  54. package/dist/cursor-rect.js.map +1 -0
  55. package/dist/drop-indicator.d.ts +108 -0
  56. package/dist/drop-indicator.d.ts.map +1 -0
  57. package/dist/drop-indicator.js +236 -0
  58. package/dist/drop-indicator.js.map +1 -0
  59. package/dist/editor.d.ts +41 -0
  60. package/dist/editor.d.ts.map +1 -0
  61. package/dist/editor.js +710 -0
  62. package/dist/editor.js.map +1 -0
  63. package/dist/floating-toolbar.d.ts +93 -0
  64. package/dist/floating-toolbar.d.ts.map +1 -0
  65. package/dist/floating-toolbar.js +159 -0
  66. package/dist/floating-toolbar.js.map +1 -0
  67. package/dist/index.d.ts +62 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +119 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/input-bridge.d.ts +273 -0
  72. package/dist/input-bridge.d.ts.map +1 -0
  73. package/dist/input-bridge.js +884 -0
  74. package/dist/input-bridge.js.map +1 -0
  75. package/dist/link-popover.d.ts +38 -0
  76. package/dist/link-popover.d.ts.map +1 -0
  77. package/dist/link-popover.js +278 -0
  78. package/dist/link-popover.js.map +1 -0
  79. package/dist/mark-renderer.d.ts +275 -0
  80. package/dist/mark-renderer.d.ts.map +1 -0
  81. package/dist/mark-renderer.js +210 -0
  82. package/dist/mark-renderer.js.map +1 -0
  83. package/dist/perf.d.ts +145 -0
  84. package/dist/perf.d.ts.map +1 -0
  85. package/dist/perf.js +260 -0
  86. package/dist/perf.js.map +1 -0
  87. package/dist/plugin-kit.d.ts +265 -0
  88. package/dist/plugin-kit.d.ts.map +1 -0
  89. package/dist/plugin-kit.js +234 -0
  90. package/dist/plugin-kit.js.map +1 -0
  91. package/dist/plugins/alignment-plugin.d.ts +68 -0
  92. package/dist/plugins/alignment-plugin.d.ts.map +1 -0
  93. package/dist/plugins/alignment-plugin.js +98 -0
  94. package/dist/plugins/alignment-plugin.js.map +1 -0
  95. package/dist/plugins/block-utils.d.ts +113 -0
  96. package/dist/plugins/block-utils.d.ts.map +1 -0
  97. package/dist/plugins/block-utils.js +191 -0
  98. package/dist/plugins/block-utils.js.map +1 -0
  99. package/dist/plugins/blockquote-plugin.d.ts +39 -0
  100. package/dist/plugins/blockquote-plugin.d.ts.map +1 -0
  101. package/dist/plugins/blockquote-plugin.js +88 -0
  102. package/dist/plugins/blockquote-plugin.js.map +1 -0
  103. package/dist/plugins/bold-plugin.d.ts +37 -0
  104. package/dist/plugins/bold-plugin.d.ts.map +1 -0
  105. package/dist/plugins/bold-plugin.js +48 -0
  106. package/dist/plugins/bold-plugin.js.map +1 -0
  107. package/dist/plugins/callout-plugin.d.ts +100 -0
  108. package/dist/plugins/callout-plugin.d.ts.map +1 -0
  109. package/dist/plugins/callout-plugin.js +200 -0
  110. package/dist/plugins/callout-plugin.js.map +1 -0
  111. package/dist/plugins/code-block-plugin.d.ts +62 -0
  112. package/dist/plugins/code-block-plugin.d.ts.map +1 -0
  113. package/dist/plugins/code-block-plugin.js +176 -0
  114. package/dist/plugins/code-block-plugin.js.map +1 -0
  115. package/dist/plugins/code-plugin.d.ts +37 -0
  116. package/dist/plugins/code-plugin.d.ts.map +1 -0
  117. package/dist/plugins/code-plugin.js +48 -0
  118. package/dist/plugins/code-plugin.js.map +1 -0
  119. package/dist/plugins/embed-plugin.d.ts +90 -0
  120. package/dist/plugins/embed-plugin.d.ts.map +1 -0
  121. package/dist/plugins/embed-plugin.js +147 -0
  122. package/dist/plugins/embed-plugin.js.map +1 -0
  123. package/dist/plugins/font-family-plugin.d.ts +58 -0
  124. package/dist/plugins/font-family-plugin.d.ts.map +1 -0
  125. package/dist/plugins/font-family-plugin.js +57 -0
  126. package/dist/plugins/font-family-plugin.js.map +1 -0
  127. package/dist/plugins/font-size-plugin.d.ts +57 -0
  128. package/dist/plugins/font-size-plugin.d.ts.map +1 -0
  129. package/dist/plugins/font-size-plugin.js +56 -0
  130. package/dist/plugins/font-size-plugin.js.map +1 -0
  131. package/dist/plugins/heading-plugin.d.ts +52 -0
  132. package/dist/plugins/heading-plugin.d.ts.map +1 -0
  133. package/dist/plugins/heading-plugin.js +114 -0
  134. package/dist/plugins/heading-plugin.js.map +1 -0
  135. package/dist/plugins/hr-plugin.d.ts +33 -0
  136. package/dist/plugins/hr-plugin.d.ts.map +1 -0
  137. package/dist/plugins/hr-plugin.js +75 -0
  138. package/dist/plugins/hr-plugin.js.map +1 -0
  139. package/dist/plugins/image-plugin.d.ts +115 -0
  140. package/dist/plugins/image-plugin.d.ts.map +1 -0
  141. package/dist/plugins/image-plugin.js +199 -0
  142. package/dist/plugins/image-plugin.js.map +1 -0
  143. package/dist/plugins/indent-plugin.d.ts +62 -0
  144. package/dist/plugins/indent-plugin.d.ts.map +1 -0
  145. package/dist/plugins/indent-plugin.js +128 -0
  146. package/dist/plugins/indent-plugin.js.map +1 -0
  147. package/dist/plugins/index.d.ts +45 -0
  148. package/dist/plugins/index.d.ts.map +1 -0
  149. package/dist/plugins/index.js +42 -0
  150. package/dist/plugins/index.js.map +1 -0
  151. package/dist/plugins/italic-plugin.d.ts +37 -0
  152. package/dist/plugins/italic-plugin.d.ts.map +1 -0
  153. package/dist/plugins/italic-plugin.js +48 -0
  154. package/dist/plugins/italic-plugin.js.map +1 -0
  155. package/dist/plugins/link-plugin.d.ts +129 -0
  156. package/dist/plugins/link-plugin.d.ts.map +1 -0
  157. package/dist/plugins/link-plugin.js +212 -0
  158. package/dist/plugins/link-plugin.js.map +1 -0
  159. package/dist/plugins/list-plugin.d.ts +53 -0
  160. package/dist/plugins/list-plugin.d.ts.map +1 -0
  161. package/dist/plugins/list-plugin.js +309 -0
  162. package/dist/plugins/list-plugin.js.map +1 -0
  163. package/dist/plugins/mark-utils.d.ts +173 -0
  164. package/dist/plugins/mark-utils.d.ts.map +1 -0
  165. package/dist/plugins/mark-utils.js +425 -0
  166. package/dist/plugins/mark-utils.js.map +1 -0
  167. package/dist/plugins/mention-plugin.d.ts +191 -0
  168. package/dist/plugins/mention-plugin.d.ts.map +1 -0
  169. package/dist/plugins/mention-plugin.js +295 -0
  170. package/dist/plugins/mention-plugin.js.map +1 -0
  171. package/dist/plugins/strikethrough-plugin.d.ts +37 -0
  172. package/dist/plugins/strikethrough-plugin.d.ts.map +1 -0
  173. package/dist/plugins/strikethrough-plugin.js +48 -0
  174. package/dist/plugins/strikethrough-plugin.js.map +1 -0
  175. package/dist/plugins/text-color-plugin.d.ts +57 -0
  176. package/dist/plugins/text-color-plugin.d.ts.map +1 -0
  177. package/dist/plugins/text-color-plugin.js +56 -0
  178. package/dist/plugins/text-color-plugin.js.map +1 -0
  179. package/dist/plugins/underline-plugin.d.ts +37 -0
  180. package/dist/plugins/underline-plugin.d.ts.map +1 -0
  181. package/dist/plugins/underline-plugin.js +48 -0
  182. package/dist/plugins/underline-plugin.js.map +1 -0
  183. package/dist/presets.d.ts +95 -0
  184. package/dist/presets.d.ts.map +1 -0
  185. package/dist/presets.js +159 -0
  186. package/dist/presets.js.map +1 -0
  187. package/dist/renderer.d.ts +125 -0
  188. package/dist/renderer.d.ts.map +1 -0
  189. package/dist/renderer.js +415 -0
  190. package/dist/renderer.js.map +1 -0
  191. package/dist/scroll-to-cursor.d.ts +25 -0
  192. package/dist/scroll-to-cursor.d.ts.map +1 -0
  193. package/dist/scroll-to-cursor.js +59 -0
  194. package/dist/scroll-to-cursor.js.map +1 -0
  195. package/dist/selection-sync.d.ts +159 -0
  196. package/dist/selection-sync.d.ts.map +1 -0
  197. package/dist/selection-sync.js +527 -0
  198. package/dist/selection-sync.js.map +1 -0
  199. package/dist/shortcut-handler.d.ts +98 -0
  200. package/dist/shortcut-handler.d.ts.map +1 -0
  201. package/dist/shortcut-handler.js +155 -0
  202. package/dist/shortcut-handler.js.map +1 -0
  203. package/dist/toolbar.d.ts +103 -0
  204. package/dist/toolbar.d.ts.map +1 -0
  205. package/dist/toolbar.js +134 -0
  206. package/dist/toolbar.js.map +1 -0
  207. package/dist/trigger-manager.d.ts +205 -0
  208. package/dist/trigger-manager.d.ts.map +1 -0
  209. package/dist/trigger-manager.js +466 -0
  210. package/dist/trigger-manager.js.map +1 -0
  211. package/dist/types.d.ts +216 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +2 -0
  214. package/dist/types.js.map +1 -0
  215. package/package.json +30 -0
@@ -0,0 +1,466 @@
1
+ /**
2
+ * Generic trigger infrastructure for character-triggered interactions.
3
+ *
4
+ * Detects trigger characters (e.g., `@`, `#`, `/`), manages TriggerSession
5
+ * lifecycle, handles keyboard routing and dismissal. Fully reusable for
6
+ * @mentions, #hashtags, /slash-commands, etc.
7
+ *
8
+ * @module
9
+ */
10
+ import { resolve } from '@rtif-sdk/core';
11
+ // ---------------------------------------------------------------------------
12
+ // Implementation
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Create a TriggerManager instance.
16
+ *
17
+ * The trigger manager detects trigger characters, manages sessions,
18
+ * and handles keyboard routing. Attach its keydown listener BEFORE
19
+ * the shortcut handler for correct priority.
20
+ *
21
+ * @param deps - Dependencies for the trigger manager
22
+ * @returns A TriggerManager instance
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const triggerManager = createTriggerManager({
27
+ * root, engine, cursorRect,
28
+ * isComposing: () => compositionHandler.isComposing(),
29
+ * });
30
+ * ```
31
+ */
32
+ export function createTriggerManager(deps) {
33
+ const { root, engine, cursorRect, isComposing } = deps;
34
+ const triggers = new Map();
35
+ let sortedTriggers = [];
36
+ let activeSession = null;
37
+ let cachedSessionObj = null;
38
+ let destroyed = false;
39
+ let positionListenersAttached = false;
40
+ let rafPending = false;
41
+ // -------------------------------------------------------------------
42
+ // Scroll / resize position listeners
43
+ // -------------------------------------------------------------------
44
+ function onPositionMayHaveChanged() {
45
+ if (!activeSession || activeSession.accepted)
46
+ return;
47
+ if (!activeSession.config.onPositionChange)
48
+ return;
49
+ if (rafPending)
50
+ return;
51
+ rafPending = true;
52
+ requestAnimationFrame(() => {
53
+ rafPending = false;
54
+ if (!activeSession || activeSession.accepted)
55
+ return;
56
+ activeSession.config.onPositionChange?.(createSessionObject(activeSession));
57
+ });
58
+ }
59
+ function attachPositionListeners() {
60
+ if (positionListenersAttached)
61
+ return;
62
+ positionListenersAttached = true;
63
+ window.addEventListener('scroll', onPositionMayHaveChanged, { capture: true, passive: true });
64
+ window.addEventListener('resize', onPositionMayHaveChanged, { passive: true });
65
+ }
66
+ function detachPositionListeners() {
67
+ if (!positionListenersAttached)
68
+ return;
69
+ positionListenersAttached = false;
70
+ window.removeEventListener('scroll', onPositionMayHaveChanged, true);
71
+ window.removeEventListener('resize', onPositionMayHaveChanged);
72
+ rafPending = false;
73
+ }
74
+ // -------------------------------------------------------------------
75
+ // Sorted trigger cache — longer triggers first for prefix priority
76
+ // -------------------------------------------------------------------
77
+ function rebuildSortedTriggers() {
78
+ sortedTriggers = [...triggers.values()].sort((a, b) => b.char.length - a.char.length);
79
+ }
80
+ // -------------------------------------------------------------------
81
+ // Session object factory
82
+ // -------------------------------------------------------------------
83
+ function createSessionObject(state) {
84
+ // Cache hit: same engine state reference → same query
85
+ if (cachedSessionObj && cachedSessionObj.engineState === engine.state && activeSession === state) {
86
+ return cachedSessionObj.session;
87
+ }
88
+ const query = computeQuery(state);
89
+ const session = {
90
+ trigger: state.config,
91
+ triggerOffset: state.triggerOffset,
92
+ query,
93
+ getTriggerRect: () => cursorRect.getRectAtOffset(state.triggerOffset),
94
+ getCursorRect: () => cursorRect.getCursorRect(),
95
+ accept: (result) => acceptSession(state, result),
96
+ dismiss: () => dismissSession(state),
97
+ isActive: () => activeSession === state && !state.accepted,
98
+ };
99
+ cachedSessionObj = { engineState: engine.state, session };
100
+ return session;
101
+ }
102
+ function computeQuery(state) {
103
+ const doc = engine.state.doc;
104
+ const focusOffset = engine.state.selection.focus.offset;
105
+ const charLen = state.config.char.length;
106
+ const queryStartOffset = state.triggerOffset + charLen;
107
+ if (focusOffset < queryStartOffset)
108
+ return '';
109
+ // Resolve to block to extract text
110
+ try {
111
+ const resolved = resolve(doc, state.triggerOffset);
112
+ const block = doc.blocks[resolved.blockIndex];
113
+ if (!block)
114
+ return '';
115
+ const blockText = getBlockText(block);
116
+ const localQueryStart = resolved.localOffset + charLen;
117
+ const focusResolved = resolve(doc, focusOffset);
118
+ // Must be same block
119
+ if (focusResolved.blockIndex !== resolved.blockIndex)
120
+ return '';
121
+ return blockText.substring(localQueryStart, focusResolved.localOffset);
122
+ }
123
+ catch {
124
+ return '';
125
+ }
126
+ }
127
+ // -------------------------------------------------------------------
128
+ // Accept / Dismiss
129
+ // -------------------------------------------------------------------
130
+ function acceptSession(state, result) {
131
+ if (activeSession !== state || state.accepted)
132
+ return;
133
+ state.accepted = true;
134
+ cachedSessionObj = null;
135
+ const focusOffset = engine.state.selection.focus.offset;
136
+ const deleteCount = focusOffset - state.triggerOffset;
137
+ const appendSpace = result.appendSpace !== false;
138
+ // Build operations as a single batch for one undo group
139
+ const ops = [];
140
+ // 1. Delete trigger + query text
141
+ if (deleteCount > 0) {
142
+ ops.push({
143
+ type: 'delete_text',
144
+ offset: state.triggerOffset,
145
+ count: deleteCount,
146
+ });
147
+ }
148
+ // 2. Insert result text
149
+ ops.push({
150
+ type: 'insert_text',
151
+ offset: state.triggerOffset,
152
+ text: result.text,
153
+ });
154
+ // 3. Apply marks if provided
155
+ if (result.marks && Object.keys(result.marks).length > 0) {
156
+ ops.push({
157
+ type: 'set_span_marks',
158
+ offset: state.triggerOffset,
159
+ count: result.text.length,
160
+ marks: result.marks,
161
+ });
162
+ }
163
+ // 4. Append space if requested
164
+ if (appendSpace) {
165
+ ops.push({
166
+ type: 'insert_text',
167
+ offset: state.triggerOffset + result.text.length,
168
+ text: ' ',
169
+ });
170
+ // 5. Strip inherited marks from the space so it forms a separate
171
+ // editable span. Without this, insert_text at the span boundary
172
+ // inherits the preceding span's marks (e.g., mention with
173
+ // contenteditable="false"), making the space non-editable and
174
+ // preventing further typing.
175
+ if (result.marks && Object.keys(result.marks).length > 0) {
176
+ const clearMarks = {};
177
+ for (const key of Object.keys(result.marks)) {
178
+ clearMarks[key] = null;
179
+ }
180
+ ops.push({
181
+ type: 'set_span_marks',
182
+ offset: state.triggerOffset + result.text.length,
183
+ count: 1,
184
+ marks: clearMarks,
185
+ });
186
+ }
187
+ }
188
+ engine.dispatch(ops);
189
+ const config = state.config;
190
+ activeSession = null;
191
+ detachPositionListeners();
192
+ config.onDeactivate?.('accepted');
193
+ }
194
+ function dismissSession(state) {
195
+ if (activeSession !== state || state.accepted)
196
+ return;
197
+ detachPositionListeners();
198
+ const config = state.config;
199
+ activeSession = null;
200
+ config.onDeactivate?.('dismissed');
201
+ }
202
+ // -------------------------------------------------------------------
203
+ // Activation logic
204
+ // -------------------------------------------------------------------
205
+ function checkForActivation() {
206
+ if (isComposing())
207
+ return;
208
+ if (activeSession)
209
+ return;
210
+ const { selection, doc } = engine.state;
211
+ // Must be collapsed cursor
212
+ if (selection.anchor.offset !== selection.focus.offset)
213
+ return;
214
+ const focusOffset = selection.focus.offset;
215
+ for (const config of sortedTriggers) {
216
+ if (shouldActivate(config, doc, focusOffset)) {
217
+ // Partial trigger guard: ensure no registered longer trigger is a prefix superset.
218
+ // e.g., if "[[" is registered, single "[" should not activate until we know
219
+ // it's not the start of "[[".
220
+ let blockedByLongerTrigger = false;
221
+ for (const other of sortedTriggers) {
222
+ if (other.char.length <= config.char.length)
223
+ break; // sorted desc, no longer triggers remain
224
+ if (other.char.startsWith(config.char)) {
225
+ blockedByLongerTrigger = true;
226
+ break;
227
+ }
228
+ }
229
+ if (blockedByLongerTrigger)
230
+ continue;
231
+ const triggerOffset = focusOffset - config.char.length;
232
+ let blockIndex;
233
+ try {
234
+ blockIndex = resolve(doc, triggerOffset).blockIndex;
235
+ }
236
+ catch {
237
+ continue;
238
+ }
239
+ activeSession = {
240
+ config,
241
+ triggerOffset,
242
+ triggerBlockIndex: blockIndex,
243
+ accepted: false,
244
+ };
245
+ config.onActivate(createSessionObject(activeSession));
246
+ attachPositionListeners();
247
+ return;
248
+ }
249
+ }
250
+ }
251
+ function shouldActivate(config, doc, focusOffset) {
252
+ const charLen = config.char.length;
253
+ if (focusOffset < charLen)
254
+ return false;
255
+ const triggerOffset = focusOffset - charLen;
256
+ // Resolve trigger offset
257
+ let resolved;
258
+ try {
259
+ resolved = resolve(doc, triggerOffset);
260
+ }
261
+ catch {
262
+ return false;
263
+ }
264
+ const block = doc.blocks[resolved.blockIndex];
265
+ if (!block)
266
+ return false;
267
+ const blockText = getBlockText(block);
268
+ const localOffset = resolved.localOffset;
269
+ // Check that the trigger char is present at this position
270
+ const candidate = blockText.substring(localOffset, localOffset + charLen);
271
+ if (candidate !== config.char)
272
+ return false;
273
+ // Check position constraint
274
+ const position = config.position ?? 'after-whitespace';
275
+ if (position === 'start') {
276
+ if (localOffset !== 0)
277
+ return false;
278
+ }
279
+ else if (position === 'after-whitespace') {
280
+ if (localOffset > 0) {
281
+ const charBefore = blockText[localOffset - 1];
282
+ if (charBefore !== undefined && !/\s/.test(charBefore))
283
+ return false;
284
+ }
285
+ }
286
+ // 'anywhere' — no constraint
287
+ return true;
288
+ }
289
+ // -------------------------------------------------------------------
290
+ // Session validity check
291
+ // -------------------------------------------------------------------
292
+ function checkSessionValidity() {
293
+ if (!activeSession || activeSession.accepted)
294
+ return;
295
+ const { selection, doc } = engine.state;
296
+ // Must be collapsed
297
+ if (selection.anchor.offset !== selection.focus.offset) {
298
+ deactivate('cursor-moved');
299
+ return;
300
+ }
301
+ const focusOffset = selection.focus.offset;
302
+ const charLen = activeSession.config.char.length;
303
+ // Cursor must be at or after trigger + char
304
+ if (focusOffset < activeSession.triggerOffset + charLen) {
305
+ deactivate('deleted');
306
+ return;
307
+ }
308
+ // Trigger offset must still be in valid range
309
+ let resolved;
310
+ try {
311
+ resolved = resolve(doc, activeSession.triggerOffset);
312
+ }
313
+ catch {
314
+ deactivate('deleted');
315
+ return;
316
+ }
317
+ // Must still be same block
318
+ if (resolved.blockIndex !== activeSession.triggerBlockIndex) {
319
+ deactivate('cursor-moved');
320
+ return;
321
+ }
322
+ // Trigger char must still be present
323
+ const block = doc.blocks[resolved.blockIndex];
324
+ if (!block) {
325
+ deactivate('deleted');
326
+ return;
327
+ }
328
+ const blockText = getBlockText(block);
329
+ const candidate = blockText.substring(resolved.localOffset, resolved.localOffset + charLen);
330
+ if (candidate !== activeSession.config.char) {
331
+ deactivate('deleted');
332
+ return;
333
+ }
334
+ // Cursor must be in same block
335
+ let focusResolved;
336
+ try {
337
+ focusResolved = resolve(doc, focusOffset);
338
+ }
339
+ catch {
340
+ deactivate('cursor-moved');
341
+ return;
342
+ }
343
+ if (focusResolved.blockIndex !== activeSession.triggerBlockIndex) {
344
+ deactivate('cursor-moved');
345
+ return;
346
+ }
347
+ // Check cancelOnSpace
348
+ if (activeSession.config.cancelOnSpace) {
349
+ const query = computeQuery(activeSession);
350
+ if (query.includes(' ')) {
351
+ deactivate('cursor-moved');
352
+ return;
353
+ }
354
+ }
355
+ // Session is still valid — notify onChange
356
+ activeSession.config.onChange?.(createSessionObject(activeSession));
357
+ }
358
+ function deactivate(reason) {
359
+ if (!activeSession)
360
+ return;
361
+ detachPositionListeners();
362
+ const config = activeSession.config;
363
+ activeSession = null;
364
+ cachedSessionObj = null;
365
+ config.onDeactivate?.(reason);
366
+ }
367
+ // -------------------------------------------------------------------
368
+ // State change handlers
369
+ // -------------------------------------------------------------------
370
+ function onStateChange() {
371
+ if (destroyed)
372
+ return;
373
+ if (isComposing())
374
+ return;
375
+ if (triggers.size === 0 && !activeSession)
376
+ return;
377
+ if (activeSession && !activeSession.accepted) {
378
+ checkSessionValidity();
379
+ }
380
+ else {
381
+ checkForActivation();
382
+ }
383
+ }
384
+ const unsubChange = engine.onChange(onStateChange);
385
+ const unsubSelChange = engine.onSelectionChange(onStateChange);
386
+ // -------------------------------------------------------------------
387
+ // Keydown handler (capture phase, before shortcuts)
388
+ // -------------------------------------------------------------------
389
+ function onKeyDown(e) {
390
+ if (destroyed)
391
+ return;
392
+ if (!activeSession || activeSession.accepted)
393
+ return;
394
+ // Escape always dismisses
395
+ if (e.key === 'Escape') {
396
+ e.preventDefault();
397
+ e.stopPropagation();
398
+ dismissSession(activeSession);
399
+ return;
400
+ }
401
+ // Route to config.onKeyDown
402
+ if (activeSession.config.onKeyDown) {
403
+ const session = createSessionObject(activeSession);
404
+ const handled = activeSession.config.onKeyDown(session, e);
405
+ if (handled) {
406
+ e.preventDefault();
407
+ e.stopPropagation();
408
+ }
409
+ }
410
+ }
411
+ root.addEventListener('keydown', onKeyDown, true);
412
+ // -------------------------------------------------------------------
413
+ // Public API
414
+ // -------------------------------------------------------------------
415
+ return {
416
+ register(config) {
417
+ triggers.set(config.id, config);
418
+ rebuildSortedTriggers();
419
+ return {
420
+ dispose() {
421
+ triggers.delete(config.id);
422
+ rebuildSortedTriggers();
423
+ // If the active session was for this trigger, deactivate
424
+ if (activeSession && activeSession.config.id === config.id) {
425
+ deactivate('dismissed');
426
+ }
427
+ },
428
+ };
429
+ },
430
+ getActiveSession() {
431
+ if (!activeSession || activeSession.accepted)
432
+ return null;
433
+ return createSessionObject(activeSession);
434
+ },
435
+ isActive() {
436
+ return activeSession !== null && !activeSession.accepted;
437
+ },
438
+ destroy() {
439
+ if (destroyed)
440
+ return;
441
+ destroyed = true;
442
+ if (activeSession && !activeSession.accepted) {
443
+ deactivate('dismissed');
444
+ }
445
+ detachPositionListeners();
446
+ root.removeEventListener('keydown', onKeyDown, true);
447
+ unsubChange();
448
+ unsubSelChange();
449
+ triggers.clear();
450
+ sortedTriggers = [];
451
+ cachedSessionObj = null;
452
+ },
453
+ };
454
+ }
455
+ // ---------------------------------------------------------------------------
456
+ // Helpers
457
+ // ---------------------------------------------------------------------------
458
+ /** Get the full text content of a block by concatenating all spans. */
459
+ function getBlockText(block) {
460
+ let text = '';
461
+ for (const span of block.spans) {
462
+ text += span.text;
463
+ }
464
+ return text;
465
+ }
466
+ //# sourceMappingURL=trigger-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-manager.js","sourceRoot":"","sources":["../src/trigger-manager.ts"],"names":[],"mappings":"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"}