@atlaskit/editor-plugin-block-controls 7.18.0 → 7.18.1

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,12 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 7.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`7b47062997f9b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7b47062997f9b) -
8
+ EDITOR-3793 Stop preserving selection on click into editor
9
+
3
10
  ## 7.18.0
4
11
 
5
12
  ### Minor Changes
@@ -8,6 +8,7 @@ exports.createSelectionPreservationPlugin = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _monitoring = require("@atlaskit/editor-common/monitoring");
10
10
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
11
+ var _styles = require("@atlaskit/editor-common/styles");
11
12
  var _selection = require("../utils/selection");
12
13
  var _editorCommands = require("./editor-commands");
13
14
  var _pluginKey = require("./plugin-key");
@@ -41,6 +42,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
41
42
  * is open (editor becomes non-interactive), during drag-and-drop operations (user is mid-drag), or
42
43
  * when modal dialogs are active. In these states, any selection changes are from ProseMirror's
43
44
  * internal behavior (not user input) and should be prevented. Do not use during normal editing.
45
+ *
46
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/6170822503/Block+Menu+Solution+for+multi-select+and+selection+preservation
44
47
  */
45
48
  var createSelectionPreservationPlugin = exports.createSelectionPreservationPlugin = function createSelectionPreservationPlugin(api) {
46
49
  return function () {
@@ -56,7 +59,7 @@ var createSelectionPreservationPlugin = exports.createSelectionPreservationPlugi
56
59
  var meta = (0, _utils.getSelectionPreservationMeta)(tr);
57
60
  var newState = _objectSpread({}, pluginState);
58
61
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'startPreserving') {
59
- newState.preservedSelection = tr.selection;
62
+ newState.preservedSelection = (0, _selection.mapPreservedSelection)(tr.selection, tr);
60
63
  } else if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'stopPreserving') {
61
64
  newState.preservedSelection = undefined;
62
65
  }
@@ -94,11 +97,34 @@ var createSelectionPreservationPlugin = exports.createSelectionPreservationPlugi
94
97
  return null;
95
98
  },
96
99
  props: {
97
- handleKeyDown: function handleKeyDown(view, event) {
98
- var _api$userIntent;
100
+ handleClick: function handleClick(view, pos, event) {
99
101
  var _ref = _pluginKey.selectionPreservationPluginKey.getState(view.state) || {},
100
102
  preservedSelection = _ref.preservedSelection;
101
103
 
104
+ // If there is no current preserved selection, do nothing
105
+ if (!preservedSelection) {
106
+ return false;
107
+ }
108
+ var clickedDragHandle = event.target instanceof HTMLElement && event.target.closest(_styles.DRAG_HANDLE_SELECTOR);
109
+
110
+ // When clicking a drag handle we continue preserving the selection
111
+ if (!clickedDragHandle) {
112
+ return false;
113
+ }
114
+
115
+ // Otherwise clicking anywhere else in the editor stops preserving the selection
116
+ var tr = view.state.tr;
117
+ (0, _editorCommands.stopPreservingSelection)({
118
+ tr: tr
119
+ });
120
+ view.dispatch(tr);
121
+ return false;
122
+ },
123
+ handleKeyDown: function handleKeyDown(view, event) {
124
+ var _api$userIntent;
125
+ var _ref2 = _pluginKey.selectionPreservationPluginKey.getState(view.state) || {},
126
+ preservedSelection = _ref2.preservedSelection;
127
+
102
128
  // If there is no current preserved selection, do nothing
103
129
  if (!preservedSelection) {
104
130
  return false;
@@ -97,19 +97,22 @@ var mapPreservedSelection = exports.mapPreservedSelection = function mapPreserve
97
97
  var to = mapping.map(selection.to);
98
98
  var isSelectionEmpty = from === to;
99
99
  var wasSelectionEmpty = selection.from === selection.to;
100
- if (isSelectionEmpty) {
101
- if (!wasSelectionEmpty) {
102
- // If selection has become empty i.e. content has been deleted, stop preserving
103
- return undefined;
104
- }
105
- // When preserving a cursor selection, just map the position without expanding
106
- return new _state.TextSelection(tr.doc.resolve(from));
100
+ if (isSelectionEmpty && !wasSelectionEmpty) {
101
+ // If selection has become empty i.e. content has been deleted, stop preserving
102
+ return undefined;
107
103
  }
108
-
109
104
  // expand the text selection range to block boundaries, so as document changes occur the
110
105
  // selection always includes whole nodes
111
106
  var expanded = (0, _selection.expandToBlockRange)(tr.doc.resolve(from), tr.doc.resolve(to));
112
107
 
108
+ // If after expanding the selection it is still empty, return a single cursor selection at 'from'
109
+ var nodeAfter = expanded.$from.nodeAfter;
110
+ var nodeBefore = expanded.$to.nodeBefore;
111
+ var expandedSelectionEmpty = nodeAfter === nodeBefore && (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.content.size) === 0;
112
+ if (isSelectionEmpty && expandedSelectionEmpty) {
113
+ return _state.TextSelection.create(tr.doc, from);
114
+ }
115
+
113
116
  // collapse the expanded range to a valid selection range
114
117
  var _collapseToSelectionR = (0, _getSelection.collapseToSelectionRange)(expanded.$from, expanded.$to),
115
118
  $from = _collapseToSelectionR.$from,
@@ -1,5 +1,6 @@
1
1
  import { logException } from '@atlaskit/editor-common/monitoring';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
+ import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
3
4
  import { mapPreservedSelection } from '../utils/selection';
4
5
  import { stopPreservingSelection } from './editor-commands';
5
6
  import { selectionPreservationPluginKey } from './plugin-key';
@@ -32,6 +33,8 @@ import { getSelectionPreservationMeta, hasUserSelectionChange } from './utils';
32
33
  * is open (editor becomes non-interactive), during drag-and-drop operations (user is mid-drag), or
33
34
  * when modal dialogs are active. In these states, any selection changes are from ProseMirror's
34
35
  * internal behavior (not user input) and should be prevented. Do not use during normal editing.
36
+ *
37
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/6170822503/Block+Menu+Solution+for+multi-select+and+selection+preservation
35
38
  */
36
39
  export const createSelectionPreservationPlugin = api => () => {
37
40
  return new SafePlugin({
@@ -48,7 +51,7 @@ export const createSelectionPreservationPlugin = api => () => {
48
51
  ...pluginState
49
52
  };
50
53
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'startPreserving') {
51
- newState.preservedSelection = tr.selection;
54
+ newState.preservedSelection = mapPreservedSelection(tr.selection, tr);
52
55
  } else if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'stopPreserving') {
53
56
  newState.preservedSelection = undefined;
54
57
  }
@@ -86,6 +89,30 @@ export const createSelectionPreservationPlugin = api => () => {
86
89
  return null;
87
90
  },
88
91
  props: {
92
+ handleClick: (view, pos, event) => {
93
+ const {
94
+ preservedSelection
95
+ } = selectionPreservationPluginKey.getState(view.state) || {};
96
+
97
+ // If there is no current preserved selection, do nothing
98
+ if (!preservedSelection) {
99
+ return false;
100
+ }
101
+ const clickedDragHandle = event.target instanceof HTMLElement && event.target.closest(DRAG_HANDLE_SELECTOR);
102
+
103
+ // When clicking a drag handle we continue preserving the selection
104
+ if (!clickedDragHandle) {
105
+ return false;
106
+ }
107
+
108
+ // Otherwise clicking anywhere else in the editor stops preserving the selection
109
+ const tr = view.state.tr;
110
+ stopPreservingSelection({
111
+ tr
112
+ });
113
+ view.dispatch(tr);
114
+ return false;
115
+ },
89
116
  handleKeyDown: (view, event) => {
90
117
  var _api$userIntent, _api$userIntent$share;
91
118
  const {
@@ -93,19 +93,22 @@ export const mapPreservedSelection = (selection, tr) => {
93
93
  const to = mapping.map(selection.to);
94
94
  const isSelectionEmpty = from === to;
95
95
  const wasSelectionEmpty = selection.from === selection.to;
96
- if (isSelectionEmpty) {
97
- if (!wasSelectionEmpty) {
98
- // If selection has become empty i.e. content has been deleted, stop preserving
99
- return undefined;
100
- }
101
- // When preserving a cursor selection, just map the position without expanding
102
- return new TextSelection(tr.doc.resolve(from));
96
+ if (isSelectionEmpty && !wasSelectionEmpty) {
97
+ // If selection has become empty i.e. content has been deleted, stop preserving
98
+ return undefined;
103
99
  }
104
-
105
100
  // expand the text selection range to block boundaries, so as document changes occur the
106
101
  // selection always includes whole nodes
107
102
  const expanded = expandToBlockRange(tr.doc.resolve(from), tr.doc.resolve(to));
108
103
 
104
+ // If after expanding the selection it is still empty, return a single cursor selection at 'from'
105
+ const nodeAfter = expanded.$from.nodeAfter;
106
+ const nodeBefore = expanded.$to.nodeBefore;
107
+ const expandedSelectionEmpty = nodeAfter === nodeBefore && (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.content.size) === 0;
108
+ if (isSelectionEmpty && expandedSelectionEmpty) {
109
+ return TextSelection.create(tr.doc, from);
110
+ }
111
+
109
112
  // collapse the expanded range to a valid selection range
110
113
  const {
111
114
  $from,
@@ -3,6 +3,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
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
4
  import { logException } from '@atlaskit/editor-common/monitoring';
5
5
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
6
+ import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
6
7
  import { mapPreservedSelection } from '../utils/selection';
7
8
  import { stopPreservingSelection } from './editor-commands';
8
9
  import { selectionPreservationPluginKey } from './plugin-key';
@@ -35,6 +36,8 @@ import { getSelectionPreservationMeta, hasUserSelectionChange } from './utils';
35
36
  * is open (editor becomes non-interactive), during drag-and-drop operations (user is mid-drag), or
36
37
  * when modal dialogs are active. In these states, any selection changes are from ProseMirror's
37
38
  * internal behavior (not user input) and should be prevented. Do not use during normal editing.
39
+ *
40
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/6170822503/Block+Menu+Solution+for+multi-select+and+selection+preservation
38
41
  */
39
42
  export var createSelectionPreservationPlugin = function createSelectionPreservationPlugin(api) {
40
43
  return function () {
@@ -50,7 +53,7 @@ export var createSelectionPreservationPlugin = function createSelectionPreservat
50
53
  var meta = getSelectionPreservationMeta(tr);
51
54
  var newState = _objectSpread({}, pluginState);
52
55
  if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'startPreserving') {
53
- newState.preservedSelection = tr.selection;
56
+ newState.preservedSelection = mapPreservedSelection(tr.selection, tr);
54
57
  } else if ((meta === null || meta === void 0 ? void 0 : meta.type) === 'stopPreserving') {
55
58
  newState.preservedSelection = undefined;
56
59
  }
@@ -88,11 +91,34 @@ export var createSelectionPreservationPlugin = function createSelectionPreservat
88
91
  return null;
89
92
  },
90
93
  props: {
91
- handleKeyDown: function handleKeyDown(view, event) {
92
- var _api$userIntent;
94
+ handleClick: function handleClick(view, pos, event) {
93
95
  var _ref = selectionPreservationPluginKey.getState(view.state) || {},
94
96
  preservedSelection = _ref.preservedSelection;
95
97
 
98
+ // If there is no current preserved selection, do nothing
99
+ if (!preservedSelection) {
100
+ return false;
101
+ }
102
+ var clickedDragHandle = event.target instanceof HTMLElement && event.target.closest(DRAG_HANDLE_SELECTOR);
103
+
104
+ // When clicking a drag handle we continue preserving the selection
105
+ if (!clickedDragHandle) {
106
+ return false;
107
+ }
108
+
109
+ // Otherwise clicking anywhere else in the editor stops preserving the selection
110
+ var tr = view.state.tr;
111
+ stopPreservingSelection({
112
+ tr: tr
113
+ });
114
+ view.dispatch(tr);
115
+ return false;
116
+ },
117
+ handleKeyDown: function handleKeyDown(view, event) {
118
+ var _api$userIntent;
119
+ var _ref2 = selectionPreservationPluginKey.getState(view.state) || {},
120
+ preservedSelection = _ref2.preservedSelection;
121
+
96
122
  // If there is no current preserved selection, do nothing
97
123
  if (!preservedSelection) {
98
124
  return false;
@@ -91,19 +91,22 @@ export var mapPreservedSelection = function mapPreservedSelection(selection, tr)
91
91
  var to = mapping.map(selection.to);
92
92
  var isSelectionEmpty = from === to;
93
93
  var wasSelectionEmpty = selection.from === selection.to;
94
- if (isSelectionEmpty) {
95
- if (!wasSelectionEmpty) {
96
- // If selection has become empty i.e. content has been deleted, stop preserving
97
- return undefined;
98
- }
99
- // When preserving a cursor selection, just map the position without expanding
100
- return new TextSelection(tr.doc.resolve(from));
94
+ if (isSelectionEmpty && !wasSelectionEmpty) {
95
+ // If selection has become empty i.e. content has been deleted, stop preserving
96
+ return undefined;
101
97
  }
102
-
103
98
  // expand the text selection range to block boundaries, so as document changes occur the
104
99
  // selection always includes whole nodes
105
100
  var expanded = expandToBlockRange(tr.doc.resolve(from), tr.doc.resolve(to));
106
101
 
102
+ // If after expanding the selection it is still empty, return a single cursor selection at 'from'
103
+ var nodeAfter = expanded.$from.nodeAfter;
104
+ var nodeBefore = expanded.$to.nodeBefore;
105
+ var expandedSelectionEmpty = nodeAfter === nodeBefore && (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.content.size) === 0;
106
+ if (isSelectionEmpty && expandedSelectionEmpty) {
107
+ return TextSelection.create(tr.doc, from);
108
+ }
109
+
107
110
  // collapse the expanded range to a valid selection range
108
111
  var _collapseToSelectionR = collapseToSelectionRange(expanded.$from, expanded.$to),
109
112
  $from = _collapseToSelectionR.$from,
@@ -29,5 +29,7 @@ import type { SelectionPreservationPluginState } from './types';
29
29
  * is open (editor becomes non-interactive), during drag-and-drop operations (user is mid-drag), or
30
30
  * when modal dialogs are active. In these states, any selection changes are from ProseMirror's
31
31
  * internal behavior (not user input) and should be prevented. Do not use during normal editing.
32
+ *
33
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/6170822503/Block+Menu+Solution+for+multi-select+and+selection+preservation
32
34
  */
33
35
  export declare const createSelectionPreservationPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => () => SafePlugin<SelectionPreservationPluginState>;
@@ -29,5 +29,7 @@ import type { SelectionPreservationPluginState } from './types';
29
29
  * is open (editor becomes non-interactive), during drag-and-drop operations (user is mid-drag), or
30
30
  * when modal dialogs are active. In these states, any selection changes are from ProseMirror's
31
31
  * internal behavior (not user input) and should be prevented. Do not use during normal editing.
32
+ *
33
+ * https://hello.atlassian.net/wiki/spaces/egcuc/pages/6170822503/Block+Menu+Solution+for+multi-select+and+selection+preservation
32
34
  */
33
35
  export declare const createSelectionPreservationPlugin: (api: ExtractInjectionAPI<BlockControlsPlugin> | undefined) => () => SafePlugin<SelectionPreservationPluginState>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "7.18.0",
3
+ "version": "7.18.1",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",