@portabletext/plugin-emoji-picker 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +241 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +245 -258
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
- package/src/emoji-picker-machine.tsx +444 -377
- package/src/emoji-picker.feature +81 -24
- package/src/emoji-picker.test.tsx +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,22 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
3
|
var compilerRuntime = require("react/compiler-runtime"), editor = require("@portabletext/editor"), react = require("@xstate/react"), behaviors = require("@portabletext/editor/behaviors"), selectors = require("@portabletext/editor/selectors"), utils = require("@portabletext/editor/utils"), keyboardShortcuts = require("@portabletext/keyboard-shortcuts"), pluginInputRule = require("@portabletext/plugin-input-rule"), xstate = require("xstate");
|
|
4
|
-
function _interopNamespaceCompat(e) {
|
|
5
|
-
if (e && typeof e == "object" && "default" in e) return e;
|
|
6
|
-
var n = /* @__PURE__ */ Object.create(null);
|
|
7
|
-
return e && Object.keys(e).forEach(function(k) {
|
|
8
|
-
if (k !== "default") {
|
|
9
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
10
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
11
|
-
enumerable: !0,
|
|
12
|
-
get: function() {
|
|
13
|
-
return e[k];
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}), n.default = e, Object.freeze(n);
|
|
18
|
-
}
|
|
19
|
-
var selectors__namespace = /* @__PURE__ */ _interopNamespaceCompat(selectors), utils__namespace = /* @__PURE__ */ _interopNamespaceCompat(utils);
|
|
20
4
|
function createMatchEmojis(config) {
|
|
21
5
|
return ({
|
|
22
6
|
keyword
|
|
@@ -72,22 +56,111 @@ const arrowUpShortcut = keyboardShortcuts.createKeyboardShortcut({
|
|
|
72
56
|
default: [{
|
|
73
57
|
key: "Escape"
|
|
74
58
|
}]
|
|
75
|
-
}),
|
|
59
|
+
}), getTriggerState = (snapshot) => {
|
|
60
|
+
const focusSpan = selectors.getFocusSpan(snapshot), markState = selectors.getMarkState(snapshot);
|
|
61
|
+
if (!focusSpan || !markState || !snapshot.context.selection)
|
|
62
|
+
return;
|
|
63
|
+
const focusSpanTextBefore = focusSpan.node.text.slice(0, snapshot.context.selection.focus.offset), focusSpanTextAfter = focusSpan.node.text.slice(snapshot.context.selection.focus.offset), previousSpan = selectors.getPreviousSpan(snapshot), nextSpan = selectors.getNextSpan(snapshot);
|
|
64
|
+
return {
|
|
65
|
+
focusSpan,
|
|
66
|
+
markState,
|
|
67
|
+
focusSpanTextBefore,
|
|
68
|
+
focusSpanTextAfter,
|
|
69
|
+
previousSpan,
|
|
70
|
+
nextSpan
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
function createTriggerActions({
|
|
74
|
+
snapshot,
|
|
75
|
+
payload,
|
|
76
|
+
keywordState
|
|
77
|
+
}) {
|
|
78
|
+
if (payload.markState.state === "unchanged") {
|
|
79
|
+
const focusSpan2 = {
|
|
80
|
+
node: {
|
|
81
|
+
_key: payload.focusSpan.node._key,
|
|
82
|
+
_type: payload.focusSpan.node._type,
|
|
83
|
+
text: `${payload.focusSpanTextBefore}${payload.lastMatch.text}${payload.focusSpanTextAfter}`,
|
|
84
|
+
marks: payload.markState.marks
|
|
85
|
+
},
|
|
86
|
+
path: payload.focusSpan.path,
|
|
87
|
+
textBefore: payload.focusSpanTextBefore,
|
|
88
|
+
textAfter: payload.focusSpanTextAfter
|
|
89
|
+
};
|
|
90
|
+
return keywordState === "complete" ? [behaviors.raise(createKeywordFoundEvent({
|
|
91
|
+
focusSpan: focusSpan2
|
|
92
|
+
}))] : [behaviors.raise(createTriggerFoundEvent({
|
|
93
|
+
focusSpan: focusSpan2
|
|
94
|
+
}))];
|
|
95
|
+
}
|
|
96
|
+
const newSpan = {
|
|
97
|
+
_key: snapshot.context.keyGenerator(),
|
|
98
|
+
_type: payload.focusSpan.node._type,
|
|
99
|
+
text: payload.lastMatch.text,
|
|
100
|
+
marks: payload.markState.marks
|
|
101
|
+
};
|
|
102
|
+
let focusSpan = {
|
|
103
|
+
node: {
|
|
104
|
+
_key: newSpan._key,
|
|
105
|
+
_type: newSpan._type,
|
|
106
|
+
text: `${newSpan.text}${payload.nextSpan?.node.text ?? payload.focusSpanTextAfter}`,
|
|
107
|
+
marks: payload.markState.marks
|
|
108
|
+
},
|
|
109
|
+
path: [{
|
|
110
|
+
_key: payload.focusSpan.path[0]._key
|
|
111
|
+
}, "children", {
|
|
112
|
+
_key: newSpan._key
|
|
113
|
+
}],
|
|
114
|
+
textBefore: "",
|
|
115
|
+
textAfter: payload.nextSpan?.node.text ?? payload.focusSpanTextAfter
|
|
116
|
+
};
|
|
117
|
+
return payload.previousSpan && payload.focusSpanTextBefore.length === 0 && JSON.stringify(payload.previousSpan.node.marks ?? []) === JSON.stringify(payload.markState.marks) && (focusSpan = {
|
|
118
|
+
node: {
|
|
119
|
+
_key: payload.previousSpan.node._key,
|
|
120
|
+
_type: newSpan._type,
|
|
121
|
+
text: `${payload.previousSpan.node.text}${newSpan.text}`,
|
|
122
|
+
marks: newSpan.marks
|
|
123
|
+
},
|
|
124
|
+
path: payload.previousSpan.path,
|
|
125
|
+
textBefore: payload.previousSpan.node.text,
|
|
126
|
+
textAfter: ""
|
|
127
|
+
}), [behaviors.raise({
|
|
128
|
+
type: "select",
|
|
129
|
+
at: payload.lastMatch.targetOffsets
|
|
130
|
+
}), behaviors.raise({
|
|
131
|
+
type: "delete",
|
|
132
|
+
at: payload.lastMatch.targetOffsets
|
|
133
|
+
}), behaviors.raise({
|
|
134
|
+
type: "insert.child",
|
|
135
|
+
child: newSpan
|
|
136
|
+
}), ...keywordState === "complete" ? [behaviors.raise(createKeywordFoundEvent({
|
|
137
|
+
focusSpan
|
|
138
|
+
}))] : [behaviors.raise(createTriggerFoundEvent({
|
|
139
|
+
focusSpan
|
|
140
|
+
}))]];
|
|
141
|
+
}
|
|
142
|
+
const triggerRule = pluginInputRule.defineInputRule({
|
|
76
143
|
on: /:/,
|
|
77
144
|
guard: ({
|
|
145
|
+
snapshot,
|
|
78
146
|
event
|
|
79
147
|
}) => {
|
|
80
148
|
const lastMatch = event.matches.at(-1);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
149
|
+
if (lastMatch === void 0)
|
|
150
|
+
return !1;
|
|
151
|
+
const triggerState = getTriggerState(snapshot);
|
|
152
|
+
return triggerState ? {
|
|
153
|
+
lastMatch,
|
|
154
|
+
...triggerState
|
|
155
|
+
} : !1;
|
|
89
156
|
},
|
|
90
|
-
actions: [(
|
|
157
|
+
actions: [({
|
|
158
|
+
snapshot
|
|
159
|
+
}, payload) => createTriggerActions({
|
|
160
|
+
snapshot,
|
|
161
|
+
payload,
|
|
162
|
+
keywordState: "partial"
|
|
163
|
+
})]
|
|
91
164
|
});
|
|
92
165
|
function createTriggerFoundEvent(payload) {
|
|
93
166
|
return {
|
|
@@ -98,48 +171,47 @@ function createTriggerFoundEvent(payload) {
|
|
|
98
171
|
const partialKeywordRule = pluginInputRule.defineInputRule({
|
|
99
172
|
on: /:[\S]+/,
|
|
100
173
|
guard: ({
|
|
174
|
+
snapshot,
|
|
101
175
|
event
|
|
102
176
|
}) => {
|
|
103
177
|
const lastMatch = event.matches.at(-1);
|
|
104
|
-
if (lastMatch === void 0)
|
|
178
|
+
if (lastMatch === void 0 || lastMatch.targetOffsets.anchor.offset < event.textBefore.length)
|
|
105
179
|
return !1;
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
keyword,
|
|
112
|
-
keywordAnchor,
|
|
113
|
-
keywordFocus
|
|
114
|
-
};
|
|
180
|
+
const triggerState = getTriggerState(snapshot);
|
|
181
|
+
return triggerState ? {
|
|
182
|
+
...triggerState,
|
|
183
|
+
lastMatch
|
|
184
|
+
} : !1;
|
|
115
185
|
},
|
|
116
|
-
actions: [(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const keywordRule = pluginInputRule.defineInputRule({
|
|
186
|
+
actions: [({
|
|
187
|
+
snapshot
|
|
188
|
+
}, payload) => createTriggerActions({
|
|
189
|
+
snapshot,
|
|
190
|
+
payload,
|
|
191
|
+
keywordState: "partial"
|
|
192
|
+
})]
|
|
193
|
+
}), keywordRule = pluginInputRule.defineInputRule({
|
|
125
194
|
on: /:[\S]+:/,
|
|
126
195
|
guard: ({
|
|
196
|
+
snapshot,
|
|
127
197
|
event
|
|
128
198
|
}) => {
|
|
129
199
|
const lastMatch = event.matches.at(-1);
|
|
130
|
-
if (lastMatch === void 0)
|
|
200
|
+
if (lastMatch === void 0 || lastMatch.targetOffsets.anchor.offset < event.textBefore.length)
|
|
131
201
|
return !1;
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
keyword,
|
|
138
|
-
keywordAnchor,
|
|
139
|
-
keywordFocus
|
|
140
|
-
};
|
|
202
|
+
const triggerState = getTriggerState(snapshot);
|
|
203
|
+
return triggerState ? {
|
|
204
|
+
...triggerState,
|
|
205
|
+
lastMatch
|
|
206
|
+
} : !1;
|
|
141
207
|
},
|
|
142
|
-
actions: [(
|
|
208
|
+
actions: [({
|
|
209
|
+
snapshot
|
|
210
|
+
}, payload) => createTriggerActions({
|
|
211
|
+
snapshot,
|
|
212
|
+
payload,
|
|
213
|
+
keywordState: "complete"
|
|
214
|
+
})]
|
|
143
215
|
});
|
|
144
216
|
function createKeywordFoundEvent(payload) {
|
|
145
217
|
return {
|
|
@@ -164,15 +236,6 @@ const triggerListenerCallback = ({
|
|
|
164
236
|
sendBack(event);
|
|
165
237
|
})]]
|
|
166
238
|
})
|
|
167
|
-
}), input.editor.registerBehavior({
|
|
168
|
-
behavior: behaviors.defineBehavior({
|
|
169
|
-
on: "custom.partial keyword found",
|
|
170
|
-
actions: [({
|
|
171
|
-
event
|
|
172
|
-
}) => [behaviors.effect(() => {
|
|
173
|
-
sendBack(event);
|
|
174
|
-
})]]
|
|
175
|
-
})
|
|
176
239
|
}), input.editor.registerBehavior({
|
|
177
240
|
behavior: behaviors.defineBehavior({
|
|
178
241
|
on: "custom.trigger found",
|
|
@@ -248,10 +311,16 @@ const triggerListenerCallback = ({
|
|
|
248
311
|
type: "dismiss"
|
|
249
312
|
});
|
|
250
313
|
}), behaviors.raise({
|
|
251
|
-
type: "delete
|
|
314
|
+
type: "delete",
|
|
252
315
|
at: {
|
|
253
|
-
anchor:
|
|
254
|
-
|
|
316
|
+
anchor: {
|
|
317
|
+
path: event.focusSpan.path,
|
|
318
|
+
offset: event.focusSpan.textBefore.length
|
|
319
|
+
},
|
|
320
|
+
focus: {
|
|
321
|
+
path: event.focusSpan.path,
|
|
322
|
+
offset: event.focusSpan.node.text.length - event.focusSpan.textAfter.length
|
|
323
|
+
}
|
|
255
324
|
}
|
|
256
325
|
}), behaviors.raise({
|
|
257
326
|
type: "insert.text",
|
|
@@ -275,22 +344,19 @@ const triggerListenerCallback = ({
|
|
|
275
344
|
}) => {
|
|
276
345
|
if (!enterShortcut.guard(event.originEvent) && !tabShortcut.guard(event.originEvent))
|
|
277
346
|
return !1;
|
|
278
|
-
const
|
|
279
|
-
return match &&
|
|
280
|
-
|
|
281
|
-
focus,
|
|
347
|
+
const focusSpan = context.focusSpan, match = context.matches[context.selectedIndex];
|
|
348
|
+
return match && focusSpan ? {
|
|
349
|
+
focusSpan,
|
|
282
350
|
emoji: match.emoji
|
|
283
351
|
} : !1;
|
|
284
352
|
},
|
|
285
353
|
actions: [(_, {
|
|
286
|
-
|
|
287
|
-
focus,
|
|
354
|
+
focusSpan,
|
|
288
355
|
emoji
|
|
289
356
|
}) => [behaviors.raise({
|
|
290
357
|
type: "custom.insert emoji",
|
|
291
358
|
emoji,
|
|
292
|
-
|
|
293
|
-
focus
|
|
359
|
+
focusSpan
|
|
294
360
|
})]]
|
|
295
361
|
})
|
|
296
362
|
}), input.context.editor.registerBehavior({
|
|
@@ -305,19 +371,6 @@ const triggerListenerCallback = ({
|
|
|
305
371
|
});
|
|
306
372
|
})]]
|
|
307
373
|
})
|
|
308
|
-
}), input.context.editor.registerBehavior({
|
|
309
|
-
behavior: pluginInputRule.defineInputRuleBehavior({
|
|
310
|
-
rules: [keywordRule]
|
|
311
|
-
})
|
|
312
|
-
}), input.context.editor.registerBehavior({
|
|
313
|
-
behavior: behaviors.defineBehavior({
|
|
314
|
-
on: "custom.keyword found",
|
|
315
|
-
actions: [({
|
|
316
|
-
event
|
|
317
|
-
}) => [behaviors.effect(() => {
|
|
318
|
-
sendBack(event);
|
|
319
|
-
})]]
|
|
320
|
-
})
|
|
321
374
|
})];
|
|
322
375
|
return () => {
|
|
323
376
|
for (const unregister of unregisterBehaviors)
|
|
@@ -327,79 +380,40 @@ const triggerListenerCallback = ({
|
|
|
327
380
|
sendBack,
|
|
328
381
|
input
|
|
329
382
|
}) => input.editor.on("selection", () => {
|
|
330
|
-
const snapshot = input.editor.getSnapshot();
|
|
331
383
|
sendBack({
|
|
332
|
-
type: "selection changed"
|
|
333
|
-
snapshot
|
|
384
|
+
type: "selection changed"
|
|
334
385
|
});
|
|
335
|
-
}).unsubscribe,
|
|
386
|
+
}).unsubscribe, textInsertionListenerCallback = ({
|
|
336
387
|
sendBack,
|
|
337
|
-
input
|
|
388
|
+
input,
|
|
389
|
+
receive
|
|
338
390
|
}) => {
|
|
339
|
-
|
|
391
|
+
let context = input.context;
|
|
392
|
+
return receive((event) => {
|
|
393
|
+
context = event.context;
|
|
394
|
+
}), input.context.editor.registerBehavior({
|
|
340
395
|
behavior: behaviors.defineBehavior({
|
|
341
396
|
on: "insert.text",
|
|
342
397
|
guard: ({
|
|
343
398
|
snapshot
|
|
344
|
-
}) =>
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
...event,
|
|
354
|
-
focus
|
|
355
|
-
});
|
|
356
|
-
}), behaviors.forward(event)]]
|
|
357
|
-
})
|
|
358
|
-
}), input.editor.registerBehavior({
|
|
359
|
-
behavior: behaviors.defineBehavior({
|
|
360
|
-
on: "delete.backward",
|
|
361
|
-
guard: ({
|
|
362
|
-
snapshot,
|
|
363
|
-
event
|
|
364
|
-
}) => event.unit === "character" && snapshot.context.selection ? {
|
|
365
|
-
focus: snapshot.context.selection.focus
|
|
366
|
-
} : !1,
|
|
367
|
-
actions: [({
|
|
368
|
-
event
|
|
369
|
-
}, {
|
|
370
|
-
focus
|
|
371
|
-
}) => [behaviors.effect(() => {
|
|
372
|
-
sendBack({
|
|
373
|
-
type: "delete.backward",
|
|
374
|
-
focus
|
|
375
|
-
});
|
|
376
|
-
}), behaviors.forward(event)]]
|
|
377
|
-
})
|
|
378
|
-
}), input.editor.registerBehavior({
|
|
379
|
-
behavior: behaviors.defineBehavior({
|
|
380
|
-
on: "delete.forward",
|
|
381
|
-
guard: ({
|
|
382
|
-
snapshot,
|
|
383
|
-
event
|
|
384
|
-
}) => event.unit === "character" && snapshot.context.selection ? {
|
|
385
|
-
focus: snapshot.context.selection.focus
|
|
386
|
-
} : !1,
|
|
399
|
+
}) => {
|
|
400
|
+
if (!context.focusSpan || !snapshot.context.selection)
|
|
401
|
+
return !1;
|
|
402
|
+
const keywordAnchor = {
|
|
403
|
+
path: context.focusSpan.path,
|
|
404
|
+
offset: context.focusSpan.textBefore.length
|
|
405
|
+
};
|
|
406
|
+
return utils.isEqualSelectionPoints(snapshot.context.selection.focus, keywordAnchor);
|
|
407
|
+
},
|
|
387
408
|
actions: [({
|
|
388
409
|
event
|
|
389
|
-
}, {
|
|
390
|
-
focus
|
|
391
|
-
}) => [behaviors.effect(() => {
|
|
410
|
+
}) => [behaviors.forward(event), behaviors.effect(() => {
|
|
392
411
|
sendBack({
|
|
393
|
-
type: "
|
|
394
|
-
focus
|
|
412
|
+
type: "dismiss"
|
|
395
413
|
});
|
|
396
|
-
})
|
|
414
|
+
})]]
|
|
397
415
|
})
|
|
398
|
-
})
|
|
399
|
-
return () => {
|
|
400
|
-
for (const unregister of unregisterBehaviors)
|
|
401
|
-
unregister();
|
|
402
|
-
};
|
|
416
|
+
});
|
|
403
417
|
}, emojiPickerMachine = xstate.setup({
|
|
404
418
|
types: {
|
|
405
419
|
context: {},
|
|
@@ -413,60 +427,65 @@ const triggerListenerCallback = ({
|
|
|
413
427
|
"trigger listener": xstate.fromCallback(triggerListenerCallback),
|
|
414
428
|
"escape listener": xstate.fromCallback(escapeListenerCallback),
|
|
415
429
|
"selection listener": xstate.fromCallback(selectionListenerCallback),
|
|
416
|
-
"text
|
|
430
|
+
"text insertion listener": xstate.fromCallback(textInsertionListenerCallback)
|
|
417
431
|
},
|
|
418
432
|
actions: {
|
|
419
|
-
"
|
|
420
|
-
|
|
421
|
-
context,
|
|
422
|
-
event
|
|
423
|
-
}) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keyword : event.keyword
|
|
424
|
-
}),
|
|
425
|
-
"set keyword anchor": xstate.assign({
|
|
426
|
-
keywordAnchor: ({
|
|
427
|
-
context,
|
|
428
|
-
event
|
|
429
|
-
}) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keywordAnchor : event.keywordAnchor
|
|
430
|
-
}),
|
|
431
|
-
"set keyword focus": xstate.assign({
|
|
432
|
-
keywordFocus: ({
|
|
433
|
-
context,
|
|
434
|
-
event
|
|
435
|
-
}) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keywordFocus : event.keywordFocus
|
|
436
|
-
}),
|
|
437
|
-
"update keyword focus": xstate.assign({
|
|
438
|
-
keywordFocus: ({
|
|
433
|
+
"set focus span": xstate.assign({
|
|
434
|
+
focusSpan: ({
|
|
439
435
|
context,
|
|
440
436
|
event
|
|
441
|
-
}) =>
|
|
442
|
-
path: context.keywordFocus.path,
|
|
443
|
-
offset: event.type === "insert.text" ? context.keywordFocus.offset + event.text.length : event.type === "delete.backward" || event.type === "delete.forward" ? context.keywordFocus.offset - 1 : event.focus.offset
|
|
444
|
-
} : context.keywordFocus)
|
|
437
|
+
}) => event.type !== "custom.trigger found" && event.type !== "custom.keyword found" ? context.focusSpan : event.focusSpan
|
|
445
438
|
}),
|
|
446
|
-
"update
|
|
447
|
-
|
|
448
|
-
context
|
|
449
|
-
event
|
|
439
|
+
"update focus span": xstate.assign({
|
|
440
|
+
focusSpan: ({
|
|
441
|
+
context
|
|
450
442
|
}) => {
|
|
451
|
-
if (
|
|
452
|
-
return
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
return keywordFocusPoint ? selectors__namespace.getSelectionText({
|
|
459
|
-
...event.snapshot,
|
|
443
|
+
if (!context.focusSpan)
|
|
444
|
+
return;
|
|
445
|
+
const snapshot = context.editor.getSnapshot(), focusSpan = selectors.getFocusSpan(snapshot);
|
|
446
|
+
if (!snapshot.context.selection || !focusSpan)
|
|
447
|
+
return;
|
|
448
|
+
const nextSpan = selectors.getNextSpan({
|
|
449
|
+
...snapshot,
|
|
460
450
|
context: {
|
|
461
|
-
...
|
|
451
|
+
...snapshot.context,
|
|
462
452
|
selection: {
|
|
463
|
-
anchor:
|
|
464
|
-
|
|
453
|
+
anchor: {
|
|
454
|
+
path: context.focusSpan.path,
|
|
455
|
+
offset: 0
|
|
456
|
+
},
|
|
457
|
+
focus: {
|
|
458
|
+
path: context.focusSpan.path,
|
|
459
|
+
offset: 0
|
|
460
|
+
}
|
|
465
461
|
}
|
|
466
462
|
}
|
|
467
|
-
})
|
|
463
|
+
});
|
|
464
|
+
if (JSON.stringify(focusSpan.path) !== JSON.stringify(context.focusSpan.path))
|
|
465
|
+
return nextSpan && context.focusSpan.textAfter.length === 0 && snapshot.context.selection.focus.offset === 0 && utils.isSelectionCollapsed(snapshot.context.selection) ? context.focusSpan : void 0;
|
|
466
|
+
if (!focusSpan.node.text.startsWith(context.focusSpan.textBefore) || !focusSpan.node.text.endsWith(context.focusSpan.textAfter))
|
|
467
|
+
return;
|
|
468
|
+
const keywordAnchor = {
|
|
469
|
+
path: focusSpan.path,
|
|
470
|
+
offset: context.focusSpan.textBefore.length
|
|
471
|
+
}, keywordFocus = {
|
|
472
|
+
path: focusSpan.path,
|
|
473
|
+
offset: focusSpan.node.text.length - context.focusSpan.textAfter.length
|
|
474
|
+
}, selectionIsBeforeKeyword = selectors.isPointAfterSelection(keywordAnchor)(snapshot), selectionIsAfterKeyword = selectors.isPointBeforeSelection(keywordFocus)(snapshot);
|
|
475
|
+
if (!(selectionIsBeforeKeyword || selectionIsAfterKeyword))
|
|
476
|
+
return {
|
|
477
|
+
node: focusSpan.node,
|
|
478
|
+
path: focusSpan.path,
|
|
479
|
+
textBefore: context.focusSpan.textBefore,
|
|
480
|
+
textAfter: context.focusSpan.textAfter
|
|
481
|
+
};
|
|
468
482
|
}
|
|
469
483
|
}),
|
|
484
|
+
"update keyword": xstate.assign({
|
|
485
|
+
keyword: ({
|
|
486
|
+
context
|
|
487
|
+
}) => context.focusSpan ? context.focusSpan.textBefore.length > 0 && context.focusSpan.textAfter.length > 0 ? context.focusSpan.node.text.slice(context.focusSpan.textBefore.length, -context.focusSpan.textAfter.length) : context.focusSpan.textBefore.length > 0 ? context.focusSpan.node.text.slice(context.focusSpan.textBefore.length) : context.focusSpan.textAfter.length > 0 ? context.focusSpan.node.text.slice(0, -context.focusSpan.textAfter.length) : context.focusSpan.node.text : ""
|
|
488
|
+
}),
|
|
470
489
|
"update matches": xstate.assign({
|
|
471
490
|
matches: ({
|
|
472
491
|
context
|
|
@@ -495,99 +514,65 @@ const triggerListenerCallback = ({
|
|
|
495
514
|
event
|
|
496
515
|
}) => (xstate.assertEvent(event, "navigate to"), event.index)
|
|
497
516
|
}),
|
|
498
|
-
"update
|
|
517
|
+
"update submit listener context": xstate.sendTo("submit listener", ({
|
|
499
518
|
context
|
|
500
519
|
}) => ({
|
|
501
520
|
type: "context changed",
|
|
502
521
|
context
|
|
503
522
|
})),
|
|
504
|
-
"update
|
|
523
|
+
"update text insertion listener context": xstate.sendTo("text insertion listener", ({
|
|
505
524
|
context
|
|
506
525
|
}) => ({
|
|
507
526
|
type: "context changed",
|
|
508
527
|
context
|
|
509
528
|
})),
|
|
510
529
|
"insert selected match": ({
|
|
511
|
-
context
|
|
512
|
-
event
|
|
530
|
+
context
|
|
513
531
|
}) => {
|
|
514
532
|
const match = context.matches[context.selectedIndex];
|
|
515
|
-
!match || !context.
|
|
533
|
+
!match || !context.focusSpan || context.editor.send({
|
|
516
534
|
type: "custom.insert emoji",
|
|
517
535
|
emoji: match.emoji,
|
|
518
|
-
|
|
519
|
-
focus: context.keywordFocus
|
|
536
|
+
focusSpan: context.focusSpan
|
|
520
537
|
});
|
|
521
538
|
},
|
|
522
539
|
reset: xstate.assign({
|
|
523
|
-
|
|
524
|
-
keywordFocus: void 0,
|
|
540
|
+
focusSpan: void 0,
|
|
525
541
|
keyword: "",
|
|
526
542
|
matches: [],
|
|
527
543
|
selectedIndex: 0
|
|
528
544
|
})
|
|
529
545
|
},
|
|
530
546
|
guards: {
|
|
547
|
+
"no focus span": ({
|
|
548
|
+
context
|
|
549
|
+
}) => !context.focusSpan,
|
|
531
550
|
"has matches": ({
|
|
532
551
|
context
|
|
533
552
|
}) => context.matches.length > 0,
|
|
534
553
|
"no matches": xstate.not("has matches"),
|
|
535
|
-
"keyword is
|
|
554
|
+
"keyword is malformed": ({
|
|
555
|
+
context
|
|
556
|
+
}) => !context.incompleteKeywordRegex.test(context.keyword),
|
|
557
|
+
"keyword is direct match": ({
|
|
536
558
|
context
|
|
537
|
-
}) => context.incompleteKeywordRegex.test(context.keyword),
|
|
538
|
-
"keyword is malformed": xstate.not("keyword is wel-formed"),
|
|
539
|
-
"selection is before keyword": ({
|
|
540
|
-
context,
|
|
541
|
-
event
|
|
542
|
-
}) => (xstate.assertEvent(event, "selection changed"), context.keywordAnchor ? selectors__namespace.isPointAfterSelection(context.keywordAnchor.point)(event.snapshot) : !0),
|
|
543
|
-
"selection is after keyword": ({
|
|
544
|
-
context,
|
|
545
|
-
event
|
|
546
|
-
}) => {
|
|
547
|
-
if (xstate.assertEvent(event, "selection changed"), context.keywordFocus === void 0)
|
|
548
|
-
return !0;
|
|
549
|
-
const keywordFocusPoint = utils__namespace.blockOffsetToSpanSelectionPoint({
|
|
550
|
-
context: event.snapshot.context,
|
|
551
|
-
blockOffset: context.keywordFocus,
|
|
552
|
-
direction: "forward"
|
|
553
|
-
});
|
|
554
|
-
return keywordFocusPoint ? selectors__namespace.isPointBeforeSelection(keywordFocusPoint)(event.snapshot) : !0;
|
|
555
|
-
},
|
|
556
|
-
"selection is expanded": ({
|
|
557
|
-
event
|
|
558
|
-
}) => (xstate.assertEvent(event, "selection changed"), selectors__namespace.isSelectionExpanded(event.snapshot)),
|
|
559
|
-
"selection moved unexpectedly": xstate.or(["selection is before keyword", "selection is after keyword", "selection is expanded"]),
|
|
560
|
-
"unexpected text insertion": ({
|
|
561
|
-
context,
|
|
562
|
-
event
|
|
563
559
|
}) => {
|
|
564
|
-
if (
|
|
560
|
+
if (!/^:[\S]+:$/.test(context.keyword))
|
|
565
561
|
return !1;
|
|
566
|
-
const
|
|
567
|
-
return
|
|
568
|
-
...snapshot,
|
|
569
|
-
context: {
|
|
570
|
-
...snapshot.context,
|
|
571
|
-
selection: {
|
|
572
|
-
anchor: context.keywordAnchor.point,
|
|
573
|
-
focus: context.keywordAnchor.point
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}) || utils__namespace.isEqualSelectionPoints(event.focus, context.keywordAnchor.point);
|
|
562
|
+
const match = context.matches.at(context.selectedIndex);
|
|
563
|
+
return !(!match || match.type !== "exact");
|
|
577
564
|
}
|
|
578
565
|
}
|
|
579
566
|
}).createMachine({
|
|
580
|
-
/** @xstate-layout N4IgpgJg5mDOIC5RgLYHsBWBLABABywGMBrMAJwDosIAbMAYkLRrQDsctXZyAXSAbQAMAXUSg8aWFh5Y2YkAA9EARmUB2AJwUAzADYNADgCs65YO1q1ygDQgAnojUG1O5c+W7tAJmdfdRgF8A21RMXAIScgpuAEMyQgALTih6Tm4yHgo+BR4hUSQQCSkZOQKlBABaZW0DHSMAFksNQUF6oyNzL1sHBC9vCnrGtS8GtQaNNt0gkPRsfCJSSlj4pNYUiDA6PgoAMzQyAHc4iDz5IulZVnlyr3MKE30LA31DZoNuxD6vAaHdP29vOo1NNwLNwgsostEsl6BstmAKAAjGIkI5kE4iM6SC6lUDlerabT3arDfS3eoaPQfXr9QaWEaNcaTEGhOYRRbRMBxaFrWFYWAofmwU4Fc4lK5lFTqWqDAwUjReeoGbwaNTU1TPCh-QxNNS6XQGHwssHzSJLLkrGHcOiEcU4RIxNYCTGi7Hi66IfxE1oeZX1EbeZXUhUUZSKjxOOV6bTmY1hU0cqGrFLWsC2y72hKOmAnZT5cRuy4ehDVXQUVXDIyWGpmAzveyfLRKwQaVRVwR1ixeONsiHm7nJ+gigvFIuSkvKVuhgwaEwKmMKwbqkaCAaverqVuvKbBUHx9mQi08qAUVhoHAoGI8RJwHCwBJoA4w4eFQu4xSfaoDA3KOmCVSTn06r-i4-hGH0ZiEoI4H1D24JmpyA7JNED5PmsF5XjesD0KwMQAG5YFAV5gDgECPqwL5imOeKIIM9ShsoRh1i2erPB41L6C40GqISUb6n8cEJoeSFrChj7JBh14JHAOH4YRxE4AArnglFvhKNEIGoq4+E0yraPULa6PUHGqhQ3HVDUBL8dogkHv2lqife4noZeUkybhBFEXwOA8Ggqmju+5RGPqFBqP6ujDD4v4tjYDYIMqLjVKo5gdM4TGBLurLwYmR7JmJaFQJJWGpFwvB3psaZ8BARUJP5OLqR+CD1Loq5ymYfyeP4spGOqv70fpv7NBSBKtBlMz7n2iEOSeTkFTVMl1e645eB49wGP+K0UpBbjaMBzQUF4IzBYq7TNa2QS7meGzwAUWVCWQWIBQ15RVJq2ijJoLRtB03jUhUVYUHKtz-gqeoxkYGi2ZN1B0I99XFqobTlh4-5-Ot4H1j0ZirbcENhR4RmKrBmUmnZU3HnDS0aVUjHlh2cqtkqfTBdSSr0RMGieBS7htASUMIUmyFnvNsB3qhySU9RjUVBFdN1ltTPvbowZOGZEWHe9xgTHo-M5SJM3iy5mHSTdI7w+OlnlgY6heJzbgUv4ytxaqtSCBFg1eJFM4XQEQA */
|
|
581
567
|
id: "emoji picker",
|
|
582
568
|
context: ({
|
|
583
569
|
input
|
|
584
570
|
}) => ({
|
|
585
571
|
editor: input.editor,
|
|
586
572
|
keyword: "",
|
|
587
|
-
|
|
588
|
-
keywordFocus: void 0,
|
|
573
|
+
focusSpan: void 0,
|
|
589
574
|
matchEmojis: input.matchEmojis,
|
|
590
|
-
incompleteKeywordRegex:
|
|
575
|
+
incompleteKeywordRegex: /^:[\S]*$/,
|
|
591
576
|
matches: [],
|
|
592
577
|
selectedIndex: 0
|
|
593
578
|
}),
|
|
@@ -615,14 +600,10 @@ const triggerListenerCallback = ({
|
|
|
615
600
|
on: {
|
|
616
601
|
"custom.trigger found": {
|
|
617
602
|
target: "searching",
|
|
618
|
-
actions: ["set
|
|
619
|
-
},
|
|
620
|
-
"custom.partial keyword found": {
|
|
621
|
-
target: "searching",
|
|
622
|
-
actions: ["set keyword anchor", "set keyword focus", "init keyword"]
|
|
603
|
+
actions: ["set focus span", "update keyword"]
|
|
623
604
|
},
|
|
624
605
|
"custom.keyword found": {
|
|
625
|
-
actions: ["set
|
|
606
|
+
actions: ["set focus span", "update keyword", "update matches", "insert selected match"],
|
|
626
607
|
target: "idle",
|
|
627
608
|
reenter: !0
|
|
628
609
|
}
|
|
@@ -652,42 +633,32 @@ const triggerListenerCallback = ({
|
|
|
652
633
|
editor: context.editor
|
|
653
634
|
})
|
|
654
635
|
}, {
|
|
655
|
-
src: "text
|
|
636
|
+
src: "text insertion listener",
|
|
637
|
+
id: "text insertion listener",
|
|
656
638
|
input: ({
|
|
657
639
|
context
|
|
658
640
|
}) => ({
|
|
659
|
-
|
|
641
|
+
context
|
|
660
642
|
})
|
|
661
643
|
}],
|
|
662
644
|
on: {
|
|
663
|
-
"custom.keyword found": {
|
|
664
|
-
actions: ["set keyword anchor", "set keyword focus", "init keyword", "update matches", "insert selected match"]
|
|
665
|
-
},
|
|
666
|
-
"insert.text": [{
|
|
667
|
-
guard: "unexpected text insertion",
|
|
668
|
-
target: "idle"
|
|
669
|
-
}, {
|
|
670
|
-
actions: ["update keyword focus"]
|
|
671
|
-
}],
|
|
672
|
-
"delete.forward": {
|
|
673
|
-
actions: ["update keyword focus"]
|
|
674
|
-
},
|
|
675
|
-
"delete.backward": {
|
|
676
|
-
actions: ["update keyword focus"]
|
|
677
|
-
},
|
|
678
645
|
dismiss: {
|
|
679
646
|
target: "idle"
|
|
680
647
|
},
|
|
681
648
|
"selection changed": [{
|
|
682
|
-
|
|
683
|
-
target: "idle"
|
|
684
|
-
}, {
|
|
685
|
-
actions: ["update keyword", "update matches", "reset selected index", "update submit listener context"]
|
|
649
|
+
actions: ["update focus span", "update keyword", "update matches", "reset selected index", "update submit listener context", "update text insertion listener context"]
|
|
686
650
|
}]
|
|
687
651
|
},
|
|
688
652
|
always: [{
|
|
653
|
+
guard: "no focus span",
|
|
654
|
+
target: "idle"
|
|
655
|
+
}, {
|
|
689
656
|
guard: "keyword is malformed",
|
|
690
657
|
target: "idle"
|
|
658
|
+
}, {
|
|
659
|
+
guard: "keyword is direct match",
|
|
660
|
+
actions: ["insert selected match"],
|
|
661
|
+
target: "idle"
|
|
691
662
|
}],
|
|
692
663
|
initial: "no matches showing",
|
|
693
664
|
states: {
|