@atlaskit/editor-plugin-find-replace 3.0.0 → 3.0.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/editor-plugin-find-replace
2
2
 
3
+ ## 3.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#182839](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/182839)
8
+ [`81f1c3383bdab`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/81f1c3383bdab) -
9
+ refactor: use useSharedPluginStateWithSelector instead of useSharedPluginStateSelector
10
+ - Updated dependencies
11
+
12
+ ## 3.0.1
13
+
14
+ ### Patch Changes
15
+
16
+ - [#180340](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/180340)
17
+ [`3cf803e05d3b9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3cf803e05d3b9) -
18
+ [ux] ED-28366 set active match to closest match to selection rather than first following selection
19
+ - Updated dependencies
20
+
3
21
  ## 3.0.0
4
22
 
5
23
  ### Major Changes
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.toggleMatchCase = exports.replaceAll = exports.replace = exports.removeDecorations = exports.findPrevious = exports.findNext = exports.find = exports.cancelSearch = exports.blur = exports.addDecorations = exports.activate = void 0;
8
8
  var _state = require("@atlaskit/editor-prosemirror/state");
9
9
  var _view = require("@atlaskit/editor-prosemirror/view");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
11
12
  var _actions = require("./actions");
12
13
  var _pluginFactory = require("./plugin-factory");
@@ -34,7 +35,7 @@ var activate = exports.activate = function activate() {
34
35
  getIntl: getIntl,
35
36
  api: api
36
37
  });
37
- index = (0, _utils.findSearchIndex)(selection.from, matches);
38
+ index = (0, _expValEquals.expValEquals)('platform_editor_find_and_replace_improvements', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('platform_editor_find_and_replace_improvements_1') ? (0, _utils.findClosestMatch)(selection.from, matches) : (0, _utils.findSearchIndex)(selection.from, matches);
38
39
  }
39
40
  return {
40
41
  type: _actions.FindReplaceActionTypes.ACTIVATE,
@@ -58,7 +59,7 @@ var find = exports.find = function find(editorView, containerElement, keyword) {
58
59
  getIntl: getIntl,
59
60
  api: api
60
61
  }) : [];
61
- var index = (0, _utils.findSearchIndex)(selection.from, matches);
62
+ var index = (0, _expValEquals.expValEquals)('platform_editor_find_and_replace_improvements', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('platform_editor_find_and_replace_improvements_1') ? (0, _utils.findClosestMatch)(selection.from, matches) : (0, _utils.findSearchIndex)(selection.from, matches);
62
63
 
63
64
  // we can't just apply all the decorations to highlight the search results at once
64
65
  // as if there are a lot ProseMirror cries :'(
@@ -87,7 +88,7 @@ var find = exports.find = function find(editorView, containerElement, keyword) {
87
88
  api: api
88
89
  }) : [];
89
90
  if (matches.length > 0) {
90
- var index = (0, _utils.findSearchIndex)(selection.from, matches);
91
+ var index = (0, _expValEquals.expValEquals)('platform_editor_find_and_replace_improvements', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('platform_editor_find_and_replace_improvements_1') ? (0, _utils.findClosestMatch)(selection.from, matches) : (0, _utils.findSearchIndex)(selection.from, matches);
91
92
  return tr.setSelection((0, _utils.getSelectionForMatch)(tr.selection, tr.doc, index, matches));
92
93
  }
93
94
  return tr;
@@ -9,6 +9,8 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _utils = require("@atlaskit/editor-common/utils");
11
11
  var _view = require("@atlaskit/editor-prosemirror/view");
12
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
12
14
  var _main = require("./main");
13
15
  var _pluginKey = require("./plugin-key");
14
16
  var _reducer = _interopRequireDefault(require("./reducer"));
@@ -101,7 +103,7 @@ var handleDocChanged = function handleDocChanged(tr, pluginState) {
101
103
  });
102
104
  }
103
105
  if (newIndex === undefined || newIndex === -1) {
104
- newIndex = (0, _utils2.findSearchIndex)(tr.selection.from, newMatches);
106
+ newIndex = (0, _expValEquals.expValEquals)('platform_editor_find_and_replace_improvements', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('platform_editor_find_and_replace_improvements_1') ? (0, _utils2.findClosestMatch)(tr.selection.from, newMatches) : (0, _utils2.findSearchIndex)(tr.selection.from, newMatches);
105
107
  }
106
108
  var newSelectedMatch = newMatches[newIndex];
107
109
  decorationSet = (0, _utils2.removeMatchesFromSet)(decorationSet, [selectedMatch, newSelectedMatch], tr.doc);
@@ -4,7 +4,9 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.findLostAdjacentDecorations = exports.findIndexBeforePosition = exports.findDecorationFromMatch = exports.createDecorations = exports.createDecoration = void 0;
7
+ exports.createDecorations = exports.createDecoration = void 0;
8
+ exports.findClosestMatch = findClosestMatch;
9
+ exports.findLostAdjacentDecorations = exports.findIndexBeforePosition = exports.findDecorationFromMatch = void 0;
8
10
  exports.findMatches = findMatches;
9
11
  exports.findSearchIndex = findSearchIndex;
10
12
  exports.getSelectedText = getSelectedText;
@@ -247,6 +249,22 @@ function findMatches(_ref2) {
247
249
  }
248
250
  return matches;
249
251
  }
252
+ function findClosestMatch(selectionPos, matches) {
253
+ var forwardMatchIndex = Math.max(matches.findIndex(function (match) {
254
+ return match.start >= selectionPos;
255
+ }), 0);
256
+ if (forwardMatchIndex === 0) {
257
+ return forwardMatchIndex;
258
+ }
259
+ var backwardMatchIndex = forwardMatchIndex - 1;
260
+ var forwardMatchPos = matches[forwardMatchIndex].start;
261
+ var backwardMatchPos = matches[backwardMatchIndex].end;
262
+ if (forwardMatchPos - selectionPos < selectionPos - backwardMatchPos) {
263
+ return forwardMatchIndex;
264
+ } else {
265
+ return backwardMatchIndex;
266
+ }
267
+ }
250
268
 
251
269
  /**
252
270
  * Finds index of first item in matches array that comes after user's cursor pos.
@@ -9,13 +9,11 @@ exports.default = void 0;
9
9
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _analytics = require("@atlaskit/editor-common/analytics");
12
- var _hooks = require("@atlaskit/editor-common/hooks");
13
12
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
13
  var _commands = require("../pm-plugins/commands");
15
14
  var _commandsWithAnalytics = require("../pm-plugins/commands-with-analytics");
16
15
  var _FindReplaceDropdown = _interopRequireDefault(require("./FindReplaceDropdown"));
17
16
  var _FindReplaceToolbarButton = _interopRequireDefault(require("./FindReplaceToolbarButton"));
18
- var _useFindReplacePluginStateSelector = require("./hooks/useFindReplacePluginStateSelector");
19
17
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
20
18
  // light implementation of useSharedPluginState(). This is due to findreplace
21
19
  // being the only plugin that previously used WithPluginState with
@@ -42,36 +40,6 @@ var useSharedPluginStateNoDebounce = function useSharedPluginStateNoDebounce(api
42
40
  findReplaceState: state
43
41
  };
44
42
  };
45
- var useSharedState = (0, _hooks.sharedPluginStateHookMigratorFactory)(function (api) {
46
- var shouldMatchCase = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'shouldMatchCase');
47
- var isActive = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'isActive');
48
- var findText = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'findText');
49
- var replaceText = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'replaceText');
50
- var index = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'index');
51
- var matches = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'matches');
52
- var shouldFocus = (0, _useFindReplacePluginStateSelector.useFindReplacePluginStateSelector)(api, 'shouldFocus');
53
- return {
54
- shouldMatchCase: shouldMatchCase,
55
- isActive: isActive,
56
- findText: findText,
57
- replaceText: replaceText,
58
- index: index,
59
- matches: matches,
60
- shouldFocus: shouldFocus
61
- };
62
- }, function (api) {
63
- var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
64
- findReplaceState = _useSharedPluginState.findReplaceState;
65
- return {
66
- shouldMatchCase: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase,
67
- isActive: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive,
68
- findText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText,
69
- replaceText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText,
70
- index: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index,
71
- matches: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches,
72
- shouldFocus: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus
73
- };
74
- });
75
43
  var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithState(_ref2) {
76
44
  var _api$analytics, _matches$index;
77
45
  var popupsBoundariesElement = _ref2.popupsBoundariesElement,
@@ -86,14 +54,15 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
86
54
  isButtonHidden = _ref2.isButtonHidden,
87
55
  doesNotHaveButton = _ref2.doesNotHaveButton;
88
56
  var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
89
- var _useSharedState = useSharedState(api),
90
- shouldMatchCase = _useSharedState.shouldMatchCase,
91
- isActive = _useSharedState.isActive,
92
- findText = _useSharedState.findText,
93
- replaceText = _useSharedState.replaceText,
94
- index = _useSharedState.index,
95
- matches = _useSharedState.matches,
96
- shouldFocus = _useSharedState.shouldFocus;
57
+ var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
58
+ findReplaceState = _useSharedPluginState.findReplaceState;
59
+ var shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
60
+ var isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
61
+ var findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
62
+ var replaceText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText;
63
+ var index = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index;
64
+ var matches = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches;
65
+ var shouldFocus = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus;
97
66
  if (!editorView) {
98
67
  return null;
99
68
  }
@@ -1,9 +1,10 @@
1
1
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
2
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
5
  import { FindReplaceActionTypes } from './actions';
5
6
  import { createCommand, getPluginState } from './plugin-factory';
6
- import { createDecoration, findDecorationFromMatch, findMatches, findSearchIndex, getSelectedText, getSelectionForMatch, nextIndex, prevIndex, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
7
+ import { createDecoration, findClosestMatch, findDecorationFromMatch, findMatches, findSearchIndex, getSelectedText, getSelectionForMatch, nextIndex, prevIndex, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
7
8
  import batchDecorations from './utils/batch-decorations';
8
9
  import { withScrollIntoView } from './utils/commands';
9
10
  export const activate = () => createCommand(state => {
@@ -29,7 +30,7 @@ export const activate = () => createCommand(state => {
29
30
  getIntl,
30
31
  api
31
32
  });
32
- index = findSearchIndex(selection.from, matches);
33
+ index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
33
34
  }
34
35
  return {
35
36
  type: FindReplaceActionTypes.ACTIVATE,
@@ -54,7 +55,7 @@ export const find = (editorView, containerElement, keyword) => withScrollIntoVie
54
55
  getIntl,
55
56
  api
56
57
  }) : [];
57
- const index = findSearchIndex(selection.from, matches);
58
+ const index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
58
59
 
59
60
  // we can't just apply all the decorations to highlight the search results at once
60
61
  // as if there are a lot ProseMirror cries :'(
@@ -82,7 +83,7 @@ export const find = (editorView, containerElement, keyword) => withScrollIntoVie
82
83
  api
83
84
  }) : [];
84
85
  if (matches.length > 0) {
85
- const index = findSearchIndex(selection.from, matches);
86
+ const index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
86
87
  return tr.setSelection(getSelectionForMatch(tr.selection, tr.doc, index, matches));
87
88
  }
88
89
  return tr;
@@ -1,9 +1,11 @@
1
1
  import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils';
2
2
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
5
  import { initialState } from './main';
4
6
  import { findReplacePluginKey } from './plugin-key';
5
7
  import reducer from './reducer';
6
- import { createDecorations, findDecorationFromMatch, findMatches, findSearchIndex, isMatchAffectedByStep, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
8
+ import { createDecorations, findClosestMatch, findDecorationFromMatch, findMatches, findSearchIndex, isMatchAffectedByStep, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
7
9
  import { findUniqueItemsIn } from './utils/array'; // TODO: ED-26959 - move into index export
8
10
 
9
11
  const handleDocChanged = (tr, pluginState) => {
@@ -81,7 +83,7 @@ const handleDocChanged = (tr, pluginState) => {
81
83
  newIndex = newMatches.findIndex(match => match.start === selectedMatch.start);
82
84
  }
83
85
  if (newIndex === undefined || newIndex === -1) {
84
- newIndex = findSearchIndex(tr.selection.from, newMatches);
86
+ newIndex = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(tr.selection.from, newMatches) : findSearchIndex(tr.selection.from, newMatches);
85
87
  }
86
88
  const newSelectedMatch = newMatches[newIndex];
87
89
  decorationSet = removeMatchesFromSet(decorationSet, [selectedMatch, newSelectedMatch], tr.doc);
@@ -246,6 +246,20 @@ export function findMatches({
246
246
  }
247
247
  return matches;
248
248
  }
249
+ export function findClosestMatch(selectionPos, matches) {
250
+ const forwardMatchIndex = Math.max(matches.findIndex(match => match.start >= selectionPos), 0);
251
+ if (forwardMatchIndex === 0) {
252
+ return forwardMatchIndex;
253
+ }
254
+ const backwardMatchIndex = forwardMatchIndex - 1;
255
+ const forwardMatchPos = matches[forwardMatchIndex].start;
256
+ const backwardMatchPos = matches[backwardMatchIndex].end;
257
+ if (forwardMatchPos - selectionPos < selectionPos - backwardMatchPos) {
258
+ return forwardMatchIndex;
259
+ } else {
260
+ return backwardMatchIndex;
261
+ }
262
+ }
249
263
 
250
264
  /**
251
265
  * Finds index of first item in matches array that comes after user's cursor pos.
@@ -1,12 +1,10 @@
1
1
  import React, { useLayoutEffect, useState } from 'react';
2
2
  import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
3
- import { sharedPluginStateHookMigratorFactory } from '@atlaskit/editor-common/hooks';
4
3
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
4
  import { blur, toggleMatchCase } from '../pm-plugins/commands';
6
5
  import { activateWithAnalytics, cancelSearchWithAnalytics, findNextWithAnalytics, findPrevWithAnalytics, findWithAnalytics, replaceAllWithAnalytics, replaceWithAnalytics } from '../pm-plugins/commands-with-analytics';
7
6
  import FindReplaceDropdown from './FindReplaceDropdown';
8
7
  import FindReplaceToolbarButton from './FindReplaceToolbarButton';
9
- import { useFindReplacePluginStateSelector } from './hooks/useFindReplacePluginStateSelector';
10
8
 
11
9
  // light implementation of useSharedPluginState(). This is due to findreplace
12
10
  // being the only plugin that previously used WithPluginState with
@@ -31,37 +29,6 @@ const useSharedPluginStateNoDebounce = api => {
31
29
  findReplaceState: state
32
30
  };
33
31
  };
34
- const useSharedState = sharedPluginStateHookMigratorFactory(api => {
35
- const shouldMatchCase = useFindReplacePluginStateSelector(api, 'shouldMatchCase');
36
- const isActive = useFindReplacePluginStateSelector(api, 'isActive');
37
- const findText = useFindReplacePluginStateSelector(api, 'findText');
38
- const replaceText = useFindReplacePluginStateSelector(api, 'replaceText');
39
- const index = useFindReplacePluginStateSelector(api, 'index');
40
- const matches = useFindReplacePluginStateSelector(api, 'matches');
41
- const shouldFocus = useFindReplacePluginStateSelector(api, 'shouldFocus');
42
- return {
43
- shouldMatchCase,
44
- isActive,
45
- findText,
46
- replaceText,
47
- index,
48
- matches,
49
- shouldFocus
50
- };
51
- }, api => {
52
- const {
53
- findReplaceState
54
- } = useSharedPluginStateNoDebounce(api);
55
- return {
56
- shouldMatchCase: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase,
57
- isActive: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive,
58
- findText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText,
59
- replaceText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText,
60
- index: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index,
61
- matches: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches,
62
- shouldFocus: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus
63
- };
64
- });
65
32
  const FindReplaceToolbarButtonWithState = ({
66
33
  popupsBoundariesElement,
67
34
  popupsMountPoint,
@@ -78,14 +45,15 @@ const FindReplaceToolbarButtonWithState = ({
78
45
  var _api$analytics, _matches$index;
79
46
  const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
80
47
  const {
81
- shouldMatchCase,
82
- isActive,
83
- findText,
84
- replaceText,
85
- index,
86
- matches,
87
- shouldFocus
88
- } = useSharedState(api);
48
+ findReplaceState
49
+ } = useSharedPluginStateNoDebounce(api);
50
+ const shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
51
+ const isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
52
+ const findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
53
+ const replaceText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText;
54
+ const index = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index;
55
+ const matches = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches;
56
+ const shouldFocus = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus;
89
57
  if (!editorView) {
90
58
  return null;
91
59
  }
@@ -1,9 +1,10 @@
1
1
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
2
2
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
5
  import { FindReplaceActionTypes } from './actions';
5
6
  import { createCommand, getPluginState } from './plugin-factory';
6
- import { createDecoration, findDecorationFromMatch, findMatches, findSearchIndex, getSelectedText, getSelectionForMatch, nextIndex, prevIndex, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
7
+ import { createDecoration, findClosestMatch, findDecorationFromMatch, findMatches, findSearchIndex, getSelectedText, getSelectionForMatch, nextIndex, prevIndex, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
7
8
  import batchDecorations from './utils/batch-decorations';
8
9
  import { withScrollIntoView } from './utils/commands';
9
10
  export var activate = function activate() {
@@ -27,7 +28,7 @@ export var activate = function activate() {
27
28
  getIntl: getIntl,
28
29
  api: api
29
30
  });
30
- index = findSearchIndex(selection.from, matches);
31
+ index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
31
32
  }
32
33
  return {
33
34
  type: FindReplaceActionTypes.ACTIVATE,
@@ -51,7 +52,7 @@ export var find = function find(editorView, containerElement, keyword) {
51
52
  getIntl: getIntl,
52
53
  api: api
53
54
  }) : [];
54
- var index = findSearchIndex(selection.from, matches);
55
+ var index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
55
56
 
56
57
  // we can't just apply all the decorations to highlight the search results at once
57
58
  // as if there are a lot ProseMirror cries :'(
@@ -80,7 +81,7 @@ export var find = function find(editorView, containerElement, keyword) {
80
81
  api: api
81
82
  }) : [];
82
83
  if (matches.length > 0) {
83
- var index = findSearchIndex(selection.from, matches);
84
+ var index = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(selection.from, matches) : findSearchIndex(selection.from, matches);
84
85
  return tr.setSelection(getSelectionForMatch(tr.selection, tr.doc, index, matches));
85
86
  }
86
87
  return tr;
@@ -4,10 +4,12 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
4
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
5
  import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils';
6
6
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
+ import { fg } from '@atlaskit/platform-feature-flags';
8
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
9
  import { initialState } from './main';
8
10
  import { findReplacePluginKey } from './plugin-key';
9
11
  import reducer from './reducer';
10
- import { createDecorations, findDecorationFromMatch, findMatches, findSearchIndex, isMatchAffectedByStep, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
12
+ import { createDecorations, findClosestMatch, findDecorationFromMatch, findMatches, findSearchIndex, isMatchAffectedByStep, removeDecorationsFromSet, removeMatchesFromSet } from './utils';
11
13
  import { findUniqueItemsIn } from './utils/array'; // TODO: ED-26959 - move into index export
12
14
 
13
15
  var handleDocChanged = function handleDocChanged(tr, pluginState) {
@@ -93,7 +95,7 @@ var handleDocChanged = function handleDocChanged(tr, pluginState) {
93
95
  });
94
96
  }
95
97
  if (newIndex === undefined || newIndex === -1) {
96
- newIndex = findSearchIndex(tr.selection.from, newMatches);
98
+ newIndex = expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && fg('platform_editor_find_and_replace_improvements_1') ? findClosestMatch(tr.selection.from, newMatches) : findSearchIndex(tr.selection.from, newMatches);
97
99
  }
98
100
  var newSelectedMatch = newMatches[newIndex];
99
101
  decorationSet = removeMatchesFromSet(decorationSet, [selectedMatch, newSelectedMatch], tr.doc);
@@ -236,6 +236,22 @@ export function findMatches(_ref2) {
236
236
  }
237
237
  return matches;
238
238
  }
239
+ export function findClosestMatch(selectionPos, matches) {
240
+ var forwardMatchIndex = Math.max(matches.findIndex(function (match) {
241
+ return match.start >= selectionPos;
242
+ }), 0);
243
+ if (forwardMatchIndex === 0) {
244
+ return forwardMatchIndex;
245
+ }
246
+ var backwardMatchIndex = forwardMatchIndex - 1;
247
+ var forwardMatchPos = matches[forwardMatchIndex].start;
248
+ var backwardMatchPos = matches[backwardMatchIndex].end;
249
+ if (forwardMatchPos - selectionPos < selectionPos - backwardMatchPos) {
250
+ return forwardMatchIndex;
251
+ } else {
252
+ return backwardMatchIndex;
253
+ }
254
+ }
239
255
 
240
256
  /**
241
257
  * Finds index of first item in matches array that comes after user's cursor pos.
@@ -1,13 +1,11 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import React, { useLayoutEffect, useState } from 'react';
3
3
  import { TRIGGER_METHOD } from '@atlaskit/editor-common/analytics';
4
- import { sharedPluginStateHookMigratorFactory } from '@atlaskit/editor-common/hooks';
5
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
5
  import { blur, toggleMatchCase } from '../pm-plugins/commands';
7
6
  import { activateWithAnalytics, cancelSearchWithAnalytics, findNextWithAnalytics, findPrevWithAnalytics, findWithAnalytics, replaceAllWithAnalytics, replaceWithAnalytics } from '../pm-plugins/commands-with-analytics';
8
7
  import FindReplaceDropdown from './FindReplaceDropdown';
9
8
  import FindReplaceToolbarButton from './FindReplaceToolbarButton';
10
- import { useFindReplacePluginStateSelector } from './hooks/useFindReplacePluginStateSelector';
11
9
 
12
10
  // light implementation of useSharedPluginState(). This is due to findreplace
13
11
  // being the only plugin that previously used WithPluginState with
@@ -34,36 +32,6 @@ var useSharedPluginStateNoDebounce = function useSharedPluginStateNoDebounce(api
34
32
  findReplaceState: state
35
33
  };
36
34
  };
37
- var useSharedState = sharedPluginStateHookMigratorFactory(function (api) {
38
- var shouldMatchCase = useFindReplacePluginStateSelector(api, 'shouldMatchCase');
39
- var isActive = useFindReplacePluginStateSelector(api, 'isActive');
40
- var findText = useFindReplacePluginStateSelector(api, 'findText');
41
- var replaceText = useFindReplacePluginStateSelector(api, 'replaceText');
42
- var index = useFindReplacePluginStateSelector(api, 'index');
43
- var matches = useFindReplacePluginStateSelector(api, 'matches');
44
- var shouldFocus = useFindReplacePluginStateSelector(api, 'shouldFocus');
45
- return {
46
- shouldMatchCase: shouldMatchCase,
47
- isActive: isActive,
48
- findText: findText,
49
- replaceText: replaceText,
50
- index: index,
51
- matches: matches,
52
- shouldFocus: shouldFocus
53
- };
54
- }, function (api) {
55
- var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
56
- findReplaceState = _useSharedPluginState.findReplaceState;
57
- return {
58
- shouldMatchCase: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase,
59
- isActive: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive,
60
- findText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText,
61
- replaceText: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText,
62
- index: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index,
63
- matches: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches,
64
- shouldFocus: findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus
65
- };
66
- });
67
35
  var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithState(_ref2) {
68
36
  var _api$analytics, _matches$index;
69
37
  var popupsBoundariesElement = _ref2.popupsBoundariesElement,
@@ -78,14 +46,15 @@ var FindReplaceToolbarButtonWithState = function FindReplaceToolbarButtonWithSta
78
46
  isButtonHidden = _ref2.isButtonHidden,
79
47
  doesNotHaveButton = _ref2.doesNotHaveButton;
80
48
  var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
81
- var _useSharedState = useSharedState(api),
82
- shouldMatchCase = _useSharedState.shouldMatchCase,
83
- isActive = _useSharedState.isActive,
84
- findText = _useSharedState.findText,
85
- replaceText = _useSharedState.replaceText,
86
- index = _useSharedState.index,
87
- matches = _useSharedState.matches,
88
- shouldFocus = _useSharedState.shouldFocus;
49
+ var _useSharedPluginState = useSharedPluginStateNoDebounce(api),
50
+ findReplaceState = _useSharedPluginState.findReplaceState;
51
+ var shouldMatchCase = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldMatchCase;
52
+ var isActive = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.isActive;
53
+ var findText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.findText;
54
+ var replaceText = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.replaceText;
55
+ var index = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.index;
56
+ var matches = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.matches;
57
+ var shouldFocus = findReplaceState === null || findReplaceState === void 0 ? void 0 : findReplaceState.shouldFocus;
89
58
  if (!editorView) {
90
59
  return null;
91
60
  }
@@ -20,6 +20,7 @@ type FindMatchesType = {
20
20
  api?: ExtractInjectionAPI<FindReplacePlugin>;
21
21
  };
22
22
  export declare function findMatches({ content, searchText, shouldMatchCase, contentIndex, getIntl, api, }: FindMatchesType): Match[];
23
+ export declare function findClosestMatch(selectionPos: number, matches: Match[]): number;
23
24
  /**
24
25
  * Finds index of first item in matches array that comes after user's cursor pos.
25
26
  * If `backward` is `true`, finds index of first item that comes before instead.
@@ -20,6 +20,7 @@ type FindMatchesType = {
20
20
  api?: ExtractInjectionAPI<FindReplacePlugin>;
21
21
  };
22
22
  export declare function findMatches({ content, searchText, shouldMatchCase, contentIndex, getIntl, api, }: FindMatchesType): Match[];
23
+ export declare function findClosestMatch(selectionPos: number, matches: Match[]): number;
23
24
  /**
24
25
  * Finds index of first item in matches array that comes after user's cursor pos.
25
26
  * If `backward` is `true`, finds index of first item that comes before instead.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-find-replace",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "find replace plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,19 +35,19 @@
35
35
  "@atlaskit/button": "^23.2.0",
36
36
  "@atlaskit/editor-plugin-analytics": "^3.0.0",
37
37
  "@atlaskit/editor-plugin-card": "^7.0.0",
38
- "@atlaskit/editor-plugin-mentions": "^5.0.0",
38
+ "@atlaskit/editor-plugin-mentions": "^5.1.0",
39
39
  "@atlaskit/editor-plugin-primary-toolbar": "^4.0.0",
40
40
  "@atlaskit/editor-prosemirror": "7.0.0",
41
41
  "@atlaskit/editor-shared-styles": "^3.4.0",
42
42
  "@atlaskit/form": "^12.0.0",
43
- "@atlaskit/icon": "^27.2.0",
43
+ "@atlaskit/icon": "^27.3.0",
44
44
  "@atlaskit/icon-lab": "^5.1.0",
45
45
  "@atlaskit/mention": "^24.2.0",
46
46
  "@atlaskit/platform-feature-flags": "^1.1.0",
47
47
  "@atlaskit/primitives": "^14.10.0",
48
48
  "@atlaskit/textfield": "^8.0.0",
49
49
  "@atlaskit/theme": "^18.0.0",
50
- "@atlaskit/tmp-editor-statsig": "^8.7.0",
50
+ "@atlaskit/tmp-editor-statsig": "^9.0.0",
51
51
  "@atlaskit/tokens": "^5.4.0",
52
52
  "@atlaskit/tooltip": "^20.3.0",
53
53
  "@babel/runtime": "^7.0.0",
@@ -67,7 +67,7 @@
67
67
  "react-dom": "^18.2.0"
68
68
  },
69
69
  "peerDependencies": {
70
- "@atlaskit/editor-common": "^107.6.0",
70
+ "@atlaskit/editor-common": "^107.7.0",
71
71
  "react": "^18.2.0",
72
72
  "react-intl-next": "npm:react-intl@^5.18.1"
73
73
  },