Mercurial
comparison .cms/lib/codemirror/src/util/operation_group.js @ 0:78edf6b517a0 draft
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Fri, 11 Oct 2024 22:40:23 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78edf6b517a0 |
---|---|
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 } |