@atlaskit/editor-plugin-paste-options-toolbar 9.1.3 → 9.1.4

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,15 @@
1
1
  # @atlaskit/editor-plugin-paste-options-toolbar
2
2
 
3
+ ## 9.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`cdacbdec78ed6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cdacbdec78ed6) -
8
+ [EDITOR-5980] Fix sticky menu stopping before table when paste selection ends inside cell
9
+ - [`70e3625a8ae3f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/70e3625a8ae3f) -
10
+ [EDITOR-5880] updated prop name for consistency and used view.dom for stable editor reference
11
+ - Updated dependencies
12
+
3
13
  ## 9.1.3
4
14
 
5
15
  ### Patch Changes
@@ -6,7 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.PasteActionsMenu = void 0;
9
+ exports.getVisualEndBottom = getVisualEndBottom;
9
10
  exports.onPositionCalculated = onPositionCalculated;
11
+ exports.resolveTableAfterPos = resolveTableAfterPos;
10
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
13
  var _react = _interopRequireWildcard(require("react"));
12
14
  var _analytics = require("@atlaskit/editor-common/analytics");
@@ -39,6 +41,34 @@ function getTargetElement(editorView, pos) {
39
41
  }
40
42
  }
41
43
 
44
+ /**
45
+ * Returns the position immediately after a table ancestor of `pos`, or
46
+ * `undefined` if not inside a table. Safe to cache per document version.
47
+ */
48
+ function resolveTableAfterPos(editorView, pos) {
49
+ var $pos = editorView.state.doc.resolve(pos);
50
+ for (var depth = $pos.depth; depth > 0; depth--) {
51
+ if ($pos.node(depth).type.name === 'table') {
52
+ return $pos.after(depth);
53
+ }
54
+ }
55
+ return undefined;
56
+ }
57
+
58
+ /**
59
+ * Returns the visual bottom of the pasted content. For positions inside a
60
+ * table, uses the pre-computed `tableAfterPos` to get the correct bottom edge.
61
+ */
62
+ function getVisualEndBottom(editorView, pasteEndPos, tableAfterPos) {
63
+ var endCoords = editorView.coordsAtPos(pasteEndPos);
64
+ var bottom = endCoords.bottom;
65
+ if (tableAfterPos !== undefined) {
66
+ var afterCoords = editorView.coordsAtPos(tableAfterPos);
67
+ bottom = Math.max(bottom, afterCoords.bottom);
68
+ }
69
+ return bottom;
70
+ }
71
+
42
72
  /**
43
73
  * Adjusts the vertical position of the paste menu to align with the top of the
44
74
  * pasted content using the exact coordinates at the paste start position,
@@ -56,10 +86,12 @@ function getTargetElement(editorView, pos) {
56
86
  * above the visible area.
57
87
  */
58
88
  function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElement, scrollableElement) {
89
+ // Pre-compute once per render to avoid doc.resolve() on every scroll frame.
90
+ var tableAfterPos = resolveTableAfterPos(editorView, pasteEndPos);
59
91
  return function (position) {
60
92
  var _position$top;
61
93
  var startCoords = editorView.coordsAtPos(pasteStartPos);
62
- var endCoords = editorView.coordsAtPos(pasteEndPos);
94
+ var endBottom = getVisualEndBottom(editorView, pasteEndPos, tableAfterPos);
63
95
  var targetRect = targetElement.getBoundingClientRect();
64
96
 
65
97
  // The Popup places the menu at the target's bottom edge by default.
@@ -73,7 +105,7 @@ function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElem
73
105
  // content is still visible.
74
106
  if (scrollableElement) {
75
107
  var scrollContainerTop = scrollableElement.getBoundingClientRect().top;
76
- if (startCoords.top < scrollContainerTop && endCoords.bottom > scrollContainerTop) {
108
+ if (startCoords.top < scrollContainerTop && endBottom > scrollContainerTop) {
77
109
  adjustedTop += scrollContainerTop - startCoords.top + _constants.PASTE_MENU_GAP_TOP;
78
110
  }
79
111
  }
@@ -177,8 +209,7 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
177
209
  // so the Popup attaches its built-in scroll listener, which calls
178
210
  // scheduledUpdatePosition (RAF-throttled) on each scroll event — triggering
179
211
  // onPositionCalculated with fresh viewport coordinates.
180
- var targetForScroll = isToolbarShown ? getTargetElement(editorView, pasteStartPos) : null;
181
- var overflowScrollParent = targetForScroll ? (0, _ui.findOverflowScrollParent)(targetForScroll) : false;
212
+ var overflowScrollParent = isToolbarShown ? (0, _ui.findOverflowScrollParent)(editorView.dom) : false;
182
213
  var effectiveScrollableElement = overflowScrollParent || scrollableElement;
183
214
  var pasteMenuComponents = (_api$uiControlRegistr3 = api === null || api === void 0 || (_api$uiControlRegistr4 = api.uiControlRegistry) === null || _api$uiControlRegistr4 === void 0 ? void 0 : _api$uiControlRegistr4.actions.getComponents(_toolbar.PASTE_MENU.key)) !== null && _api$uiControlRegistr3 !== void 0 ? _api$uiControlRegistr3 : [];
184
215
  var anyComponentVisible = (0, _hasVisibleButton.hasVisibleButton)(pasteMenuComponents);
@@ -26,6 +26,34 @@ function getTargetElement(editorView, pos) {
26
26
  }
27
27
  }
28
28
 
29
+ /**
30
+ * Returns the position immediately after a table ancestor of `pos`, or
31
+ * `undefined` if not inside a table. Safe to cache per document version.
32
+ */
33
+ export function resolveTableAfterPos(editorView, pos) {
34
+ const $pos = editorView.state.doc.resolve(pos);
35
+ for (let depth = $pos.depth; depth > 0; depth--) {
36
+ if ($pos.node(depth).type.name === 'table') {
37
+ return $pos.after(depth);
38
+ }
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ /**
44
+ * Returns the visual bottom of the pasted content. For positions inside a
45
+ * table, uses the pre-computed `tableAfterPos` to get the correct bottom edge.
46
+ */
47
+ export function getVisualEndBottom(editorView, pasteEndPos, tableAfterPos) {
48
+ const endCoords = editorView.coordsAtPos(pasteEndPos);
49
+ let bottom = endCoords.bottom;
50
+ if (tableAfterPos !== undefined) {
51
+ const afterCoords = editorView.coordsAtPos(tableAfterPos);
52
+ bottom = Math.max(bottom, afterCoords.bottom);
53
+ }
54
+ return bottom;
55
+ }
56
+
29
57
  /**
30
58
  * Adjusts the vertical position of the paste menu to align with the top of the
31
59
  * pasted content using the exact coordinates at the paste start position,
@@ -43,10 +71,12 @@ function getTargetElement(editorView, pos) {
43
71
  * above the visible area.
44
72
  */
45
73
  export function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElement, scrollableElement) {
74
+ // Pre-compute once per render to avoid doc.resolve() on every scroll frame.
75
+ const tableAfterPos = resolveTableAfterPos(editorView, pasteEndPos);
46
76
  return position => {
47
77
  var _position$top;
48
78
  const startCoords = editorView.coordsAtPos(pasteStartPos);
49
- const endCoords = editorView.coordsAtPos(pasteEndPos);
79
+ const endBottom = getVisualEndBottom(editorView, pasteEndPos, tableAfterPos);
50
80
  const targetRect = targetElement.getBoundingClientRect();
51
81
 
52
82
  // The Popup places the menu at the target's bottom edge by default.
@@ -60,7 +90,7 @@ export function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, tar
60
90
  // content is still visible.
61
91
  if (scrollableElement) {
62
92
  const scrollContainerTop = scrollableElement.getBoundingClientRect().top;
63
- if (startCoords.top < scrollContainerTop && endCoords.bottom > scrollContainerTop) {
93
+ if (startCoords.top < scrollContainerTop && endBottom > scrollContainerTop) {
64
94
  adjustedTop += scrollContainerTop - startCoords.top + PASTE_MENU_GAP_TOP;
65
95
  }
66
96
  }
@@ -168,8 +198,7 @@ export const PasteActionsMenu = ({
168
198
  // so the Popup attaches its built-in scroll listener, which calls
169
199
  // scheduledUpdatePosition (RAF-throttled) on each scroll event — triggering
170
200
  // onPositionCalculated with fresh viewport coordinates.
171
- const targetForScroll = isToolbarShown ? getTargetElement(editorView, pasteStartPos) : null;
172
- const overflowScrollParent = targetForScroll ? findOverflowScrollParent(targetForScroll) : false;
201
+ const overflowScrollParent = isToolbarShown ? findOverflowScrollParent(editorView.dom) : false;
173
202
  const effectiveScrollableElement = overflowScrollParent || scrollableElement;
174
203
  const pasteMenuComponents = (_api$uiControlRegistr3 = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr4 = api.uiControlRegistry) === null || _api$uiControlRegistr4 === void 0 ? void 0 : _api$uiControlRegistr4.actions.getComponents(PASTE_MENU.key)) !== null && _api$uiControlRegistr3 !== void 0 ? _api$uiControlRegistr3 : [];
175
204
  const anyComponentVisible = hasVisibleButton(pasteMenuComponents);
@@ -29,6 +29,34 @@ function getTargetElement(editorView, pos) {
29
29
  }
30
30
  }
31
31
 
32
+ /**
33
+ * Returns the position immediately after a table ancestor of `pos`, or
34
+ * `undefined` if not inside a table. Safe to cache per document version.
35
+ */
36
+ export function resolveTableAfterPos(editorView, pos) {
37
+ var $pos = editorView.state.doc.resolve(pos);
38
+ for (var depth = $pos.depth; depth > 0; depth--) {
39
+ if ($pos.node(depth).type.name === 'table') {
40
+ return $pos.after(depth);
41
+ }
42
+ }
43
+ return undefined;
44
+ }
45
+
46
+ /**
47
+ * Returns the visual bottom of the pasted content. For positions inside a
48
+ * table, uses the pre-computed `tableAfterPos` to get the correct bottom edge.
49
+ */
50
+ export function getVisualEndBottom(editorView, pasteEndPos, tableAfterPos) {
51
+ var endCoords = editorView.coordsAtPos(pasteEndPos);
52
+ var bottom = endCoords.bottom;
53
+ if (tableAfterPos !== undefined) {
54
+ var afterCoords = editorView.coordsAtPos(tableAfterPos);
55
+ bottom = Math.max(bottom, afterCoords.bottom);
56
+ }
57
+ return bottom;
58
+ }
59
+
32
60
  /**
33
61
  * Adjusts the vertical position of the paste menu to align with the top of the
34
62
  * pasted content using the exact coordinates at the paste start position,
@@ -46,10 +74,12 @@ function getTargetElement(editorView, pos) {
46
74
  * above the visible area.
47
75
  */
48
76
  export function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, targetElement, scrollableElement) {
77
+ // Pre-compute once per render to avoid doc.resolve() on every scroll frame.
78
+ var tableAfterPos = resolveTableAfterPos(editorView, pasteEndPos);
49
79
  return function (position) {
50
80
  var _position$top;
51
81
  var startCoords = editorView.coordsAtPos(pasteStartPos);
52
- var endCoords = editorView.coordsAtPos(pasteEndPos);
82
+ var endBottom = getVisualEndBottom(editorView, pasteEndPos, tableAfterPos);
53
83
  var targetRect = targetElement.getBoundingClientRect();
54
84
 
55
85
  // The Popup places the menu at the target's bottom edge by default.
@@ -63,7 +93,7 @@ export function onPositionCalculated(editorView, pasteStartPos, pasteEndPos, tar
63
93
  // content is still visible.
64
94
  if (scrollableElement) {
65
95
  var scrollContainerTop = scrollableElement.getBoundingClientRect().top;
66
- if (startCoords.top < scrollContainerTop && endCoords.bottom > scrollContainerTop) {
96
+ if (startCoords.top < scrollContainerTop && endBottom > scrollContainerTop) {
67
97
  adjustedTop += scrollContainerTop - startCoords.top + PASTE_MENU_GAP_TOP;
68
98
  }
69
99
  }
@@ -167,8 +197,7 @@ export var PasteActionsMenu = function PasteActionsMenu(_ref) {
167
197
  // so the Popup attaches its built-in scroll listener, which calls
168
198
  // scheduledUpdatePosition (RAF-throttled) on each scroll event — triggering
169
199
  // onPositionCalculated with fresh viewport coordinates.
170
- var targetForScroll = isToolbarShown ? getTargetElement(editorView, pasteStartPos) : null;
171
- var overflowScrollParent = targetForScroll ? findOverflowScrollParent(targetForScroll) : false;
200
+ var overflowScrollParent = isToolbarShown ? findOverflowScrollParent(editorView.dom) : false;
172
201
  var effectiveScrollableElement = overflowScrollParent || scrollableElement;
173
202
  var pasteMenuComponents = (_api$uiControlRegistr3 = api === null || api === void 0 || (_api$uiControlRegistr4 = api.uiControlRegistry) === null || _api$uiControlRegistr4 === void 0 ? void 0 : _api$uiControlRegistr4.actions.getComponents(PASTE_MENU.key)) !== null && _api$uiControlRegistr3 !== void 0 ? _api$uiControlRegistr3 : [];
174
203
  var anyComponentVisible = hasVisibleButton(pasteMenuComponents);
@@ -9,6 +9,16 @@ interface PasteActionsMenuProps {
9
9
  mountTo?: HTMLElement;
10
10
  scrollableElement?: HTMLElement;
11
11
  }
12
+ /**
13
+ * Returns the position immediately after a table ancestor of `pos`, or
14
+ * `undefined` if not inside a table. Safe to cache per document version.
15
+ */
16
+ export declare function resolveTableAfterPos(editorView: EditorView, pos: number): number | undefined;
17
+ /**
18
+ * Returns the visual bottom of the pasted content. For positions inside a
19
+ * table, uses the pre-computed `tableAfterPos` to get the correct bottom edge.
20
+ */
21
+ export declare function getVisualEndBottom(editorView: EditorView, pasteEndPos: number, tableAfterPos?: number): number;
12
22
  /**
13
23
  * Adjusts the vertical position of the paste menu to align with the top of the
14
24
  * pasted content using the exact coordinates at the paste start position,
@@ -9,6 +9,16 @@ interface PasteActionsMenuProps {
9
9
  mountTo?: HTMLElement;
10
10
  scrollableElement?: HTMLElement;
11
11
  }
12
+ /**
13
+ * Returns the position immediately after a table ancestor of `pos`, or
14
+ * `undefined` if not inside a table. Safe to cache per document version.
15
+ */
16
+ export declare function resolveTableAfterPos(editorView: EditorView, pos: number): number | undefined;
17
+ /**
18
+ * Returns the visual bottom of the pasted content. For positions inside a
19
+ * table, uses the pre-computed `tableAfterPos` to get the correct bottom edge.
20
+ */
21
+ export declare function getVisualEndBottom(editorView: EditorView, pasteEndPos: number, tableAfterPos?: number): number;
12
22
  /**
13
23
  * Adjusts the vertical position of the paste menu to align with the top of the
14
24
  * pasted content using the exact coordinates at the paste start position,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-paste-options-toolbar",
3
- "version": "9.1.3",
3
+ "version": "9.1.4",
4
4
  "description": "Paste options toolbar for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",