1 | (() => {
|
---|
2 | let initialized = false;
|
---|
3 | let globalNodeMap = new EditingHistory.GlobalNodeMap();
|
---|
4 | let topLevelUpdates = [];
|
---|
5 | let currentChildUpdates = [];
|
---|
6 | let isProcessingTopLevelUpdate = false;
|
---|
7 | let lastKnownSelectionState = null;
|
---|
8 | let mutationObserver = new MutationObserver(records => appendDOMUpdatesFromRecords(records));
|
---|
9 |
|
---|
10 | function beginProcessingTopLevelUpdate() {
|
---|
11 | isProcessingTopLevelUpdate = true;
|
---|
12 | }
|
---|
13 |
|
---|
14 | function endProcessingTopLevelUpdate(topLevelUpdate) {
|
---|
15 | topLevelUpdates.push(topLevelUpdate);
|
---|
16 | currentChildUpdates = [];
|
---|
17 | isProcessingTopLevelUpdate = false;
|
---|
18 | }
|
---|
19 |
|
---|
20 | function appendDOMUpdatesFromRecords(records) {
|
---|
21 | if (!records.length)
|
---|
22 | return;
|
---|
23 |
|
---|
24 | let newUpdates = EditingHistory.DOMUpdate.fromRecords(records, globalNodeMap);
|
---|
25 | if (isProcessingTopLevelUpdate)
|
---|
26 | currentChildUpdates = currentChildUpdates.concat(newUpdates);
|
---|
27 | else
|
---|
28 | topLevelUpdates = topLevelUpdates.concat(newUpdates);
|
---|
29 | }
|
---|
30 |
|
---|
31 | function appendSelectionUpdateIfNecessary() {
|
---|
32 | let newSelectionState = EditingHistory.SelectionState.fromSelection(getSelection(), globalNodeMap);
|
---|
33 | if (newSelectionState.isEqual(lastKnownSelectionState))
|
---|
34 | return;
|
---|
35 |
|
---|
36 | let update = new EditingHistory.SelectionUpdate(globalNodeMap, newSelectionState);
|
---|
37 | if (isProcessingTopLevelUpdate)
|
---|
38 | currentChildUpdates.push(update);
|
---|
39 | else
|
---|
40 | topLevelUpdates.push(update);
|
---|
41 | lastKnownSelectionState = newSelectionState;
|
---|
42 | }
|
---|
43 |
|
---|
44 | document.body.addEventListener("focus", () => {
|
---|
45 | if (initialized)
|
---|
46 | return;
|
---|
47 |
|
---|
48 | initialized = true;
|
---|
49 |
|
---|
50 | EditingHistory.getEditingHistoryAsJSONString = (formatted) => {
|
---|
51 | let record = {};
|
---|
52 | record.updates = topLevelUpdates.map(update => update.toObject());
|
---|
53 | record.globalNodeMap = globalNodeMap.toObject();
|
---|
54 | return formatted ? JSON.stringify(record, null, 4) : JSON.stringify(record);
|
---|
55 | };
|
---|
56 |
|
---|
57 | document.addEventListener("selectionchange", () => {
|
---|
58 | appendSelectionUpdateIfNecessary();
|
---|
59 | });
|
---|
60 |
|
---|
61 | document.addEventListener("beforeinput", event => {
|
---|
62 | appendDOMUpdatesFromRecords(mutationObserver.takeRecords());
|
---|
63 | beginProcessingTopLevelUpdate();
|
---|
64 | });
|
---|
65 |
|
---|
66 | document.addEventListener("input", event => {
|
---|
67 | appendDOMUpdatesFromRecords(mutationObserver.takeRecords());
|
---|
68 | let eventData = event.dataTransfer ? event.dataTransfer.getData("text/html") : event.data;
|
---|
69 | lastKnownSelectionState = null;
|
---|
70 | endProcessingTopLevelUpdate(new EditingHistory.InputEventUpdate(globalNodeMap, currentChildUpdates, event.inputType, eventData, event.timeStamp));
|
---|
71 | });
|
---|
72 |
|
---|
73 | mutationObserver.observe(document, {
|
---|
74 | childList: true,
|
---|
75 | attributes: true,
|
---|
76 | characterData: true,
|
---|
77 | subtree: true,
|
---|
78 | attributeOldValue: true,
|
---|
79 | characterDataOldValue: true,
|
---|
80 | });
|
---|
81 | });
|
---|
82 | })();
|
---|