0
|
1 import { getHandlers } from "./event.js"
|
|
2
|
|
3 let operationGroup = null
|
|
4
|
|
5 export function pushOperation(op) {
|
|
6 if (operationGroup) {
|
|
7 operationGroup.ops.push(op)
|
|
8 } else {
|
|
9 op.ownsGroup = operationGroup = {
|
|
10 ops: [op],
|
|
11 delayedCallbacks: []
|
|
12 }
|
|
13 }
|
|
14 }
|
|
15
|
|
16 function fireCallbacksForOps(group) {
|
|
17 // Calls delayed callbacks and cursorActivity handlers until no
|
|
18 // new ones appear
|
|
19 let callbacks = group.delayedCallbacks, i = 0
|
|
20 do {
|
|
21 for (; i < callbacks.length; i++)
|
|
22 callbacks[i].call(null)
|
|
23 for (let j = 0; j < group.ops.length; j++) {
|
|
24 let op = group.ops[j]
|
|
25 if (op.cursorActivityHandlers)
|
|
26 while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
|
|
27 op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm)
|
|
28 }
|
|
29 } while (i < callbacks.length)
|
|
30 }
|
|
31
|
|
32 export function finishOperation(op, endCb) {
|
|
33 let group = op.ownsGroup
|
|
34 if (!group) return
|
|
35
|
|
36 try { fireCallbacksForOps(group) }
|
|
37 finally {
|
|
38 operationGroup = null
|
|
39 endCb(group)
|
|
40 }
|
|
41 }
|
|
42
|
|
43 let orphanDelayedCallbacks = null
|
|
44
|
|
45 // Often, we want to signal events at a point where we are in the
|
|
46 // middle of some work, but don't want the handler to start calling
|
|
47 // other methods on the editor, which might be in an inconsistent
|
|
48 // state or simply not expect any other events to happen.
|
|
49 // signalLater looks whether there are any handlers, and schedules
|
|
50 // them to be executed when the last operation ends, or, if no
|
|
51 // operation is active, when a timeout fires.
|
|
52 export function signalLater(emitter, type /*, values...*/) {
|
|
53 let arr = getHandlers(emitter, type)
|
|
54 if (!arr.length) return
|
|
55 let args = Array.prototype.slice.call(arguments, 2), list
|
|
56 if (operationGroup) {
|
|
57 list = operationGroup.delayedCallbacks
|
|
58 } else if (orphanDelayedCallbacks) {
|
|
59 list = orphanDelayedCallbacks
|
|
60 } else {
|
|
61 list = orphanDelayedCallbacks = []
|
|
62 setTimeout(fireOrphanDelayed, 0)
|
|
63 }
|
|
64 for (let i = 0; i < arr.length; ++i)
|
|
65 list.push(() => arr[i].apply(null, args))
|
|
66 }
|
|
67
|
|
68 function fireOrphanDelayed() {
|
|
69 let delayed = orphanDelayedCallbacks
|
|
70 orphanDelayedCallbacks = null
|
|
71 for (let i = 0; i < delayed.length; ++i) delayed[i]()
|
|
72 }
|