@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,248 @@
1
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { FindReplaceActionTypes } from './actions';
4
+ import { createCommand, getPluginState } from './pm-plugins/plugin-factory';
5
+ import { createDecoration, findDecorationFromMatch, findMatches, findSearchIndex, getSelectedText, getSelectionForMatch, nextIndex, prevIndex, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
6
+ import batchDecorations from './utils/batch-decorations';
7
+ import { withScrollIntoView } from './utils/commands';
8
+ export var activate = function activate() {
9
+ return createCommand(function (state) {
10
+ var selection = state.selection;
11
+ var findText;
12
+ var matches;
13
+ var index;
14
+
15
+ // if user has selected text and hit cmd-f, set that as the keyword
16
+ if (selection instanceof TextSelection && !selection.empty) {
17
+ findText = getSelectedText(selection);
18
+ var _getPluginState = getPluginState(state),
19
+ shouldMatchCase = _getPluginState.shouldMatchCase;
20
+ matches = findMatches(state.doc, findText, shouldMatchCase);
21
+ index = findSearchIndex(selection.from, matches);
22
+ }
23
+ return {
24
+ type: FindReplaceActionTypes.ACTIVATE,
25
+ findText: findText,
26
+ matches: matches,
27
+ index: index
28
+ };
29
+ });
30
+ };
31
+ export var find = function find(editorView, containerElement, keyword) {
32
+ return withScrollIntoView(createCommand(function (state) {
33
+ var selection = state.selection;
34
+ var _getPluginState2 = getPluginState(state),
35
+ shouldMatchCase = _getPluginState2.shouldMatchCase;
36
+ var matches = keyword !== undefined ? findMatches(state.doc, keyword, shouldMatchCase) : [];
37
+ var index = findSearchIndex(selection.from, matches);
38
+
39
+ // we can't just apply all the decorations to highlight the search results at once
40
+ // as if there are a lot ProseMirror cries :'(
41
+ batchDecorations.applyAllSearchDecorations(editorView, containerElement, function (decorations) {
42
+ return addDecorations(decorations)(editorView.state, editorView.dispatch);
43
+ }, function (decorations) {
44
+ return removeDecorations(decorations)(editorView.state, editorView.dispatch);
45
+ });
46
+ return {
47
+ type: FindReplaceActionTypes.FIND,
48
+ findText: keyword || '',
49
+ matches: matches,
50
+ index: index
51
+ };
52
+ }, function (tr, state) {
53
+ var selection = state.selection;
54
+ var _getPluginState3 = getPluginState(state),
55
+ shouldMatchCase = _getPluginState3.shouldMatchCase;
56
+ var matches = keyword !== undefined ? findMatches(state.doc, keyword, shouldMatchCase) : [];
57
+ if (matches.length > 0) {
58
+ var index = findSearchIndex(selection.from, matches);
59
+ return tr.setSelection(getSelectionForMatch(tr.selection, tr.doc, index, matches));
60
+ }
61
+ return tr;
62
+ }));
63
+ };
64
+ export var findNext = function findNext() {
65
+ return withScrollIntoView(createCommand(function (state) {
66
+ return findInDirection(state, 'next');
67
+ }, function (tr, state) {
68
+ var _getPluginState4 = getPluginState(state),
69
+ matches = _getPluginState4.matches,
70
+ index = _getPluginState4.index;
71
+ // can't use index from plugin state because if the cursor has moved, it will still be the
72
+ // OLD index (the find next operation should look for the first match forward starting
73
+ // from the current cursor position)
74
+ var searchIndex = findSearchIndex(state.selection.from, matches);
75
+ if (searchIndex === index) {
76
+ // cursor has not moved, so we just want to find the next in matches array
77
+ searchIndex = nextIndex(searchIndex, matches.length);
78
+ }
79
+ return tr.setSelection(getSelectionForMatch(tr.selection, tr.doc, searchIndex, matches));
80
+ }));
81
+ };
82
+ export var findPrevious = function findPrevious() {
83
+ return withScrollIntoView(createCommand(function (state) {
84
+ return findInDirection(state, 'previous');
85
+ }, function (tr, state) {
86
+ var _getPluginState5 = getPluginState(state),
87
+ matches = _getPluginState5.matches;
88
+ // can't use index from plugin state because if the cursor has moved, it will still be the
89
+ // OLD index (the find prev operation should look for the first match backward starting
90
+ // from the current cursor position)
91
+ var searchIndex = findSearchIndex(state.selection.from, matches, true);
92
+ return tr.setSelection(getSelectionForMatch(tr.selection, tr.doc, searchIndex, matches));
93
+ }));
94
+ };
95
+ var findInDirection = function findInDirection(state, dir) {
96
+ var pluginState = getPluginState(state);
97
+ var matches = pluginState.matches,
98
+ findText = pluginState.findText;
99
+ var decorationSet = pluginState.decorationSet,
100
+ index = pluginState.index;
101
+ if (findText) {
102
+ var searchIndex = findSearchIndex(state.selection.from, matches, dir === 'previous');
103
+ // compare index from plugin state and index of first match forward from cursor position
104
+ if (index === searchIndex) {
105
+ // normal case, cycling through matches
106
+ index = dir === 'next' ? nextIndex(index, matches.length) : prevIndex(index, matches.length);
107
+ } else {
108
+ // cursor has moved
109
+ index = searchIndex;
110
+ }
111
+ decorationSet = updateSelectedHighlight(state, index);
112
+ }
113
+ return {
114
+ type: dir === 'next' ? FindReplaceActionTypes.FIND_NEXT : FindReplaceActionTypes.FIND_PREVIOUS,
115
+ index: index,
116
+ decorationSet: decorationSet
117
+ };
118
+ };
119
+ export var replace = function replace(replaceText) {
120
+ return withScrollIntoView(createCommand(function (state) {
121
+ var pluginState = getPluginState(state);
122
+ var findText = pluginState.findText;
123
+ var decorationSet = pluginState.decorationSet,
124
+ matches = pluginState.matches,
125
+ index = pluginState.index;
126
+ decorationSet = updateSelectedHighlight(state, nextIndex(index, matches.length));
127
+ if (replaceText.toLowerCase().indexOf(findText.toLowerCase()) === -1) {
128
+ decorationSet = removeMatchesFromSet(decorationSet, [matches[index]], state.doc);
129
+ matches.splice(index, 1);
130
+ if (index > matches.length - 1) {
131
+ index = 0;
132
+ }
133
+ } else {
134
+ index = nextIndex(index, matches.length);
135
+ }
136
+ return {
137
+ type: FindReplaceActionTypes.REPLACE,
138
+ replaceText: replaceText,
139
+ decorationSet: decorationSet,
140
+ matches: matches,
141
+ index: index
142
+ };
143
+ }, function (tr, state) {
144
+ var _getPluginState6 = getPluginState(state),
145
+ matches = _getPluginState6.matches,
146
+ index = _getPluginState6.index,
147
+ findText = _getPluginState6.findText;
148
+ if (matches[index]) {
149
+ var _matches$index = matches[index],
150
+ start = _matches$index.start,
151
+ end = _matches$index.end;
152
+ var newIndex = nextIndex(index, matches.length);
153
+ tr.insertText(replaceText, start, end).setSelection(getSelectionForMatch(tr.selection, tr.doc, newIndex, matches, newIndex === 0 ? 0 : replaceText.length - findText.length));
154
+ }
155
+ return tr;
156
+ }));
157
+ };
158
+ export var replaceAll = function replaceAll(replaceText) {
159
+ return createCommand({
160
+ type: FindReplaceActionTypes.REPLACE_ALL,
161
+ replaceText: replaceText,
162
+ decorationSet: DecorationSet.empty,
163
+ matches: [],
164
+ index: 0
165
+ }, function (tr, state) {
166
+ var pluginState = getPluginState(state);
167
+ pluginState.matches.forEach(function (match) {
168
+ tr.insertText(replaceText, tr.mapping.map(match.start), tr.mapping.map(match.end));
169
+ });
170
+ tr.setMeta('scrollIntoView', false);
171
+ return tr;
172
+ });
173
+ };
174
+ export var addDecorations = function addDecorations(decorations) {
175
+ return createCommand(function (state) {
176
+ var _getPluginState7 = getPluginState(state),
177
+ decorationSet = _getPluginState7.decorationSet;
178
+ return {
179
+ type: FindReplaceActionTypes.UPDATE_DECORATIONS,
180
+ decorationSet: decorationSet.add(state.doc, decorations)
181
+ };
182
+ });
183
+ };
184
+ export var removeDecorations = function removeDecorations(decorations) {
185
+ return createCommand(function (state) {
186
+ var _getPluginState8 = getPluginState(state),
187
+ decorationSet = _getPluginState8.decorationSet;
188
+ return {
189
+ type: FindReplaceActionTypes.UPDATE_DECORATIONS,
190
+ decorationSet: removeDecorationsFromSet(decorationSet, decorations, state.doc)
191
+ };
192
+ });
193
+ };
194
+ export var cancelSearch = function cancelSearch() {
195
+ return createCommand(function () {
196
+ batchDecorations.stop();
197
+ return {
198
+ type: FindReplaceActionTypes.CANCEL
199
+ };
200
+ });
201
+ };
202
+ export var blur = function blur() {
203
+ return createCommand({
204
+ type: FindReplaceActionTypes.BLUR
205
+ });
206
+ };
207
+ export var toggleMatchCase = function toggleMatchCase() {
208
+ return createCommand({
209
+ type: FindReplaceActionTypes.TOGGLE_MATCH_CASE
210
+ });
211
+ };
212
+ var updateSelectedHighlight = function updateSelectedHighlight(state, nextSelectedIndex) {
213
+ var _getPluginState9 = getPluginState(state),
214
+ decorationSet = _getPluginState9.decorationSet,
215
+ index = _getPluginState9.index,
216
+ matches = _getPluginState9.matches;
217
+ var currentSelectedMatch = matches[index];
218
+ var nextSelectedMatch = matches[nextSelectedIndex];
219
+ if (index === nextSelectedIndex) {
220
+ return decorationSet;
221
+ }
222
+ var currentSelectedDecoration = findDecorationFromMatch(decorationSet, currentSelectedMatch);
223
+ var nextSelectedDecoration = findDecorationFromMatch(decorationSet, nextSelectedMatch);
224
+
225
+ // Update decorations so the current selected match becomes a normal match
226
+ // and the next selected gets the selected styling
227
+ var decorationsToRemove = [];
228
+ if (currentSelectedDecoration) {
229
+ decorationsToRemove.push(currentSelectedDecoration);
230
+ }
231
+ if (nextSelectedDecoration) {
232
+ decorationsToRemove.push(nextSelectedDecoration);
233
+ }
234
+ if (decorationsToRemove.length > 0) {
235
+ // removeDecorationsFromSet depends on decorations being pre-sorted
236
+ decorationsToRemove.sort(function (a, b) {
237
+ return a.from < b.from ? -1 : 1;
238
+ });
239
+ decorationSet = removeDecorationsFromSet(decorationSet, decorationsToRemove, state.doc);
240
+ }
241
+ if (currentSelectedMatch) {
242
+ decorationSet = decorationSet.add(state.doc, [createDecoration(currentSelectedMatch.start, currentSelectedMatch.end)]);
243
+ }
244
+ if (nextSelectedMatch) {
245
+ decorationSet = decorationSet.add(state.doc, [createDecoration(nextSelectedMatch.start, nextSelectedMatch.end, true)]);
246
+ }
247
+ return decorationSet;
248
+ };
@@ -0,0 +1 @@
1
+ export { findReplacePlugin } from './plugin';
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import FindReplaceToolbarButtonWithState from './FindReplaceToolbarButtonWithState';
3
+ import keymapPlugin from './pm-plugins/keymap';
4
+ import { createPlugin } from './pm-plugins/main';
5
+ import { findReplacePluginKey } from './pm-plugins/plugin-key';
6
+ export var findReplacePlugin = function findReplacePlugin(_ref) {
7
+ var _api$featureFlags;
8
+ var props = _ref.config,
9
+ api = _ref.api;
10
+ var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
11
+ return {
12
+ name: 'findReplace',
13
+ pmPlugins: function pmPlugins() {
14
+ return [{
15
+ name: 'findReplace',
16
+ plugin: function plugin(_ref2) {
17
+ var dispatch = _ref2.dispatch;
18
+ return createPlugin(dispatch);
19
+ }
20
+ }, {
21
+ name: 'findReplaceKeymap',
22
+ plugin: function plugin() {
23
+ var _api$analytics;
24
+ return keymapPlugin(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
25
+ }
26
+ }];
27
+ },
28
+ getSharedState: function getSharedState(editorState) {
29
+ if (!editorState) {
30
+ return undefined;
31
+ }
32
+ return findReplacePluginKey.getState(editorState) || undefined;
33
+ },
34
+ actions: {
35
+ getToolbarButton: function getToolbarButton(_ref3) {
36
+ var popupsBoundariesElement = _ref3.popupsBoundariesElement,
37
+ popupsMountPoint = _ref3.popupsMountPoint,
38
+ popupsScrollableElement = _ref3.popupsScrollableElement,
39
+ editorView = _ref3.editorView,
40
+ containerElement = _ref3.containerElement,
41
+ dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent,
42
+ isToolbarReducedSpacing = _ref3.isToolbarReducedSpacing;
43
+ return /*#__PURE__*/React.createElement(FindReplaceToolbarButtonWithState, {
44
+ popupsBoundariesElement: popupsBoundariesElement,
45
+ popupsMountPoint: popupsMountPoint,
46
+ popupsScrollableElement: popupsScrollableElement,
47
+ editorView: editorView,
48
+ containerElement: containerElement,
49
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent
50
+ // `allowMatchCase` comes through the preset, but not the feature flags
51
+ // prop with the `ComposableEditor` - grab the FFs from the editor API
52
+ // instead until we clean this up.
53
+ ,
54
+ featureFlags: featureFlags,
55
+ isToolbarReducedSpacing: isToolbarReducedSpacing,
56
+ api: api
57
+ });
58
+ }
59
+ },
60
+ primaryToolbarComponent: function primaryToolbarComponent(_ref4) {
61
+ var popupsBoundariesElement = _ref4.popupsBoundariesElement,
62
+ popupsMountPoint = _ref4.popupsMountPoint,
63
+ popupsScrollableElement = _ref4.popupsScrollableElement,
64
+ isToolbarReducedSpacing = _ref4.isToolbarReducedSpacing,
65
+ editorView = _ref4.editorView,
66
+ containerElement = _ref4.containerElement,
67
+ dispatchAnalyticsEvent = _ref4.dispatchAnalyticsEvent;
68
+ if (props !== null && props !== void 0 && props.twoLineEditorToolbar) {
69
+ return null;
70
+ } else {
71
+ return /*#__PURE__*/React.createElement(FindReplaceToolbarButtonWithState, {
72
+ popupsBoundariesElement: popupsBoundariesElement,
73
+ popupsMountPoint: popupsMountPoint,
74
+ popupsScrollableElement: popupsScrollableElement,
75
+ isToolbarReducedSpacing: isToolbarReducedSpacing,
76
+ editorView: editorView,
77
+ containerElement: containerElement,
78
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
79
+ takeFullWidth: props === null || props === void 0 ? void 0 : props.takeFullWidth,
80
+ featureFlags: featureFlags,
81
+ api: api
82
+ });
83
+ }
84
+ }
85
+ };
86
+ };
@@ -0,0 +1,18 @@
1
+ import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { bindKeymapWithCommand, find as findKeymap } from '@atlaskit/editor-common/keymaps';
3
+ import { keymap } from '@atlaskit/editor-prosemirror/keymap';
4
+ import { activateWithAnalytics } from '../commands-with-analytics';
5
+ var activateFindReplace = function activateFindReplace(editorAnalyticsAPI) {
6
+ return function (state, dispatch) {
7
+ activateWithAnalytics(editorAnalyticsAPI)({
8
+ triggerMethod: TRIGGER_METHOD.SHORTCUT
9
+ })(state, dispatch);
10
+ return true;
11
+ };
12
+ };
13
+ var keymapPlugin = function keymapPlugin(editorAnalyticsAPI) {
14
+ var list = {};
15
+ bindKeymapWithCommand(findKeymap.common, activateFindReplace(editorAnalyticsAPI), list);
16
+ return keymap(list);
17
+ };
18
+ export default keymapPlugin;
@@ -0,0 +1,33 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { createPluginState, getPluginState } from './plugin-factory';
4
+ import { findReplacePluginKey } from './plugin-key';
5
+ export var initialState = {
6
+ isActive: false,
7
+ shouldFocus: false,
8
+ findText: '',
9
+ replaceText: '',
10
+ index: 0,
11
+ matches: [],
12
+ decorationSet: DecorationSet.empty,
13
+ shouldMatchCase: false
14
+ };
15
+ export var createPlugin = function createPlugin(dispatch) {
16
+ return new SafePlugin({
17
+ key: findReplacePluginKey,
18
+ state: createPluginState(dispatch, function () {
19
+ return initialState;
20
+ }),
21
+ props: {
22
+ decorations: function decorations(state) {
23
+ var _getPluginState = getPluginState(state),
24
+ isActive = _getPluginState.isActive,
25
+ findText = _getPluginState.findText,
26
+ decorationSet = _getPluginState.decorationSet;
27
+ if (isActive && findText) {
28
+ return decorationSet;
29
+ }
30
+ }
31
+ }
32
+ });
33
+ };
@@ -0,0 +1,104 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils';
6
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
+ import reducer from '../reducer';
8
+ import { createDecorations, findDecorationFromMatch, findMatches, findSearchIndex, isMatchAffectedByStep, removeDecorationsFromSet, removeMatchesFromSet } from '../utils';
9
+ import { findUniqueItemsIn } from '../utils/array'; // TODO: move into index export
10
+
11
+ import { initialState } from './main';
12
+ import { findReplacePluginKey } from './plugin-key';
13
+ var handleDocChanged = function handleDocChanged(tr, pluginState) {
14
+ var isActive = pluginState.isActive,
15
+ findText = pluginState.findText;
16
+ if (!isActive || !findText) {
17
+ return pluginState;
18
+ }
19
+ if (!tr.steps.find(stepHasSlice)) {
20
+ return pluginState;
21
+ }
22
+ var index = pluginState.index,
23
+ decorationSet = pluginState.decorationSet,
24
+ matches = pluginState.matches,
25
+ shouldMatchCase = pluginState.shouldMatchCase;
26
+ var newMatches = findMatches(tr.doc, findText, shouldMatchCase);
27
+ decorationSet = decorationSet.map(tr.mapping, tr.doc);
28
+ var numDecorations = decorationSet.find().length;
29
+ var mappedMatches = matches.map(function (match) {
30
+ return {
31
+ start: tr.mapping.map(match.start),
32
+ end: tr.mapping.map(match.end)
33
+ };
34
+ });
35
+ var matchesToAdd = [];
36
+ var matchesToDelete = [];
37
+ if (newMatches.length > 0 && numDecorations === 0) {
38
+ matchesToAdd = newMatches;
39
+ } else if (newMatches.length === 0 && numDecorations > 0) {
40
+ decorationSet = DecorationSet.empty;
41
+ } else if (newMatches.length > 0 || numDecorations > 0) {
42
+ // go through tr steps and find any new matches from user adding content or
43
+ // any dead matches from user deleting content
44
+ tr.steps.forEach(function (step) {
45
+ if (stepHasSlice(step)) {
46
+ // add all matches that are between the affected positions and don't already have
47
+ // corresponding decorations
48
+ matchesToAdd = [].concat(_toConsumableArray(matchesToAdd), _toConsumableArray(newMatches.filter(function (match) {
49
+ return isMatchAffectedByStep(match, step, tr) && !findDecorationFromMatch(decorationSet, match);
50
+ })));
51
+
52
+ // delete any matches that are missing from the newMatches array and have a
53
+ // corresponding decoration
54
+ matchesToDelete = [].concat(_toConsumableArray(matchesToDelete), _toConsumableArray(findUniqueItemsIn(mappedMatches.filter(function (match) {
55
+ return isMatchAffectedByStep(match, step, tr) && !!findDecorationFromMatch(decorationSet, match);
56
+ }), newMatches, function (firstMatch, secondMatch) {
57
+ return firstMatch.start === secondMatch.start && firstMatch.end === secondMatch.end;
58
+ })));
59
+ }
60
+ });
61
+ }
62
+
63
+ // update decorations if matches changed following document update
64
+ if (matchesToDelete.length > 0) {
65
+ var decorationsToDelete = matchesToDelete.reduce(function (decorations, match) {
66
+ return [].concat(_toConsumableArray(decorations), _toConsumableArray(decorationSet.find(match.start, match.end)));
67
+ }, []);
68
+ decorationSet = removeDecorationsFromSet(decorationSet, decorationsToDelete, tr.doc);
69
+ }
70
+ if (matchesToAdd.length > 0) {
71
+ decorationSet = decorationSet.add(tr.doc, createDecorations(tr.selection.from, matchesToAdd));
72
+ }
73
+
74
+ // update selected match if it has changed
75
+ var newIndex = index;
76
+ var selectedMatch = mappedMatches[index];
77
+ if (selectedMatch) {
78
+ newIndex = newMatches.findIndex(function (match) {
79
+ return match.start === selectedMatch.start;
80
+ });
81
+ }
82
+ if (newIndex === undefined || newIndex === -1) {
83
+ newIndex = findSearchIndex(tr.selection.from, newMatches);
84
+ }
85
+ var newSelectedMatch = newMatches[newIndex];
86
+ decorationSet = removeMatchesFromSet(decorationSet, [selectedMatch, newSelectedMatch], tr.doc);
87
+ if (newSelectedMatch) {
88
+ decorationSet = decorationSet.add(tr.doc, createDecorations(0, [newSelectedMatch]));
89
+ }
90
+ return _objectSpread(_objectSpread({}, pluginState), {}, {
91
+ matches: newMatches,
92
+ index: newIndex,
93
+ decorationSet: decorationSet
94
+ });
95
+ };
96
+ var _pluginFactory = pluginFactory(findReplacePluginKey, reducer(function () {
97
+ return initialState;
98
+ }), {
99
+ onDocChanged: handleDocChanged
100
+ }),
101
+ createCommand = _pluginFactory.createCommand,
102
+ getPluginState = _pluginFactory.getPluginState,
103
+ createPluginState = _pluginFactory.createPluginState;
104
+ export { createCommand, getPluginState, createPluginState };
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
2
+ export var findReplacePluginKey = new PluginKey('findReplace');
@@ -0,0 +1,54 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import { FindReplaceActionTypes } from './actions';
5
+ var reducer = function reducer(getInitialState) {
6
+ return function (state, action) {
7
+ switch (action.type) {
8
+ case FindReplaceActionTypes.ACTIVATE:
9
+ case FindReplaceActionTypes.FIND:
10
+ return _objectSpread(_objectSpread({}, state), {}, {
11
+ isActive: true,
12
+ shouldFocus: action.type === FindReplaceActionTypes.ACTIVATE,
13
+ findText: action.findText !== undefined ? action.findText : state.findText,
14
+ matches: action.matches || state.matches,
15
+ index: action.index !== undefined ? action.index : state.index
16
+ });
17
+ case FindReplaceActionTypes.UPDATE_DECORATIONS:
18
+ return _objectSpread(_objectSpread({}, state), {}, {
19
+ decorationSet: action.decorationSet
20
+ });
21
+ case FindReplaceActionTypes.FIND_NEXT:
22
+ return _objectSpread(_objectSpread({}, state), {}, {
23
+ index: action.index,
24
+ decorationSet: action.decorationSet
25
+ });
26
+ case FindReplaceActionTypes.FIND_PREVIOUS:
27
+ return _objectSpread(_objectSpread({}, state), {}, {
28
+ index: action.index,
29
+ decorationSet: action.decorationSet
30
+ });
31
+ case FindReplaceActionTypes.REPLACE:
32
+ case FindReplaceActionTypes.REPLACE_ALL:
33
+ return _objectSpread(_objectSpread({}, state), {}, {
34
+ replaceText: action.replaceText,
35
+ decorationSet: action.decorationSet,
36
+ matches: action.matches,
37
+ index: action.index
38
+ });
39
+ case FindReplaceActionTypes.CANCEL:
40
+ return getInitialState();
41
+ case FindReplaceActionTypes.BLUR:
42
+ return _objectSpread(_objectSpread({}, state), {}, {
43
+ shouldFocus: false
44
+ });
45
+ case FindReplaceActionTypes.TOGGLE_MATCH_CASE:
46
+ return _objectSpread(_objectSpread({}, state), {}, {
47
+ shouldMatchCase: !state.shouldMatchCase
48
+ });
49
+ default:
50
+ return state;
51
+ }
52
+ };
53
+ };
54
+ export default reducer;
@@ -0,0 +1,11 @@
1
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
+ var _templateObject;
3
+ /* eslint-disable @atlaskit/design-system/ensure-design-token-usage/preview */
4
+ /* eslint-disable @atlaskit/design-system/ensure-design-token-usage */
5
+
6
+ // TODO: https://product-fabric.atlassian.net/browse/DSP-4290
7
+ import { css } from '@emotion/react';
8
+ import { B200, B75 } from '@atlaskit/theme/colors';
9
+ export var searchMatchClass = 'search-match';
10
+ export var selectedSearchMatchClass = 'selected-search-match';
11
+ export var findReplaceStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n .", " {\n background-color: ", ";\n }\n\n .", " {\n background-color: ", ";\n color: white;\n }\n"])), searchMatchClass, B75, selectedSearchMatchClass, B200);
@@ -0,0 +1 @@
1
+ export {};