@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.
Files changed (121) hide show
  1. package/.eslintrc.js +26 -0
  2. package/CHANGELOG.md +11 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +30 -0
  5. package/dist/cjs/FindReplaceToolbarButtonWithState.js +166 -0
  6. package/dist/cjs/actions.js +19 -0
  7. package/dist/cjs/commands-with-analytics.js +101 -0
  8. package/dist/cjs/commands.js +255 -0
  9. package/dist/cjs/index.js +12 -0
  10. package/dist/cjs/plugin.js +93 -0
  11. package/dist/cjs/pm-plugins/keymap.js +24 -0
  12. package/dist/cjs/pm-plugins/main.js +39 -0
  13. package/dist/cjs/pm-plugins/plugin-factory.js +109 -0
  14. package/dist/cjs/pm-plugins/plugin-key.js +8 -0
  15. package/dist/cjs/reducer.js +61 -0
  16. package/dist/cjs/styles.js +17 -0
  17. package/dist/cjs/types.js +5 -0
  18. package/dist/cjs/ui/Find.js +309 -0
  19. package/dist/cjs/ui/FindReplace.js +104 -0
  20. package/dist/cjs/ui/FindReplaceToolbarButton.js +133 -0
  21. package/dist/cjs/ui/FindReplaceTooltipButton.js +77 -0
  22. package/dist/cjs/ui/Replace.js +176 -0
  23. package/dist/cjs/ui/styles.js +46 -0
  24. package/dist/cjs/utils/array.js +13 -0
  25. package/dist/cjs/utils/batch-decorations.js +310 -0
  26. package/dist/cjs/utils/commands.js +16 -0
  27. package/dist/cjs/utils/index.js +290 -0
  28. package/dist/es2019/FindReplaceToolbarButtonWithState.js +153 -0
  29. package/dist/es2019/actions.js +13 -0
  30. package/dist/es2019/commands-with-analytics.js +72 -0
  31. package/dist/es2019/commands.js +240 -0
  32. package/dist/es2019/index.js +1 -0
  33. package/dist/es2019/plugin.js +88 -0
  34. package/dist/es2019/pm-plugins/keymap.js +16 -0
  35. package/dist/es2019/pm-plugins/main.js +30 -0
  36. package/dist/es2019/pm-plugins/plugin-factory.js +91 -0
  37. package/dist/es2019/pm-plugins/plugin-key.js +2 -0
  38. package/dist/es2019/reducer.js +56 -0
  39. package/dist/es2019/styles.js +18 -0
  40. package/dist/es2019/types.js +1 -0
  41. package/dist/es2019/ui/Find.js +286 -0
  42. package/dist/es2019/ui/FindReplace.js +81 -0
  43. package/dist/es2019/ui/FindReplaceToolbarButton.js +122 -0
  44. package/dist/es2019/ui/FindReplaceTooltipButton.js +51 -0
  45. package/dist/es2019/ui/Replace.js +155 -0
  46. package/dist/es2019/ui/styles.js +50 -0
  47. package/dist/es2019/utils/array.js +3 -0
  48. package/dist/es2019/utils/batch-decorations.js +189 -0
  49. package/dist/es2019/utils/commands.js +6 -0
  50. package/dist/es2019/utils/index.js +249 -0
  51. package/dist/esm/FindReplaceToolbarButtonWithState.js +157 -0
  52. package/dist/esm/actions.js +13 -0
  53. package/dist/esm/commands-with-analytics.js +95 -0
  54. package/dist/esm/commands.js +248 -0
  55. package/dist/esm/index.js +1 -0
  56. package/dist/esm/plugin.js +86 -0
  57. package/dist/esm/pm-plugins/keymap.js +18 -0
  58. package/dist/esm/pm-plugins/main.js +33 -0
  59. package/dist/esm/pm-plugins/plugin-factory.js +104 -0
  60. package/dist/esm/pm-plugins/plugin-key.js +2 -0
  61. package/dist/esm/reducer.js +54 -0
  62. package/dist/esm/styles.js +11 -0
  63. package/dist/esm/types.js +1 -0
  64. package/dist/esm/ui/Find.js +304 -0
  65. package/dist/esm/ui/FindReplace.js +100 -0
  66. package/dist/esm/ui/FindReplaceToolbarButton.js +126 -0
  67. package/dist/esm/ui/FindReplaceTooltipButton.js +70 -0
  68. package/dist/esm/ui/Replace.js +171 -0
  69. package/dist/esm/ui/styles.js +39 -0
  70. package/dist/esm/utils/array.js +7 -0
  71. package/dist/esm/utils/batch-decorations.js +304 -0
  72. package/dist/esm/utils/commands.js +10 -0
  73. package/dist/esm/utils/index.js +280 -0
  74. package/dist/types/FindReplaceToolbarButtonWithState.d.ts +4 -0
  75. package/dist/types/actions.d.ts +64 -0
  76. package/dist/types/commands-with-analytics.d.ts +27 -0
  77. package/dist/types/commands.d.ts +12 -0
  78. package/dist/types/index.d.ts +2 -0
  79. package/dist/types/plugin.d.ts +2 -0
  80. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  81. package/dist/types/pm-plugins/main.d.ts +5 -0
  82. package/dist/types/pm-plugins/plugin-factory.d.ts +2 -0
  83. package/dist/types/pm-plugins/plugin-key.d.ts +3 -0
  84. package/dist/types/reducer.d.ts +4 -0
  85. package/dist/types/styles.d.ts +3 -0
  86. package/dist/types/types.d.ts +76 -0
  87. package/dist/types/ui/Find.d.ts +71 -0
  88. package/dist/types/ui/FindReplace.d.ts +43 -0
  89. package/dist/types/ui/FindReplaceToolbarButton.d.ts +21 -0
  90. package/dist/types/ui/FindReplaceTooltipButton.d.ts +18 -0
  91. package/dist/types/ui/Replace.d.ts +27 -0
  92. package/dist/types/ui/styles.d.ts +6 -0
  93. package/dist/types/utils/array.d.ts +1 -0
  94. package/dist/types/utils/batch-decorations.d.ts +36 -0
  95. package/dist/types/utils/commands.d.ts +2 -0
  96. package/dist/types/utils/index.d.ts +49 -0
  97. package/dist/types-ts4.5/FindReplaceToolbarButtonWithState.d.ts +4 -0
  98. package/dist/types-ts4.5/actions.d.ts +64 -0
  99. package/dist/types-ts4.5/commands-with-analytics.d.ts +27 -0
  100. package/dist/types-ts4.5/commands.d.ts +12 -0
  101. package/dist/types-ts4.5/index.d.ts +2 -0
  102. package/dist/types-ts4.5/plugin.d.ts +2 -0
  103. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  104. package/dist/types-ts4.5/pm-plugins/main.d.ts +5 -0
  105. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +2 -0
  106. package/dist/types-ts4.5/pm-plugins/plugin-key.d.ts +3 -0
  107. package/dist/types-ts4.5/reducer.d.ts +4 -0
  108. package/dist/types-ts4.5/styles.d.ts +3 -0
  109. package/dist/types-ts4.5/types.d.ts +76 -0
  110. package/dist/types-ts4.5/ui/Find.d.ts +71 -0
  111. package/dist/types-ts4.5/ui/FindReplace.d.ts +43 -0
  112. package/dist/types-ts4.5/ui/FindReplaceToolbarButton.d.ts +21 -0
  113. package/dist/types-ts4.5/ui/FindReplaceTooltipButton.d.ts +18 -0
  114. package/dist/types-ts4.5/ui/Replace.d.ts +27 -0
  115. package/dist/types-ts4.5/ui/styles.d.ts +6 -0
  116. package/dist/types-ts4.5/utils/array.d.ts +1 -0
  117. package/dist/types-ts4.5/utils/batch-decorations.d.ts +36 -0
  118. package/dist/types-ts4.5/utils/commands.d.ts +2 -0
  119. package/dist/types-ts4.5/utils/index.d.ts +49 -0
  120. package/package.json +117 -0
  121. package/styles/package.json +17 -0
@@ -0,0 +1,249 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
+ import { searchMatchClass, selectedSearchMatchClass } from '../styles';
4
+ export function getSelectedText(selection) {
5
+ let text = '';
6
+ const selectedContent = selection.content().content;
7
+ for (let i = 0; i < selectedContent.childCount; i++) {
8
+ text += selectedContent.child(i).textContent;
9
+ }
10
+ return text;
11
+ }
12
+ export const createDecorations = (selectedIndex, matches) => matches.map(({
13
+ start,
14
+ end
15
+ }, i) => createDecoration(start, end, i === selectedIndex));
16
+ export const createDecoration = (start, end, isSelected) => {
17
+ let className = searchMatchClass;
18
+ if (isSelected) {
19
+ className += ` ${selectedSearchMatchClass}`;
20
+ }
21
+ return Decoration.inline(start, end, {
22
+ class: className
23
+ });
24
+ };
25
+ export function findMatches(content, searchText, shouldMatchCase, contentIndex = 0) {
26
+ let matches = [];
27
+ const searchTextLength = searchText.length;
28
+ let textGrouping = null;
29
+ const collectMatch = textGrouping => {
30
+ if (!textGrouping) {
31
+ return;
32
+ }
33
+ let {
34
+ text,
35
+ pos: relativePos
36
+ } = textGrouping;
37
+ const pos = contentIndex + relativePos;
38
+ if (!shouldMatchCase) {
39
+ searchText = searchText.toLowerCase();
40
+ text = text.toLowerCase();
41
+ }
42
+ let index = text.indexOf(searchText);
43
+ while (index !== -1) {
44
+ // Find the next substring from the end of the first, so that they don't overlap
45
+ const end = index + searchTextLength;
46
+ // Add the substring index to the position of the node
47
+ matches.push({
48
+ start: pos + index,
49
+ end: pos + end
50
+ });
51
+ index = text.indexOf(searchText, end);
52
+ }
53
+ };
54
+ if (searchTextLength > 0) {
55
+ content.descendants((node, pos) => {
56
+ if (node.isText) {
57
+ if (textGrouping === null) {
58
+ textGrouping = {
59
+ text: node.text,
60
+ pos
61
+ };
62
+ } else {
63
+ textGrouping.text = textGrouping.text + node.text;
64
+ }
65
+ } else {
66
+ collectMatch(textGrouping);
67
+ textGrouping = null;
68
+ }
69
+ });
70
+ // if there's a dangling text grouping and no non-text node to trigger collectMatch, manually collectMatch
71
+ if (textGrouping) {
72
+ collectMatch(textGrouping);
73
+ }
74
+ }
75
+ return matches;
76
+ }
77
+
78
+ /**
79
+ * Finds index of first item in matches array that comes after user's cursor pos.
80
+ * If `backward` is `true`, finds index of first item that comes before instead.
81
+ */
82
+ export function findSearchIndex(selectionPos, matches, backward = false) {
83
+ if (backward) {
84
+ let matchIndex = matches.findIndex(match => match.start >= selectionPos) - 1;
85
+ if (matchIndex < 0) {
86
+ matchIndex = matches.length - 1; // wrap around from the end
87
+ }
88
+
89
+ return matchIndex;
90
+ }
91
+ return Math.max(matches.findIndex(match => match.start >= selectionPos), 0);
92
+ }
93
+ export const nextIndex = (currentIndex, total) => (currentIndex + 1) % total;
94
+ export const prevIndex = (currentIndex, total) => (currentIndex - 1 + total) % total;
95
+ export const getSelectionForMatch = (selection, doc, index, matches, offset = 0) => {
96
+ if (matches[index]) {
97
+ return TextSelection.create(doc, matches[index].start + offset);
98
+ }
99
+ return selection;
100
+ };
101
+ export const findDecorationFromMatch = (decorationSet, match) => {
102
+ if (!match) {
103
+ return;
104
+ }
105
+ const decorations = decorationSet.find(match.start, match.end);
106
+ return decorations.length ? decorations.find(
107
+ // decorationSet.find() returns any decorations that touch the specifided
108
+ // positions, but we want to be stricter
109
+ decoration => decoration.from === match.start && decoration.to === match.end) : undefined;
110
+ };
111
+ export const removeDecorationsFromSet = (decorationSet, decorationsToRemove, doc) => {
112
+ const prevDecorations = decorationSet.find();
113
+
114
+ // it is essential that we copy the decorations otherwise in some rare cases
115
+ // prosemirror-view will update our decorationsToRemove array to contain nulls
116
+ // instead of Decorations which ruins our check for lost decorations below
117
+ decorationSet = decorationSet.remove(decorationsToRemove.map(decoration =>
118
+ // copy exists but isn't on the type definition
119
+ decoration.copy(decoration.from, decoration.to)));
120
+ const newDecorations = decorationSet.find();
121
+
122
+ // there is a bug in prosemirror-view where it can't cope with deleting inline
123
+ // decorations from a set in some cases (where there are multiple levels of nested
124
+ // children arrays), and it deletes more decorations than it should
125
+ // todo: ticket link
126
+ const lostDecorations = findLostAdjacentDecorations(decorationsToRemove, prevDecorations, newDecorations);
127
+ if (lostDecorations.length > 0) {
128
+ decorationSet = decorationSet.add(doc, lostDecorations);
129
+ }
130
+ return decorationSet;
131
+ };
132
+ export const removeMatchesFromSet = (decorationSet, matches, doc) => {
133
+ const decorationsToRemove = matches.filter(match => !!match).map(match => findDecorationFromMatch(decorationSet, match));
134
+ decorationsToRemove.forEach(decoration => {
135
+ if (decoration) {
136
+ decorationSet = removeDecorationsFromSet(decorationSet, [decoration], doc);
137
+ }
138
+ });
139
+ return decorationSet;
140
+ };
141
+
142
+ /**
143
+ * Finds decorations in prevDecorations that are not in newDecorations or decorationsToRemove
144
+ * These decorations have been lost by Prosemirror during an over eager decoration removal
145
+ * We need to be smart to cope with thousands of decorations without crashing everything
146
+ */
147
+ export const findLostAdjacentDecorations = (decorationsToRemove, prevDecorations, newDecorations) => {
148
+ let lostDecorations = [];
149
+ if (prevDecorations.length - decorationsToRemove.length > newDecorations.length) {
150
+ const position = decorationsToRemove.length > 0 ? decorationsToRemove[0].from : 0;
151
+ const prevDecorationsStartIdx = findIndexBeforePosition(prevDecorations, position);
152
+ const newDecorationsStartIdx = findIndexBeforePosition(newDecorations, position);
153
+ const startIdx = Math.min(prevDecorationsStartIdx, newDecorationsStartIdx);
154
+ const prevDecorationsToCheck = prevDecorations.slice(startIdx);
155
+ const newDecorationsToCheck = newDecorations.slice(startIdx);
156
+ const uniqueInPrev = [];
157
+ const numToFind = prevDecorationsToCheck.length - newDecorationsToCheck.length;
158
+ let foundAll = false;
159
+ let newDecorationsIdxOffset = 0;
160
+ for (let i = 0; i < prevDecorationsToCheck.length; i++) {
161
+ const prevDecoration = prevDecorationsToCheck[i];
162
+ // this was a legit removal, skip and continue
163
+ if (decorationsToRemove.find(decoration => decoration.from === prevDecoration.from)) {
164
+ newDecorationsIdxOffset -= 1;
165
+ continue;
166
+ }
167
+ let j = i + newDecorationsIdxOffset;
168
+
169
+ // this is a lost decoration
170
+ if (j >= newDecorationsToCheck.length) {
171
+ uniqueInPrev.push(prevDecoration);
172
+ if (uniqueInPrev.length === numToFind) {
173
+ foundAll = true;
174
+ }
175
+ }
176
+ for (; j < newDecorationsToCheck.length; j++) {
177
+ const newDecoration = newDecorationsToCheck[j];
178
+
179
+ // decoration found in both arrays, skip and continue
180
+ if (prevDecoration.from === newDecoration.from) {
181
+ break;
182
+ }
183
+
184
+ // this is a lost decoration
185
+ if (newDecoration.from > prevDecoration.from || j === newDecorationsToCheck.length - 1) {
186
+ uniqueInPrev.push(prevDecoration);
187
+ newDecorationsIdxOffset -= 1;
188
+ if (uniqueInPrev.length === numToFind) {
189
+ foundAll = true;
190
+ }
191
+ break;
192
+ }
193
+ }
194
+ if (foundAll) {
195
+ break;
196
+ }
197
+ }
198
+
199
+ // make sure we ignore any that we wanted to delete
200
+ lostDecorations = uniqueInPrev.filter(decoration => !decorationsToRemove.find(decorationToRemove => decoration.from === decorationToRemove.from));
201
+ }
202
+ return lostDecorations;
203
+ };
204
+
205
+ /**
206
+ * Searches through array in bumps of 100 to return the index of the first
207
+ * decoration whose 'from' value is before or equal to the position
208
+ */
209
+ export const findIndexBeforePosition = (items, position) => {
210
+ // jump in batches to cope with arrays with thousands of decorations
211
+ const increment = 100;
212
+ let index = 0;
213
+ for (let i = items.length - 1; i >= 0; i -= increment) {
214
+ if (items[i].from < position) {
215
+ // now we have found the 100 range, we can narrow it down to exact index
216
+ index = i;
217
+ for (let j = i; j <= items.length - 1; j++) {
218
+ if (items[j].from <= position) {
219
+ index = j;
220
+ } else {
221
+ break;
222
+ }
223
+ }
224
+ break;
225
+ }
226
+ if (i < 100 && i > 0) {
227
+ i = 100;
228
+ }
229
+ }
230
+ return index;
231
+ };
232
+
233
+ /**
234
+ * Determines whether a find/replace text Match will be changed as a result
235
+ * of a Step modification to the document. This is evaluated by checking
236
+ * both mapped and unmapped versions of the Step as in different cases the
237
+ * matches will match.
238
+ *
239
+ * **Note:** Match state received here is after step has been applied.
240
+ */
241
+ export const isMatchAffectedByStep = (match, step, tr) => {
242
+ const {
243
+ from,
244
+ to,
245
+ slice
246
+ } = step;
247
+ const sliceSize = slice.content.size;
248
+ return from + sliceSize >= match.start && to - sliceSize <= match.end || tr.mapping.map(from) + sliceSize >= match.start && tr.mapping.map(to) - sliceSize <= match.end;
249
+ };
@@ -0,0 +1,157 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import React, { useLayoutEffect, useState } from 'react';
3
+ import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { blur, toggleMatchCase } from './commands';
5
+ import { activateWithAnalytics, cancelSearchWithAnalytics, findNextWithAnalytics, findPrevWithAnalytics, findWithAnalytics, replaceAllWithAnalytics, replaceWithAnalytics } from './commands-with-analytics';
6
+ import FindReplaceToolbarButton from './ui/FindReplaceToolbarButton';
7
+
8
+ // light implementation of useSharedPluginState(). This is due to findreplace
9
+ // being the only plugin that previously used WithPluginState with
10
+ // debounce=false. That was implemented because of text sync issues
11
+ // between editor & findreplace dialog.
12
+ // To address under ENGHEALTH-5853
13
+ var useSharedPluginStateNoDebounce = function useSharedPluginStateNoDebounce(api) {
14
+ var _useState = useState(api === null || api === void 0 ? void 0 : api.findReplace.sharedState.currentState()),
15
+ _useState2 = _slicedToArray(_useState, 2),
16
+ state = _useState2[0],
17
+ setState = _useState2[1];
18
+ useLayoutEffect(function () {
19
+ var unsub = api === null || api === void 0 ? void 0 : api.findReplace.sharedState.onChange(function (_ref) {
20
+ var nextSharedState = _ref.nextSharedState;
21
+ setState(nextSharedState);
22
+ });
23
+ return function () {
24
+ unsub === null || unsub === void 0 || unsub();
25
+ };
26
+ }, [api]);
27
+ return {
28
+ findReplaceState: state
29
+ };
30
+ };
31
+ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithState(_ref2) {
32
+ var _api$analytics;
33
+ var popupsBoundariesElement = _ref2.popupsBoundariesElement,
34
+ popupsMountPoint = _ref2.popupsMountPoint,
35
+ popupsScrollableElement = _ref2.popupsScrollableElement,
36
+ isToolbarReducedSpacing = _ref2.isToolbarReducedSpacing,
37
+ editorView = _ref2.editorView,
38
+ containerElement = _ref2.containerElement,
39
+ dispatchAnalyticsEvent = _ref2.dispatchAnalyticsEvent,
40
+ featureFlags = _ref2.featureFlags,
41
+ takeFullWidth = _ref2.takeFullWidth,
42
+ api = _ref2.api;
43
+ var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
44
+ var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
45
+ findReplaceState = _useSharedPluginState.findReplaceState;
46
+ if (!editorView) {
47
+ return null;
48
+ }
49
+
50
+ // we need the editor to be in focus for scrollIntoView() to work
51
+ // so we focus it while we run the command, then put focus back into
52
+ // whatever element was previously focused in find replace component
53
+ var runWithEditorFocused = function runWithEditorFocused(fn) {
54
+ var activeElement = document.activeElement;
55
+ editorView.focus();
56
+ fn();
57
+ activeElement === null || activeElement === void 0 || activeElement.focus();
58
+ };
59
+ var dispatchCommand = function dispatchCommand(cmd) {
60
+ var state = editorView.state,
61
+ dispatch = editorView.dispatch;
62
+ cmd(state, dispatch);
63
+ };
64
+ var handleActivate = function handleActivate() {
65
+ runWithEditorFocused(function () {
66
+ return dispatchCommand(activateWithAnalytics(editorAnalyticsAPI)({
67
+ triggerMethod: TRIGGER_METHOD.TOOLBAR
68
+ }));
69
+ });
70
+ };
71
+ var handleFind = function handleFind(keyword) {
72
+ runWithEditorFocused(function () {
73
+ return dispatchCommand(findWithAnalytics(editorAnalyticsAPI)({
74
+ editorView: editorView,
75
+ containerElement: containerElement,
76
+ keyword: keyword
77
+ }));
78
+ });
79
+ };
80
+ var handleFindNext = function handleFindNext(_ref3) {
81
+ var triggerMethod = _ref3.triggerMethod;
82
+ runWithEditorFocused(function () {
83
+ return dispatchCommand(findNextWithAnalytics(editorAnalyticsAPI)({
84
+ triggerMethod: triggerMethod
85
+ }));
86
+ });
87
+ };
88
+ var handleFindPrev = function handleFindPrev(_ref4) {
89
+ var triggerMethod = _ref4.triggerMethod;
90
+ runWithEditorFocused(function () {
91
+ return dispatchCommand(findPrevWithAnalytics(editorAnalyticsAPI)({
92
+ triggerMethod: triggerMethod
93
+ }));
94
+ });
95
+ };
96
+ var handleReplace = function handleReplace(_ref5) {
97
+ var triggerMethod = _ref5.triggerMethod,
98
+ replaceText = _ref5.replaceText;
99
+ runWithEditorFocused(function () {
100
+ return dispatchCommand(replaceWithAnalytics(editorAnalyticsAPI)({
101
+ triggerMethod: triggerMethod,
102
+ replaceText: replaceText
103
+ }));
104
+ });
105
+ };
106
+ var handleReplaceAll = function handleReplaceAll(_ref6) {
107
+ var replaceText = _ref6.replaceText;
108
+ runWithEditorFocused(function () {
109
+ return dispatchCommand(replaceAllWithAnalytics(editorAnalyticsAPI)({
110
+ replaceText: replaceText
111
+ }));
112
+ });
113
+ };
114
+ var handleFindBlur = function handleFindBlur() {
115
+ dispatchCommand(blur());
116
+ };
117
+ var handleCancel = function handleCancel(_ref7) {
118
+ var triggerMethod = _ref7.triggerMethod;
119
+ dispatchCommand(cancelSearchWithAnalytics(editorAnalyticsAPI)({
120
+ triggerMethod: triggerMethod
121
+ }));
122
+ editorView.focus();
123
+ };
124
+ var handleToggleMatchCase = function handleToggleMatchCase() {
125
+ dispatchCommand(toggleMatchCase());
126
+ };
127
+ var findReplaceMatchCase = featureFlags.findReplaceMatchCase;
128
+ if (!findReplaceState) {
129
+ return null;
130
+ }
131
+ return /*#__PURE__*/React.createElement(FindReplaceToolbarButton, {
132
+ allowMatchCase: findReplaceMatchCase,
133
+ shouldMatchCase: findReplaceState.shouldMatchCase,
134
+ onToggleMatchCase: handleToggleMatchCase,
135
+ isActive: findReplaceState.isActive,
136
+ findText: findReplaceState.findText,
137
+ index: findReplaceState.index,
138
+ numMatches: findReplaceState.matches.length,
139
+ replaceText: findReplaceState.replaceText,
140
+ shouldFocus: findReplaceState.shouldFocus,
141
+ popupsBoundariesElement: popupsBoundariesElement,
142
+ popupsMountPoint: popupsMountPoint,
143
+ popupsScrollableElement: popupsScrollableElement,
144
+ isReducedSpacing: !!isToolbarReducedSpacing,
145
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
146
+ onFindBlur: handleFindBlur,
147
+ onCancel: handleCancel,
148
+ onActivate: handleActivate,
149
+ onFind: handleFind,
150
+ onFindNext: handleFindNext,
151
+ onFindPrev: handleFindPrev,
152
+ onReplace: handleReplace,
153
+ onReplaceAll: handleReplaceAll,
154
+ takeFullWidth: !!takeFullWidth
155
+ });
156
+ };
157
+ export default /*#__PURE__*/React.memo(FindReplaceToolbarButtonWithState);
@@ -0,0 +1,13 @@
1
+ export var FindReplaceActionTypes = /*#__PURE__*/function (FindReplaceActionTypes) {
2
+ FindReplaceActionTypes["ACTIVATE"] = "ACTIVATE";
3
+ FindReplaceActionTypes["FIND"] = "FIND";
4
+ FindReplaceActionTypes["UPDATE_DECORATIONS"] = "UPDATE_DECORATIONS";
5
+ FindReplaceActionTypes["FIND_NEXT"] = "FIND_NEXT";
6
+ FindReplaceActionTypes["FIND_PREVIOUS"] = "FIND_PREVIOUS";
7
+ FindReplaceActionTypes["REPLACE"] = "REPLACE";
8
+ FindReplaceActionTypes["REPLACE_ALL"] = "REPLACE_ALL";
9
+ FindReplaceActionTypes["CANCEL"] = "CANCEL";
10
+ FindReplaceActionTypes["BLUR"] = "BLUR";
11
+ FindReplaceActionTypes["TOGGLE_MATCH_CASE"] = "TOGGLE_MATCH_CASE";
12
+ return FindReplaceActionTypes;
13
+ }({});
@@ -0,0 +1,95 @@
1
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
3
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
4
+ import { activate, cancelSearch, find, findNext, findPrevious, replace, replaceAll } from './commands';
5
+ export var activateWithAnalytics = function activateWithAnalytics(editorAnalyticsAPI) {
6
+ return function (_ref) {
7
+ var triggerMethod = _ref.triggerMethod;
8
+ return withAnalytics(editorAnalyticsAPI, function (state) {
9
+ return {
10
+ eventType: EVENT_TYPE.UI,
11
+ action: ACTION.ACTIVATED,
12
+ actionSubject: ACTION_SUBJECT.FIND_REPLACE_DIALOG,
13
+ attributes: {
14
+ inputMethod: state.selection instanceof TextSelection && !state.selection.empty ? INPUT_METHOD.PREFILL : INPUT_METHOD.KEYBOARD,
15
+ triggerMethod: triggerMethod
16
+ }
17
+ };
18
+ })(activate());
19
+ };
20
+ };
21
+ export var findWithAnalytics = function findWithAnalytics(editorAnalyticsAPI) {
22
+ return function (_ref2) {
23
+ var editorView = _ref2.editorView,
24
+ containerElement = _ref2.containerElement,
25
+ keyword = _ref2.keyword;
26
+ return withAnalytics(editorAnalyticsAPI, {
27
+ eventType: EVENT_TYPE.TRACK,
28
+ action: ACTION.FIND_PERFORMED,
29
+ actionSubject: ACTION_SUBJECT.TEXT
30
+ })(find(editorView, containerElement, keyword));
31
+ };
32
+ };
33
+ export var findNextWithAnalytics = function findNextWithAnalytics(editorAnalyticsAPI) {
34
+ return function (_ref3) {
35
+ var triggerMethod = _ref3.triggerMethod;
36
+ return withAnalytics(editorAnalyticsAPI, {
37
+ eventType: EVENT_TYPE.TRACK,
38
+ action: ACTION.FIND_NEXT_PERFORMED,
39
+ actionSubject: ACTION_SUBJECT.TEXT,
40
+ attributes: {
41
+ triggerMethod: triggerMethod
42
+ }
43
+ })(findNext());
44
+ };
45
+ };
46
+ export var findPrevWithAnalytics = function findPrevWithAnalytics(editorAnalyticsAPI) {
47
+ return function (_ref4) {
48
+ var triggerMethod = _ref4.triggerMethod;
49
+ return withAnalytics(editorAnalyticsAPI, {
50
+ eventType: EVENT_TYPE.TRACK,
51
+ action: ACTION.FIND_PREV_PERFORMED,
52
+ actionSubject: ACTION_SUBJECT.TEXT,
53
+ attributes: {
54
+ triggerMethod: triggerMethod
55
+ }
56
+ })(findPrevious());
57
+ };
58
+ };
59
+ export var replaceWithAnalytics = function replaceWithAnalytics(editorAnalyticsAPI) {
60
+ return function (_ref5) {
61
+ var triggerMethod = _ref5.triggerMethod,
62
+ replaceText = _ref5.replaceText;
63
+ return withAnalytics(editorAnalyticsAPI, {
64
+ eventType: EVENT_TYPE.TRACK,
65
+ action: ACTION.REPLACED_ONE,
66
+ actionSubject: ACTION_SUBJECT.TEXT,
67
+ attributes: {
68
+ triggerMethod: triggerMethod
69
+ }
70
+ })(replace(replaceText));
71
+ };
72
+ };
73
+ export var replaceAllWithAnalytics = function replaceAllWithAnalytics(editorAnalyticsAPI) {
74
+ return function (_ref6) {
75
+ var replaceText = _ref6.replaceText;
76
+ return withAnalytics(editorAnalyticsAPI, {
77
+ eventType: EVENT_TYPE.TRACK,
78
+ action: ACTION.REPLACED_ALL,
79
+ actionSubject: ACTION_SUBJECT.TEXT
80
+ })(replaceAll(replaceText));
81
+ };
82
+ };
83
+ export var cancelSearchWithAnalytics = function cancelSearchWithAnalytics(editorAnalyticsAPI) {
84
+ return function (_ref7) {
85
+ var triggerMethod = _ref7.triggerMethod;
86
+ return withAnalytics(editorAnalyticsAPI, {
87
+ eventType: EVENT_TYPE.UI,
88
+ action: ACTION.DEACTIVATED,
89
+ actionSubject: ACTION_SUBJECT.FIND_REPLACE_DIALOG,
90
+ attributes: {
91
+ triggerMethod: triggerMethod
92
+ }
93
+ })(cancelSearch());
94
+ };
95
+ };