@atlaskit/editor-plugin-find-replace 0.1.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.
- package/.eslintrc.js +26 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE.md +13 -0
- package/README.md +30 -0
- package/dist/cjs/FindReplaceToolbarButtonWithState.js +166 -0
- package/dist/cjs/actions.js +19 -0
- package/dist/cjs/commands-with-analytics.js +101 -0
- package/dist/cjs/commands.js +255 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin.js +93 -0
- package/dist/cjs/pm-plugins/keymap.js +24 -0
- package/dist/cjs/pm-plugins/main.js +39 -0
- package/dist/cjs/pm-plugins/plugin-factory.js +109 -0
- package/dist/cjs/pm-plugins/plugin-key.js +8 -0
- package/dist/cjs/reducer.js +61 -0
- package/dist/cjs/styles.js +17 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/ui/Find.js +309 -0
- package/dist/cjs/ui/FindReplace.js +104 -0
- package/dist/cjs/ui/FindReplaceToolbarButton.js +133 -0
- package/dist/cjs/ui/FindReplaceTooltipButton.js +77 -0
- package/dist/cjs/ui/Replace.js +176 -0
- package/dist/cjs/ui/styles.js +46 -0
- package/dist/cjs/utils/array.js +13 -0
- package/dist/cjs/utils/batch-decorations.js +310 -0
- package/dist/cjs/utils/commands.js +16 -0
- package/dist/cjs/utils/index.js +290 -0
- package/dist/es2019/FindReplaceToolbarButtonWithState.js +153 -0
- package/dist/es2019/actions.js +13 -0
- package/dist/es2019/commands-with-analytics.js +72 -0
- package/dist/es2019/commands.js +240 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin.js +88 -0
- package/dist/es2019/pm-plugins/keymap.js +16 -0
- package/dist/es2019/pm-plugins/main.js +30 -0
- package/dist/es2019/pm-plugins/plugin-factory.js +91 -0
- package/dist/es2019/pm-plugins/plugin-key.js +2 -0
- package/dist/es2019/reducer.js +56 -0
- package/dist/es2019/styles.js +18 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/Find.js +286 -0
- package/dist/es2019/ui/FindReplace.js +81 -0
- package/dist/es2019/ui/FindReplaceToolbarButton.js +122 -0
- package/dist/es2019/ui/FindReplaceTooltipButton.js +51 -0
- package/dist/es2019/ui/Replace.js +155 -0
- package/dist/es2019/ui/styles.js +50 -0
- package/dist/es2019/utils/array.js +3 -0
- package/dist/es2019/utils/batch-decorations.js +189 -0
- package/dist/es2019/utils/commands.js +6 -0
- package/dist/es2019/utils/index.js +249 -0
- package/dist/esm/FindReplaceToolbarButtonWithState.js +157 -0
- package/dist/esm/actions.js +13 -0
- package/dist/esm/commands-with-analytics.js +95 -0
- package/dist/esm/commands.js +248 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin.js +86 -0
- package/dist/esm/pm-plugins/keymap.js +18 -0
- package/dist/esm/pm-plugins/main.js +33 -0
- package/dist/esm/pm-plugins/plugin-factory.js +104 -0
- package/dist/esm/pm-plugins/plugin-key.js +2 -0
- package/dist/esm/reducer.js +54 -0
- package/dist/esm/styles.js +11 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/Find.js +304 -0
- package/dist/esm/ui/FindReplace.js +100 -0
- package/dist/esm/ui/FindReplaceToolbarButton.js +126 -0
- package/dist/esm/ui/FindReplaceTooltipButton.js +70 -0
- package/dist/esm/ui/Replace.js +171 -0
- package/dist/esm/ui/styles.js +39 -0
- package/dist/esm/utils/array.js +7 -0
- package/dist/esm/utils/batch-decorations.js +304 -0
- package/dist/esm/utils/commands.js +10 -0
- package/dist/esm/utils/index.js +280 -0
- package/dist/types/FindReplaceToolbarButtonWithState.d.ts +4 -0
- package/dist/types/actions.d.ts +64 -0
- package/dist/types/commands-with-analytics.d.ts +27 -0
- package/dist/types/commands.d.ts +12 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/plugin.d.ts +2 -0
- package/dist/types/pm-plugins/keymap.d.ts +4 -0
- package/dist/types/pm-plugins/main.d.ts +5 -0
- package/dist/types/pm-plugins/plugin-factory.d.ts +2 -0
- package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types/reducer.d.ts +4 -0
- package/dist/types/styles.d.ts +3 -0
- package/dist/types/types.d.ts +76 -0
- package/dist/types/ui/Find.d.ts +71 -0
- package/dist/types/ui/FindReplace.d.ts +43 -0
- package/dist/types/ui/FindReplaceToolbarButton.d.ts +21 -0
- package/dist/types/ui/FindReplaceTooltipButton.d.ts +18 -0
- package/dist/types/ui/Replace.d.ts +27 -0
- package/dist/types/ui/styles.d.ts +6 -0
- package/dist/types/utils/array.d.ts +1 -0
- package/dist/types/utils/batch-decorations.d.ts +36 -0
- package/dist/types/utils/commands.d.ts +2 -0
- package/dist/types/utils/index.d.ts +49 -0
- package/dist/types-ts4.5/FindReplaceToolbarButtonWithState.d.ts +4 -0
- package/dist/types-ts4.5/actions.d.ts +64 -0
- package/dist/types-ts4.5/commands-with-analytics.d.ts +27 -0
- package/dist/types-ts4.5/commands.d.ts +12 -0
- package/dist/types-ts4.5/index.d.ts +2 -0
- package/dist/types-ts4.5/plugin.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/reducer.d.ts +4 -0
- package/dist/types-ts4.5/styles.d.ts +3 -0
- package/dist/types-ts4.5/types.d.ts +76 -0
- package/dist/types-ts4.5/ui/Find.d.ts +71 -0
- package/dist/types-ts4.5/ui/FindReplace.d.ts +43 -0
- package/dist/types-ts4.5/ui/FindReplaceToolbarButton.d.ts +21 -0
- package/dist/types-ts4.5/ui/FindReplaceTooltipButton.d.ts +18 -0
- package/dist/types-ts4.5/ui/Replace.d.ts +27 -0
- package/dist/types-ts4.5/ui/styles.d.ts +6 -0
- package/dist/types-ts4.5/utils/array.d.ts +1 -0
- package/dist/types-ts4.5/utils/batch-decorations.d.ts +36 -0
- package/dist/types-ts4.5/utils/commands.d.ts +2 -0
- package/dist/types-ts4.5/utils/index.d.ts +49 -0
- package/package.json +117 -0
- package/styles/package.json +17 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
|
+
var _pluginFactory = require("../pm-plugins/plugin-factory");
|
|
13
|
+
var _index = require("./index");
|
|
14
|
+
// max number of decorations to apply at once
|
|
15
|
+
var batchIncrement = 100;
|
|
16
|
+
// position range to apply decorations between before alternating above or below viewport
|
|
17
|
+
var posIncrement = 2000;
|
|
18
|
+
/**
|
|
19
|
+
* Provides support for applying search match highlight decorations in batches
|
|
20
|
+
*/
|
|
21
|
+
var BatchDecorations = /*#__PURE__*/function () {
|
|
22
|
+
function BatchDecorations() {
|
|
23
|
+
(0, _classCallCheck2.default)(this, BatchDecorations);
|
|
24
|
+
}
|
|
25
|
+
(0, _createClass2.default)(BatchDecorations, [{
|
|
26
|
+
key: "stop",
|
|
27
|
+
value: function stop() {
|
|
28
|
+
if (this.rafId) {
|
|
29
|
+
cancelAnimationFrame(this.rafId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Applies the decorations needed for the current search results
|
|
35
|
+
* It does so async, splitting them up into batches to help with performance
|
|
36
|
+
*/
|
|
37
|
+
}, {
|
|
38
|
+
key: "applyAllSearchDecorations",
|
|
39
|
+
value: function () {
|
|
40
|
+
var _applyAllSearchDecorations = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(editorView, containerElement, addDecorations, removeDecorations) {
|
|
41
|
+
var pmElement, positions, startPos, endPos, viewportStartPos, viewportEndPos, dir, before, after, diff;
|
|
42
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
43
|
+
while (1) switch (_context.prev = _context.next) {
|
|
44
|
+
case 0:
|
|
45
|
+
this.stop();
|
|
46
|
+
this.addDecorations = addDecorations;
|
|
47
|
+
this.removeDecorations = removeDecorations;
|
|
48
|
+
if (containerElement) {
|
|
49
|
+
_context.next = 5;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
return _context.abrupt("return");
|
|
53
|
+
case 5:
|
|
54
|
+
pmElement = containerElement.querySelector('.ProseMirror');
|
|
55
|
+
if (pmElement) {
|
|
56
|
+
_context.next = 8;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
return _context.abrupt("return");
|
|
60
|
+
case 8:
|
|
61
|
+
positions = this.calcDecorationPositions(editorView, containerElement, pmElement);
|
|
62
|
+
startPos = positions.startPos, endPos = positions.endPos, viewportStartPos = positions.viewportStartPos, viewportEndPos = positions.viewportEndPos;
|
|
63
|
+
dir = 0;
|
|
64
|
+
before = viewportStartPos;
|
|
65
|
+
after = viewportEndPos - posIncrement;
|
|
66
|
+
_context.next = 15;
|
|
67
|
+
return this.updateDecorationsBetween(editorView, viewportStartPos, viewportEndPos);
|
|
68
|
+
case 15:
|
|
69
|
+
if (!(before > startPos || after < endPos)) {
|
|
70
|
+
_context.next = 28;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
if (!(dir++ % 2 === 0 && before > startPos || after >= endPos)) {
|
|
74
|
+
_context.next = 23;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
diff = before - startPos;
|
|
78
|
+
before = Math.max(before - posIncrement, startPos);
|
|
79
|
+
_context.next = 21;
|
|
80
|
+
return this.updateDecorationsBetween(editorView, before, before + Math.min(diff, posIncrement));
|
|
81
|
+
case 21:
|
|
82
|
+
_context.next = 26;
|
|
83
|
+
break;
|
|
84
|
+
case 23:
|
|
85
|
+
after = Math.min(after + posIncrement, endPos);
|
|
86
|
+
_context.next = 26;
|
|
87
|
+
return this.updateDecorationsBetween(editorView, after, Math.min(after + posIncrement, endPos));
|
|
88
|
+
case 26:
|
|
89
|
+
_context.next = 15;
|
|
90
|
+
break;
|
|
91
|
+
case 28:
|
|
92
|
+
case "end":
|
|
93
|
+
return _context.stop();
|
|
94
|
+
}
|
|
95
|
+
}, _callee, this);
|
|
96
|
+
}));
|
|
97
|
+
function applyAllSearchDecorations(_x, _x2, _x3, _x4) {
|
|
98
|
+
return _applyAllSearchDecorations.apply(this, arguments);
|
|
99
|
+
}
|
|
100
|
+
return applyAllSearchDecorations;
|
|
101
|
+
}()
|
|
102
|
+
}, {
|
|
103
|
+
key: "updateDecorationsBetween",
|
|
104
|
+
value: function () {
|
|
105
|
+
var _updateDecorationsBetween = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(editorView, startPos, endPos) {
|
|
106
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
107
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
108
|
+
case 0:
|
|
109
|
+
_context2.next = 2;
|
|
110
|
+
return this.removeDecorationsBetween(editorView, startPos, endPos);
|
|
111
|
+
case 2:
|
|
112
|
+
_context2.next = 4;
|
|
113
|
+
return this.addDecorationsBetween(editorView, startPos, endPos);
|
|
114
|
+
case 4:
|
|
115
|
+
case "end":
|
|
116
|
+
return _context2.stop();
|
|
117
|
+
}
|
|
118
|
+
}, _callee2, this);
|
|
119
|
+
}));
|
|
120
|
+
function updateDecorationsBetween(_x5, _x6, _x7) {
|
|
121
|
+
return _updateDecorationsBetween.apply(this, arguments);
|
|
122
|
+
}
|
|
123
|
+
return updateDecorationsBetween;
|
|
124
|
+
}()
|
|
125
|
+
}, {
|
|
126
|
+
key: "addDecorationsBetween",
|
|
127
|
+
value: function () {
|
|
128
|
+
var _addDecorationsBetween = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(editorView, startPos, endPos) {
|
|
129
|
+
var _this = this;
|
|
130
|
+
var selection, _getPluginState, matches, decorationSet, matchesBetween, selectionMatch, selectionIndex;
|
|
131
|
+
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
132
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
133
|
+
case 0:
|
|
134
|
+
selection = editorView.state.selection;
|
|
135
|
+
_getPluginState = (0, _pluginFactory.getPluginState)(editorView.state), matches = _getPluginState.matches, decorationSet = _getPluginState.decorationSet;
|
|
136
|
+
if (!(matches.length === 0)) {
|
|
137
|
+
_context3.next = 4;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
return _context3.abrupt("return");
|
|
141
|
+
case 4:
|
|
142
|
+
matchesBetween = matches.filter(function (m) {
|
|
143
|
+
return m.start >= startPos && (endPos === undefined || m.start < endPos);
|
|
144
|
+
});
|
|
145
|
+
selectionMatch = matches.find(function (match) {
|
|
146
|
+
return match.start >= selection.from;
|
|
147
|
+
});
|
|
148
|
+
selectionIndex = matchesBetween.findIndex(function (match) {
|
|
149
|
+
return match === selectionMatch;
|
|
150
|
+
});
|
|
151
|
+
_context3.next = 9;
|
|
152
|
+
return this.batchRequests(function (counter) {
|
|
153
|
+
var matchesToDecorate = matchesBetween.slice(counter, counter + batchIncrement);
|
|
154
|
+
if (matchesToDecorate.length === 0) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
var useSelectionIndex = selectionIndex >= counter && selectionIndex < counter + batchIncrement;
|
|
158
|
+
if (selectionMatch && useSelectionIndex) {
|
|
159
|
+
var selectionMatchDecoration = (0, _index.findDecorationFromMatch)(decorationSet, selectionMatch);
|
|
160
|
+
if (selectionMatchDecoration) {
|
|
161
|
+
matchesToDecorate.splice(selectionIndex % batchIncrement, 1);
|
|
162
|
+
useSelectionIndex = false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (_this.addDecorations) {
|
|
166
|
+
_this.addDecorations((0, _index.createDecorations)(useSelectionIndex ? selectionIndex % batchIncrement : -1, matchesToDecorate));
|
|
167
|
+
}
|
|
168
|
+
}, {
|
|
169
|
+
increment: batchIncrement,
|
|
170
|
+
until: matchesBetween.length
|
|
171
|
+
});
|
|
172
|
+
case 9:
|
|
173
|
+
return _context3.abrupt("return", _context3.sent);
|
|
174
|
+
case 10:
|
|
175
|
+
case "end":
|
|
176
|
+
return _context3.stop();
|
|
177
|
+
}
|
|
178
|
+
}, _callee3, this);
|
|
179
|
+
}));
|
|
180
|
+
function addDecorationsBetween(_x8, _x9, _x10) {
|
|
181
|
+
return _addDecorationsBetween.apply(this, arguments);
|
|
182
|
+
}
|
|
183
|
+
return addDecorationsBetween;
|
|
184
|
+
}()
|
|
185
|
+
}, {
|
|
186
|
+
key: "removeDecorationsBetween",
|
|
187
|
+
value: function () {
|
|
188
|
+
var _removeDecorationsBetween = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(editorView, startPos, endPos) {
|
|
189
|
+
var _this2 = this;
|
|
190
|
+
var _getPluginState2, decorationSet, decorations;
|
|
191
|
+
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
192
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
193
|
+
case 0:
|
|
194
|
+
_getPluginState2 = (0, _pluginFactory.getPluginState)(editorView.state), decorationSet = _getPluginState2.decorationSet;
|
|
195
|
+
decorations = decorationSet.find(startPos, endPos);
|
|
196
|
+
if (!(decorations.length === 0)) {
|
|
197
|
+
_context4.next = 4;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
return _context4.abrupt("return");
|
|
201
|
+
case 4:
|
|
202
|
+
_context4.next = 6;
|
|
203
|
+
return this.batchRequests(function (counter) {
|
|
204
|
+
var decorationsToRemove = decorations.slice(counter, counter + batchIncrement);
|
|
205
|
+
if (decorationsToRemove.length === 0) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
// only get those decorations whose from >= startPos
|
|
209
|
+
for (var i = 0; i < decorationsToRemove.length; i++) {
|
|
210
|
+
if (decorationsToRemove[i].from >= startPos) {
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
decorationsToRemove = decorationsToRemove.slice(1);
|
|
214
|
+
}
|
|
215
|
+
if (_this2.removeDecorations) {
|
|
216
|
+
_this2.removeDecorations(decorationsToRemove);
|
|
217
|
+
}
|
|
218
|
+
}, {
|
|
219
|
+
increment: batchIncrement,
|
|
220
|
+
until: decorations.length
|
|
221
|
+
});
|
|
222
|
+
case 6:
|
|
223
|
+
return _context4.abrupt("return", _context4.sent);
|
|
224
|
+
case 7:
|
|
225
|
+
case "end":
|
|
226
|
+
return _context4.stop();
|
|
227
|
+
}
|
|
228
|
+
}, _callee4, this);
|
|
229
|
+
}));
|
|
230
|
+
function removeDecorationsBetween(_x11, _x12, _x13) {
|
|
231
|
+
return _removeDecorationsBetween.apply(this, arguments);
|
|
232
|
+
}
|
|
233
|
+
return removeDecorationsBetween;
|
|
234
|
+
}()
|
|
235
|
+
/**
|
|
236
|
+
* Calculates Prosemirror start and end positions we want to apply the decorations
|
|
237
|
+
* between
|
|
238
|
+
* Also calculates the positions the are the start and end of the user's viewport
|
|
239
|
+
* so we can apply decorations there first and work outwards
|
|
240
|
+
*/
|
|
241
|
+
}, {
|
|
242
|
+
key: "calcDecorationPositions",
|
|
243
|
+
value: function calcDecorationPositions(editorView, containerElement, pmElement) {
|
|
244
|
+
var containerRect = containerElement.getBoundingClientRect();
|
|
245
|
+
var pmRect = pmElement.getBoundingClientRect();
|
|
246
|
+
var viewportStartPos = this.getStartPos(editorView, 0, pmRect.left);
|
|
247
|
+
var viewportEndPos = this.getEndPos(editorView, containerRect.top + containerRect.height, pmRect.left);
|
|
248
|
+
return {
|
|
249
|
+
viewportStartPos: viewportStartPos,
|
|
250
|
+
viewportEndPos: viewportEndPos,
|
|
251
|
+
startPos: 1,
|
|
252
|
+
endPos: editorView.state.doc.nodeSize
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}, {
|
|
256
|
+
key: "getStartPos",
|
|
257
|
+
value: function getStartPos(editorView, y, x) {
|
|
258
|
+
var startPos = editorView.posAtCoords({
|
|
259
|
+
top: y,
|
|
260
|
+
left: x
|
|
261
|
+
});
|
|
262
|
+
return startPos ? startPos.pos : 1;
|
|
263
|
+
}
|
|
264
|
+
}, {
|
|
265
|
+
key: "getEndPos",
|
|
266
|
+
value: function getEndPos(editorView, y, x) {
|
|
267
|
+
var maxPos = editorView.state.doc.nodeSize;
|
|
268
|
+
var endPos = editorView.posAtCoords({
|
|
269
|
+
top: y,
|
|
270
|
+
left: x
|
|
271
|
+
});
|
|
272
|
+
return endPos ? endPos.pos : maxPos;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Util to batch function calls by animation frames
|
|
277
|
+
* A counter will start at 0 and increment by provided value until reaches limit
|
|
278
|
+
* Passed in fn receives the counter as a param, return false to skip waiting
|
|
279
|
+
* for the animation frame for the next call
|
|
280
|
+
*/
|
|
281
|
+
}, {
|
|
282
|
+
key: "batchRequests",
|
|
283
|
+
value: function batchRequests(fn, opts) {
|
|
284
|
+
var _this3 = this;
|
|
285
|
+
var counter = 0;
|
|
286
|
+
var increment = opts.increment,
|
|
287
|
+
until = opts.until;
|
|
288
|
+
return new Promise(function (resolve) {
|
|
289
|
+
var batchedFn = function batchedFn() {
|
|
290
|
+
var result = fn(counter);
|
|
291
|
+
while (result === false && counter < until) {
|
|
292
|
+
counter += increment;
|
|
293
|
+
result = fn(counter);
|
|
294
|
+
}
|
|
295
|
+
if (counter < until) {
|
|
296
|
+
counter += increment;
|
|
297
|
+
_this3.rafId = requestAnimationFrame(batchedFn);
|
|
298
|
+
} else {
|
|
299
|
+
_this3.rafId = undefined;
|
|
300
|
+
resolve();
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
_this3.rafId = requestAnimationFrame(batchedFn);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}]);
|
|
307
|
+
return BatchDecorations;
|
|
308
|
+
}();
|
|
309
|
+
var batchDecorations = new BatchDecorations();
|
|
310
|
+
var _default = exports.default = batchDecorations;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withScrollIntoView = void 0;
|
|
7
|
+
var withScrollIntoView = exports.withScrollIntoView = function withScrollIntoView(command) {
|
|
8
|
+
return function (state, dispatch, view) {
|
|
9
|
+
return command(state, function (tr) {
|
|
10
|
+
tr.scrollIntoView();
|
|
11
|
+
if (dispatch) {
|
|
12
|
+
dispatch(tr);
|
|
13
|
+
}
|
|
14
|
+
}, view);
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.findLostAdjacentDecorations = exports.findIndexBeforePosition = exports.findDecorationFromMatch = exports.createDecorations = exports.createDecoration = void 0;
|
|
7
|
+
exports.findMatches = findMatches;
|
|
8
|
+
exports.findSearchIndex = findSearchIndex;
|
|
9
|
+
exports.getSelectedText = getSelectedText;
|
|
10
|
+
exports.removeMatchesFromSet = exports.removeDecorationsFromSet = exports.prevIndex = exports.nextIndex = exports.isMatchAffectedByStep = exports.getSelectionForMatch = void 0;
|
|
11
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
12
|
+
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
13
|
+
var _styles = require("../styles");
|
|
14
|
+
function getSelectedText(selection) {
|
|
15
|
+
var text = '';
|
|
16
|
+
var selectedContent = selection.content().content;
|
|
17
|
+
for (var i = 0; i < selectedContent.childCount; i++) {
|
|
18
|
+
text += selectedContent.child(i).textContent;
|
|
19
|
+
}
|
|
20
|
+
return text;
|
|
21
|
+
}
|
|
22
|
+
var createDecorations = exports.createDecorations = function createDecorations(selectedIndex, matches) {
|
|
23
|
+
return matches.map(function (_ref, i) {
|
|
24
|
+
var start = _ref.start,
|
|
25
|
+
end = _ref.end;
|
|
26
|
+
return createDecoration(start, end, i === selectedIndex);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
var createDecoration = exports.createDecoration = function createDecoration(start, end, isSelected) {
|
|
30
|
+
var className = _styles.searchMatchClass;
|
|
31
|
+
if (isSelected) {
|
|
32
|
+
className += " ".concat(_styles.selectedSearchMatchClass);
|
|
33
|
+
}
|
|
34
|
+
return _view.Decoration.inline(start, end, {
|
|
35
|
+
class: className
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
function findMatches(content, searchText, shouldMatchCase) {
|
|
39
|
+
var contentIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
40
|
+
var matches = [];
|
|
41
|
+
var searchTextLength = searchText.length;
|
|
42
|
+
var textGrouping = null;
|
|
43
|
+
var collectMatch = function collectMatch(textGrouping) {
|
|
44
|
+
if (!textGrouping) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
var text = textGrouping.text,
|
|
48
|
+
relativePos = textGrouping.pos;
|
|
49
|
+
var pos = contentIndex + relativePos;
|
|
50
|
+
if (!shouldMatchCase) {
|
|
51
|
+
searchText = searchText.toLowerCase();
|
|
52
|
+
text = text.toLowerCase();
|
|
53
|
+
}
|
|
54
|
+
var index = text.indexOf(searchText);
|
|
55
|
+
while (index !== -1) {
|
|
56
|
+
// Find the next substring from the end of the first, so that they don't overlap
|
|
57
|
+
var end = index + searchTextLength;
|
|
58
|
+
// Add the substring index to the position of the node
|
|
59
|
+
matches.push({
|
|
60
|
+
start: pos + index,
|
|
61
|
+
end: pos + end
|
|
62
|
+
});
|
|
63
|
+
index = text.indexOf(searchText, end);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
if (searchTextLength > 0) {
|
|
67
|
+
content.descendants(function (node, pos) {
|
|
68
|
+
if (node.isText) {
|
|
69
|
+
if (textGrouping === null) {
|
|
70
|
+
textGrouping = {
|
|
71
|
+
text: node.text,
|
|
72
|
+
pos: pos
|
|
73
|
+
};
|
|
74
|
+
} else {
|
|
75
|
+
textGrouping.text = textGrouping.text + node.text;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
collectMatch(textGrouping);
|
|
79
|
+
textGrouping = null;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// if there's a dangling text grouping and no non-text node to trigger collectMatch, manually collectMatch
|
|
83
|
+
if (textGrouping) {
|
|
84
|
+
collectMatch(textGrouping);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return matches;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Finds index of first item in matches array that comes after user's cursor pos.
|
|
92
|
+
* If `backward` is `true`, finds index of first item that comes before instead.
|
|
93
|
+
*/
|
|
94
|
+
function findSearchIndex(selectionPos, matches) {
|
|
95
|
+
var backward = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
96
|
+
if (backward) {
|
|
97
|
+
var matchIndex = matches.findIndex(function (match) {
|
|
98
|
+
return match.start >= selectionPos;
|
|
99
|
+
}) - 1;
|
|
100
|
+
if (matchIndex < 0) {
|
|
101
|
+
matchIndex = matches.length - 1; // wrap around from the end
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return matchIndex;
|
|
105
|
+
}
|
|
106
|
+
return Math.max(matches.findIndex(function (match) {
|
|
107
|
+
return match.start >= selectionPos;
|
|
108
|
+
}), 0);
|
|
109
|
+
}
|
|
110
|
+
var nextIndex = exports.nextIndex = function nextIndex(currentIndex, total) {
|
|
111
|
+
return (currentIndex + 1) % total;
|
|
112
|
+
};
|
|
113
|
+
var prevIndex = exports.prevIndex = function prevIndex(currentIndex, total) {
|
|
114
|
+
return (currentIndex - 1 + total) % total;
|
|
115
|
+
};
|
|
116
|
+
var getSelectionForMatch = exports.getSelectionForMatch = function getSelectionForMatch(selection, doc, index, matches) {
|
|
117
|
+
var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
|
|
118
|
+
if (matches[index]) {
|
|
119
|
+
return _state.TextSelection.create(doc, matches[index].start + offset);
|
|
120
|
+
}
|
|
121
|
+
return selection;
|
|
122
|
+
};
|
|
123
|
+
var findDecorationFromMatch = exports.findDecorationFromMatch = function findDecorationFromMatch(decorationSet, match) {
|
|
124
|
+
if (!match) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
var decorations = decorationSet.find(match.start, match.end);
|
|
128
|
+
return decorations.length ? decorations.find(
|
|
129
|
+
// decorationSet.find() returns any decorations that touch the specifided
|
|
130
|
+
// positions, but we want to be stricter
|
|
131
|
+
function (decoration) {
|
|
132
|
+
return decoration.from === match.start && decoration.to === match.end;
|
|
133
|
+
}) : undefined;
|
|
134
|
+
};
|
|
135
|
+
var removeDecorationsFromSet = exports.removeDecorationsFromSet = function removeDecorationsFromSet(decorationSet, decorationsToRemove, doc) {
|
|
136
|
+
var prevDecorations = decorationSet.find();
|
|
137
|
+
|
|
138
|
+
// it is essential that we copy the decorations otherwise in some rare cases
|
|
139
|
+
// prosemirror-view will update our decorationsToRemove array to contain nulls
|
|
140
|
+
// instead of Decorations which ruins our check for lost decorations below
|
|
141
|
+
decorationSet = decorationSet.remove(decorationsToRemove.map(function (decoration) {
|
|
142
|
+
return (
|
|
143
|
+
// copy exists but isn't on the type definition
|
|
144
|
+
decoration.copy(decoration.from, decoration.to)
|
|
145
|
+
);
|
|
146
|
+
}));
|
|
147
|
+
var newDecorations = decorationSet.find();
|
|
148
|
+
|
|
149
|
+
// there is a bug in prosemirror-view where it can't cope with deleting inline
|
|
150
|
+
// decorations from a set in some cases (where there are multiple levels of nested
|
|
151
|
+
// children arrays), and it deletes more decorations than it should
|
|
152
|
+
// todo: ticket link
|
|
153
|
+
var lostDecorations = findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations);
|
|
154
|
+
if (lostDecorations.length > 0) {
|
|
155
|
+
decorationSet = decorationSet.add(doc, lostDecorations);
|
|
156
|
+
}
|
|
157
|
+
return decorationSet;
|
|
158
|
+
};
|
|
159
|
+
var removeMatchesFromSet = exports.removeMatchesFromSet = function removeMatchesFromSet(decorationSet, matches, doc) {
|
|
160
|
+
var decorationsToRemove = matches.filter(function (match) {
|
|
161
|
+
return !!match;
|
|
162
|
+
}).map(function (match) {
|
|
163
|
+
return findDecorationFromMatch(decorationSet, match);
|
|
164
|
+
});
|
|
165
|
+
decorationsToRemove.forEach(function (decoration) {
|
|
166
|
+
if (decoration) {
|
|
167
|
+
decorationSet = removeDecorationsFromSet(decorationSet, [decoration], doc);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return decorationSet;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Finds decorations in prevDecorations that are not in newDecorations or decorationsToRemove
|
|
175
|
+
* These decorations have been lost by Prosemirror during an over eager decoration removal
|
|
176
|
+
* We need to be smart to cope with thousands of decorations without crashing everything
|
|
177
|
+
*/
|
|
178
|
+
var findLostAdjacentDecorations = exports.findLostAdjacentDecorations = function findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations) {
|
|
179
|
+
var lostDecorations = [];
|
|
180
|
+
if (prevDecorations.length - decorationsToRemove.length > newDecorations.length) {
|
|
181
|
+
var position = decorationsToRemove.length > 0 ? decorationsToRemove[0].from : 0;
|
|
182
|
+
var prevDecorationsStartIdx = findIndexBeforePosition(prevDecorations, position);
|
|
183
|
+
var newDecorationsStartIdx = findIndexBeforePosition(newDecorations, position);
|
|
184
|
+
var startIdx = Math.min(prevDecorationsStartIdx, newDecorationsStartIdx);
|
|
185
|
+
var prevDecorationsToCheck = prevDecorations.slice(startIdx);
|
|
186
|
+
var newDecorationsToCheck = newDecorations.slice(startIdx);
|
|
187
|
+
var uniqueInPrev = [];
|
|
188
|
+
var numToFind = prevDecorationsToCheck.length - newDecorationsToCheck.length;
|
|
189
|
+
var foundAll = false;
|
|
190
|
+
var newDecorationsIdxOffset = 0;
|
|
191
|
+
var _loop = function _loop() {
|
|
192
|
+
var prevDecoration = prevDecorationsToCheck[i];
|
|
193
|
+
// this was a legit removal, skip and continue
|
|
194
|
+
if (decorationsToRemove.find(function (decoration) {
|
|
195
|
+
return decoration.from === prevDecoration.from;
|
|
196
|
+
})) {
|
|
197
|
+
newDecorationsIdxOffset -= 1;
|
|
198
|
+
return 0; // continue
|
|
199
|
+
}
|
|
200
|
+
var j = i + newDecorationsIdxOffset;
|
|
201
|
+
|
|
202
|
+
// this is a lost decoration
|
|
203
|
+
if (j >= newDecorationsToCheck.length) {
|
|
204
|
+
uniqueInPrev.push(prevDecoration);
|
|
205
|
+
if (uniqueInPrev.length === numToFind) {
|
|
206
|
+
foundAll = true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
for (; j < newDecorationsToCheck.length; j++) {
|
|
210
|
+
var newDecoration = newDecorationsToCheck[j];
|
|
211
|
+
|
|
212
|
+
// decoration found in both arrays, skip and continue
|
|
213
|
+
if (prevDecoration.from === newDecoration.from) {
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// this is a lost decoration
|
|
218
|
+
if (newDecoration.from > prevDecoration.from || j === newDecorationsToCheck.length - 1) {
|
|
219
|
+
uniqueInPrev.push(prevDecoration);
|
|
220
|
+
newDecorationsIdxOffset -= 1;
|
|
221
|
+
if (uniqueInPrev.length === numToFind) {
|
|
222
|
+
foundAll = true;
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (foundAll) {
|
|
228
|
+
return 1; // break
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
_ret;
|
|
232
|
+
for (var i = 0; i < prevDecorationsToCheck.length; i++) {
|
|
233
|
+
_ret = _loop();
|
|
234
|
+
if (_ret === 0) continue;
|
|
235
|
+
if (_ret === 1) break;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// make sure we ignore any that we wanted to delete
|
|
239
|
+
lostDecorations = uniqueInPrev.filter(function (decoration) {
|
|
240
|
+
return !decorationsToRemove.find(function (decorationToRemove) {
|
|
241
|
+
return decoration.from === decorationToRemove.from;
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
return lostDecorations;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Searches through array in bumps of 100 to return the index of the first
|
|
250
|
+
* decoration whose 'from' value is before or equal to the position
|
|
251
|
+
*/
|
|
252
|
+
var findIndexBeforePosition = exports.findIndexBeforePosition = function findIndexBeforePosition(items, position) {
|
|
253
|
+
// jump in batches to cope with arrays with thousands of decorations
|
|
254
|
+
var increment = 100;
|
|
255
|
+
var index = 0;
|
|
256
|
+
for (var i = items.length - 1; i >= 0; i -= increment) {
|
|
257
|
+
if (items[i].from < position) {
|
|
258
|
+
// now we have found the 100 range, we can narrow it down to exact index
|
|
259
|
+
index = i;
|
|
260
|
+
for (var j = i; j <= items.length - 1; j++) {
|
|
261
|
+
if (items[j].from <= position) {
|
|
262
|
+
index = j;
|
|
263
|
+
} else {
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
if (i < 100 && i > 0) {
|
|
270
|
+
i = 100;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return index;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Determines whether a find/replace text Match will be changed as a result
|
|
278
|
+
* of a Step modification to the document. This is evaluated by checking
|
|
279
|
+
* both mapped and unmapped versions of the Step as in different cases the
|
|
280
|
+
* matches will match.
|
|
281
|
+
*
|
|
282
|
+
* **Note:** Match state received here is after step has been applied.
|
|
283
|
+
*/
|
|
284
|
+
var isMatchAffectedByStep = exports.isMatchAffectedByStep = function isMatchAffectedByStep(match, step, tr) {
|
|
285
|
+
var from = step.from,
|
|
286
|
+
to = step.to,
|
|
287
|
+
slice = step.slice;
|
|
288
|
+
var sliceSize = slice.content.size;
|
|
289
|
+
return from + sliceSize >= match.start && to - sliceSize <= match.end || tr.mapping.map(from) + sliceSize >= match.start && tr.mapping.map(to) - sliceSize <= match.end;
|
|
290
|
+
};
|