@atlaskit/editor-common 111.7.2 → 111.7.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/afm-cc/tsconfig.json +1 -1
  3. package/dist/cjs/element-browser/ElementBrowser.js +0 -2
  4. package/dist/cjs/element-browser/components/StatelessElementBrowser.js +2 -10
  5. package/dist/cjs/messages/placeholder-text.js +4 -4
  6. package/dist/cjs/messages/text-color.js +1 -1
  7. package/dist/cjs/monitoring/error.js +1 -1
  8. package/dist/cjs/ui/DropList/index.js +1 -1
  9. package/dist/cjs/utils/calculate-toolbar-position.js +147 -14
  10. package/dist/es2019/element-browser/ElementBrowser.js +0 -2
  11. package/dist/es2019/element-browser/components/StatelessElementBrowser.js +3 -11
  12. package/dist/es2019/messages/placeholder-text.js +4 -4
  13. package/dist/es2019/messages/text-color.js +1 -1
  14. package/dist/es2019/monitoring/error.js +1 -1
  15. package/dist/es2019/ui/DropList/index.js +1 -1
  16. package/dist/es2019/utils/calculate-toolbar-position.js +149 -13
  17. package/dist/esm/element-browser/ElementBrowser.js +0 -2
  18. package/dist/esm/element-browser/components/StatelessElementBrowser.js +3 -11
  19. package/dist/esm/messages/placeholder-text.js +4 -4
  20. package/dist/esm/messages/text-color.js +1 -1
  21. package/dist/esm/monitoring/error.js +1 -1
  22. package/dist/esm/ui/DropList/index.js +1 -1
  23. package/dist/esm/utils/calculate-toolbar-position.js +146 -13
  24. package/dist/types/element-browser/ElementBrowser.d.ts +0 -7
  25. package/dist/types/element-browser/components/StatelessElementBrowser.d.ts +0 -14
  26. package/dist/types/messages/placeholder-text.d.ts +1 -1
  27. package/dist/types/utils/calculate-toolbar-position.d.ts +7 -0
  28. package/dist/types-ts4.5/element-browser/ElementBrowser.d.ts +0 -7
  29. package/dist/types-ts4.5/element-browser/components/StatelessElementBrowser.d.ts +0 -14
  30. package/dist/types-ts4.5/messages/placeholder-text.d.ts +1 -1
  31. package/dist/types-ts4.5/utils/calculate-toolbar-position.d.ts +7 -0
  32. package/package.json +6 -9
  33. package/dist/cjs/element-browser/ViewMore.js +0 -58
  34. package/dist/es2019/element-browser/ViewMore.js +0 -52
  35. package/dist/esm/element-browser/ViewMore.js +0 -51
  36. package/dist/types/element-browser/ViewMore.d.ts +0 -6
  37. package/dist/types-ts4.5/element-browser/ViewMore.d.ts +0 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 111.7.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`db121516e200b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/db121516e200b) -
8
+ [ux] Update hub extention titles and radius slider style
9
+ - [`ba05557f777bf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ba05557f777bf) -
10
+ Add support to render selection toolbar in editors which have an ancestor elemenent which has
11
+ position fixed, most common use case is for the chromeless appearance when rendered inside modals,
12
+ popups etc.
13
+ - Updated dependencies
14
+
15
+ ## 111.7.3
16
+
17
+ ### Patch Changes
18
+
19
+ - [`38c83ce57623b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/38c83ce57623b) -
20
+ [ux] [EDITOR-3853] Update copy for sync block placeholder and copy flag
21
+ - [`11bd6ea9cb0ba`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/11bd6ea9cb0ba) -
22
+ [ux] Clean up platform_editor_refactor_view_more
23
+ - Updated dependencies
24
+
3
25
  ## 111.7.2
4
26
 
5
27
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../../../tsconfig.entry-points.confluence.json",
2
+ "extends": "../../../../tsconfig.local-consumption.json",
3
3
  "compilerOptions": {
4
4
  "declaration": true,
5
5
  "target": "es5",
@@ -119,7 +119,6 @@ var ElementBrowser = exports.default = /*#__PURE__*/function (_PureComponent) {
119
119
  showCategories = _this$props.showCategories,
120
120
  mode = _this$props.mode,
121
121
  emptyStateHandler = _this$props.emptyStateHandler,
122
- viewMoreItem = _this$props.viewMoreItem,
123
122
  onViewMore = _this$props.onViewMore,
124
123
  cache = _this$props.cache,
125
124
  autoFocusSearch = _this$props.autoFocusSearch;
@@ -141,7 +140,6 @@ var ElementBrowser = exports.default = /*#__PURE__*/function (_PureComponent) {
141
140
  mode: mode,
142
141
  searchTerm: searchTerm,
143
142
  emptyStateHandler: emptyStateHandler,
144
- viewMoreItem: viewMoreItem,
145
143
  cache: cache,
146
144
  onViewMore: onViewMore,
147
145
  autoFocusSearch: autoFocusSearch
@@ -13,7 +13,6 @@ var _react2 = require("@emotion/react");
13
13
  var _reactIntlNext = require("react-intl-next");
14
14
  var _withAnalyticsContext = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsContext"));
15
15
  var _withAnalyticsEvents = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsEvents"));
16
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
16
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
18
17
  var _analytics = require("../../analytics");
19
18
  var _getEditorUgcToken = _interopRequireDefault(require("../../ugc-tokens/get-editor-ugc-token"));
@@ -21,7 +20,6 @@ var _ViewMore = require("../components/ViewMore");
21
20
  var _constants = require("../constants");
22
21
  var _useContainerWidth2 = _interopRequireDefault(require("../hooks/use-container-width"));
23
22
  var _useSelectAndFocusOnArrowNavigation = _interopRequireDefault(require("../hooks/use-select-and-focus-on-arrow-navigation"));
24
- var _ViewMore2 = require("../ViewMore");
25
23
  var _CategoryList = _interopRequireDefault(require("./CategoryList"));
26
24
  var _ElementList = _interopRequireDefault(require("./ElementList/ElementList"));
27
25
  var _ElementSearch = _interopRequireDefault(require("./ElementSearch"));
@@ -130,7 +128,6 @@ function StatelessElementBrowser(props) {
130
128
  var items = props.items,
131
129
  onSelectItem = props.onSelectItem,
132
130
  onInsertItem = props.onInsertItem,
133
- viewMoreItem = props.viewMoreItem,
134
131
  onViewMore = props.onViewMore,
135
132
  selectedCategory = props.selectedCategory,
136
133
  onSelectCategory = props.onSelectCategory,
@@ -170,7 +167,7 @@ function StatelessElementBrowser(props) {
170
167
  var _items$index$isDisabl, _items$index;
171
168
  return (_items$index$isDisabl = (_items$index = items[index]) === null || _items$index === void 0 ? void 0 : _items$index.isDisabled) !== null && _items$index$isDisabl !== void 0 ? _items$index$isDisabl : false;
172
169
  }, [items]);
173
- var _useSelectAndFocusOnA = (0, _useSelectAndFocusOnArrowNavigation.default)(items.length - 1, columnCount, (0, _platformFeatureFlags.fg)('platform_editor_refactor_view_more') ? !!onViewMore : !!viewMoreItem, itemIsDisabled, isFocusSearch, autoFocusSearch),
170
+ var _useSelectAndFocusOnA = (0, _useSelectAndFocusOnArrowNavigation.default)(items.length - 1, columnCount, !!onViewMore, itemIsDisabled, isFocusSearch, autoFocusSearch),
174
171
  selectedItemIndex = _useSelectAndFocusOnA.selectedItemIndex,
175
172
  focusedItemIndex = _useSelectAndFocusOnA.focusedItemIndex,
176
173
  setFocusedItemIndex = _useSelectAndFocusOnA.setFocusedItemIndex,
@@ -272,7 +269,6 @@ function StatelessElementBrowser(props) {
272
269
  setFocusOnSearch: setFocusOnSearch,
273
270
  onKeyPress: onItemsEnterTabKeyPress,
274
271
  onKeyDown: onKeyDown,
275
- viewMoreItem: viewMoreItem,
276
272
  onViewMore: onViewMore,
277
273
  focusOnViewMore: focusOnViewMore,
278
274
  cache: cache
@@ -323,7 +319,6 @@ function MobileBrowser(_ref) {
323
319
  searchTerm = _ref.searchTerm,
324
320
  createAnalyticsEvent = _ref.createAnalyticsEvent,
325
321
  emptyStateHandler = _ref.emptyStateHandler,
326
- viewMoreItem = _ref.viewMoreItem,
327
322
  onViewMore = _ref.onViewMore,
328
323
  cache = _ref.cache,
329
324
  _ref$focusOnEmptyStat = _ref.focusOnEmptyStateButton,
@@ -375,12 +370,9 @@ function MobileBrowser(_ref) {
375
370
  selectedCategory: selectedCategory,
376
371
  searchTerm: searchTerm,
377
372
  cache: cache
378
- })), onViewMore && (0, _platformFeatureFlags.fg)('platform_editor_refactor_view_more') && (0, _react2.jsx)(_ViewMore.ViewMore, {
373
+ })), onViewMore && (0, _react2.jsx)(_ViewMore.ViewMore, {
379
374
  onViewMore: onViewMore,
380
375
  focus: focusOnViewMore
381
- }), viewMoreItem && !(0, _platformFeatureFlags.fg)('platform_editor_refactor_view_more') && (0, _react2.jsx)(_ViewMore2.ViewMore, {
382
- item: viewMoreItem,
383
- focus: focusOnViewMore
384
376
  }))
385
377
  );
386
378
  }
@@ -46,9 +46,9 @@ var placeholderTextMessages = exports.placeholderTextMessages = (0, _reactIntlNe
46
46
  defaultMessage: ' to insert elements',
47
47
  description: 'Text after slash in long empty node placeholder'
48
48
  },
49
- syncBlockPlaceholderText: {
50
- id: 'fabric.editor.syncBlockPlaceholderText',
51
- defaultMessage: 'Add content then copy this synced block to access it across spaces',
52
- description: 'Placeholder text for sync block'
49
+ sourceSyncBlockPlaceholderText: {
50
+ id: 'fabric.editor.sourceSyncBlockPlaceholderText',
51
+ defaultMessage: 'Add content you want to reuse. Copy and paste this block to sync in other locations.',
52
+ description: 'Placeholder text for source sync block'
53
53
  }
54
54
  });
@@ -18,7 +18,7 @@ var textColorMessages = exports.textColorMessages = (0, _reactIntlNext.defineMes
18
18
  },
19
19
  textColorHighlightTooltip: {
20
20
  id: 'fabric.editor.textColorHighlightTooltip',
21
- defaultMessage: 'Text and Highlight color',
21
+ defaultMessage: 'Text and highlight color',
22
22
  description: 'Tooltip of menu that provides access to various colors of highlight.'
23
23
  }
24
24
  });
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
19
19
  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
20
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
21
21
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
22
- var packageVersion = "111.7.1";
22
+ var packageVersion = "111.7.3";
23
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
24
24
  // Remove URL as it has UGC
25
25
  // Ignored via go/ees007
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
24
24
  * @jsx jsx
25
25
  */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
26
26
  var packageName = "@atlaskit/editor-common";
27
- var packageVersion = "111.7.1";
27
+ var packageVersion = "111.7.3";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -3,10 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.calculateToolbarPositionTrackHead = exports.calculateToolbarPositionOnCellSelection = exports.calculateToolbarPositionAboveSelection = void 0;
6
+ exports.calculateToolbarPositionTrackHeadOld = exports.calculateToolbarPositionTrackHeadNew = exports.calculateToolbarPositionTrackHead = exports.calculateToolbarPositionOnCellSelection = exports.calculateToolbarPositionAboveSelection = void 0;
7
7
  var _utils = require("@atlaskit/editor-prosemirror/utils");
8
8
  var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
9
9
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
10
11
  var MAXIMUM_BROWSER_SCROLLBAR_WIDTH = 20;
11
12
 
12
13
  /*
@@ -85,19 +86,36 @@ var calculateToolbarPositionAboveSelection = exports.calculateToolbarPositionAbo
85
86
  };
86
87
  };
87
88
  };
88
- /*
89
- Calculates the position of the floating toolbar relative to the selection.
90
- This is a re-implementation which closely matches the behaviour on Confluence renderer.
91
- The main difference is the popup is always above the selection.
92
- Things to consider:
93
- - stick as close to the head X release coordinates as possible
94
- - coordinates of head X and getBoundingClientRect() are absolute in client viewport (not including scroll offsets)
95
- - popup may appear in '.fabric-editor-popup-scroll-parent' (or body)
96
- - we use the toolbarRect to center align toolbar
97
- - use wrapperBounds to clamp values
98
- - editorView.dom bounds differ to wrapperBounds, convert at the end
99
- */
100
- var calculateToolbarPositionTrackHead = exports.calculateToolbarPositionTrackHead = function calculateToolbarPositionTrackHead(toolbarTitle) {
89
+ var findContainingElement = function findContainingElement(editorView) {
90
+ // First, try to find .fabric-editor-popup-scroll-parent
91
+ var scrollParent = editorView.dom.closest('.fabric-editor-popup-scroll-parent');
92
+ if (scrollParent) {
93
+ return {
94
+ container: scrollParent,
95
+ isFixed: false
96
+ };
97
+ } else {
98
+ // If no scroll parent, look for a fixed positioned parent
99
+ var fixedParent = editorView.dom.parentElement;
100
+ while (fixedParent && fixedParent !== document.body) {
101
+ var computedStyle = window.getComputedStyle(fixedParent);
102
+ if (computedStyle.position === 'fixed') {
103
+ return {
104
+ container: fixedParent,
105
+ isFixed: true
106
+ };
107
+ }
108
+ fixedParent = fixedParent.parentElement;
109
+ }
110
+ }
111
+
112
+ // Fall back to document.body if no fixed parent found
113
+ return {
114
+ container: document.body,
115
+ isFixed: false
116
+ };
117
+ };
118
+ var calculateToolbarPositionTrackHeadOld = exports.calculateToolbarPositionTrackHeadOld = function calculateToolbarPositionTrackHeadOld(toolbarTitle) {
101
119
  return function (editorView, nextPos) {
102
120
  var toolbar = document.querySelector("div[aria-label=\"".concat(toolbarTitle, "\"]"));
103
121
  if (!toolbar) {
@@ -167,6 +185,121 @@ var calculateToolbarPositionTrackHead = exports.calculateToolbarPositionTrackHea
167
185
  };
168
186
  };
169
187
 
188
+ /**
189
+ * Same logic as calculateToolbarPositionTrackHeadOld, but with the following changes:
190
+ * - Uses a cached container to avoid repeated DOM traversal and getComputedStyle calls
191
+ * - Works when editor is nested within a fixed positioned parent, such as within a modal or sidebar
192
+ */
193
+ var calculateToolbarPositionTrackHeadNew = exports.calculateToolbarPositionTrackHeadNew = function calculateToolbarPositionTrackHeadNew(toolbarTitle) {
194
+ // Cache the container to avoid repeated DOM traversal and getComputedStyle calls
195
+ var cachedContainer = null;
196
+ var isFixedContainer = false;
197
+ var cachedEditorDom = null;
198
+ return function (editorView, nextPos) {
199
+ var toolbar = document.querySelector("div[aria-label=\"".concat(toolbarTitle, "\"]"));
200
+ if (!toolbar) {
201
+ return nextPos;
202
+ }
203
+
204
+ // Find and cache the container (only recalculates if editor DOM changed)
205
+ if (cachedEditorDom !== editorView.dom) {
206
+ cachedEditorDom = editorView.dom;
207
+ var _findContainingElemen = findContainingElement(editorView),
208
+ _container = _findContainingElemen.container,
209
+ isFixed = _findContainingElemen.isFixed;
210
+ cachedContainer = _container;
211
+ isFixedContainer = isFixed;
212
+ }
213
+ if (!cachedContainer) {
214
+ return nextPos;
215
+ }
216
+ var container = cachedContainer;
217
+ var containerBounds = container.getBoundingClientRect();
218
+ var selection = window && window.getSelection();
219
+ var moreRovoOptionsButton = document.querySelector('button[aria-label="More Rovo options"], [aria-label="More Rovo options"]');
220
+ var isMoreRovoOptionsButtonVisible = !!moreRovoOptionsButton && moreRovoOptionsButton instanceof HTMLElement && !!moreRovoOptionsButton.offsetParent;
221
+ var range = null;
222
+ if (isMoreRovoOptionsButtonVisible && (0, _platformFeatureFlags.fg)('platform_editor_ai_generic_prep_for_aifc')) {
223
+ if (selection && selection.getRangeAt && selection.rangeCount > 0) {
224
+ var maybeRange = selection.getRangeAt(0);
225
+ if (maybeRange instanceof Range) {
226
+ range = maybeRange;
227
+ }
228
+ }
229
+ } else {
230
+ if (selection && !selection.isCollapsed && selection.getRangeAt && selection.rangeCount > 0) {
231
+ var _maybeRange2 = selection.getRangeAt(0);
232
+ if (_maybeRange2 instanceof Range) {
233
+ range = _maybeRange2;
234
+ }
235
+ }
236
+ }
237
+ if (!range) {
238
+ return nextPos;
239
+ }
240
+ var toolbarRect = toolbar.getBoundingClientRect();
241
+ var _editorView$state$sel3 = editorView.state.selection,
242
+ head = _editorView$state$sel3.head,
243
+ anchor = _editorView$state$sel3.anchor;
244
+ var topCoords = editorView.coordsAtPos(Math.min(head, anchor));
245
+ var bottomCoords = editorView.coordsAtPos(Math.max(head, anchor) - Math.min(range.endOffset, 1));
246
+ var top;
247
+ // If not the same line AND we are selecting downwards, display toolbar below.
248
+ if (head > anchor && topCoords.top !== bottomCoords.top) {
249
+ // We are taking the previous pos to the maxium, so avoid end of line positions
250
+ // returning the next line's rect.
251
+ top = (bottomCoords.top || 0) + toolbarRect.height / 1.15;
252
+ } else {
253
+ top = (topCoords.top || 0) - toolbarRect.height * 1.5;
254
+ }
255
+ var left = (head > anchor ? bottomCoords.right : topCoords.left) - toolbarRect.width / 2;
256
+
257
+ // Place toolbar below selection if not sufficient space above
258
+ if (top < containerBounds.top) {
259
+ var _getCoordsBelowSelect3 = getCoordsBelowSelection(bottomCoords, toolbarRect);
260
+ top = _getCoordsBelowSelect3.top;
261
+ left = _getCoordsBelowSelect3.left;
262
+ }
263
+ var leftCoord = Math.max(0, left - containerBounds.left);
264
+ if (leftCoord + toolbarRect.width > containerBounds.width) {
265
+ var _scrollbarWidth2 = MAXIMUM_BROWSER_SCROLLBAR_WIDTH;
266
+ leftCoord = Math.max(0, containerBounds.width - (toolbarRect.width + _scrollbarWidth2));
267
+ }
268
+
269
+ // Apply scroll offset only for non-fixed containers
270
+ // Fixed positioned elements don't scroll with the page
271
+ var scrollOffset = isFixedContainer ? 0 : container.scrollTop;
272
+ return {
273
+ top: top - containerBounds.top + scrollOffset,
274
+ left: leftCoord
275
+ };
276
+ };
277
+ };
278
+
279
+ /*
280
+ Calculates the position of the floating toolbar relative to the selection.
281
+ This implementation works in multiple scenarios:
282
+ - Standard scrollable containers with .fabric-editor-popup-scroll-parent
283
+ - Fixed positioned parent containers
284
+ - Falls back to document.body
285
+
286
+ The function automatically detects the container type and applies the appropriate
287
+ positioning logic and scroll offset handling.
288
+
289
+ Things to consider:
290
+ - stick as close to the head X release coordinates as possible
291
+ - coordinates of head X and getBoundingClientRect() are absolute in client viewport
292
+ - popup may appear in '.fabric-editor-popup-scroll-parent', fixed parent, or body
293
+ - we use the toolbarRect to center align toolbar
294
+ - use container bounds to clamp values
295
+ - for fixed positioning, no scroll offsets are applied
296
+ - for scrollable containers, scroll offsets are included
297
+ */
298
+ var calculateToolbarPositionTrackHead = exports.calculateToolbarPositionTrackHead = function calculateToolbarPositionTrackHead(toolbarTitle) {
299
+ var isSelToolbarFixEnabled = (0, _expValEquals.expValEquals)('platform_editor_sel_toolbar_fix', 'isEnabled', true);
300
+ return isSelToolbarFixEnabled ? calculateToolbarPositionTrackHeadNew(toolbarTitle) : calculateToolbarPositionTrackHeadOld(toolbarTitle);
301
+ };
302
+
170
303
  /**
171
304
  * Returns the coordintes at the bottom the selection.
172
305
  */
@@ -88,7 +88,6 @@ export default class ElementBrowser extends PureComponent {
88
88
  showCategories,
89
89
  mode,
90
90
  emptyStateHandler,
91
- viewMoreItem,
92
91
  onViewMore,
93
92
  cache,
94
93
  autoFocusSearch
@@ -112,7 +111,6 @@ export default class ElementBrowser extends PureComponent {
112
111
  mode: mode,
113
112
  searchTerm: searchTerm,
114
113
  emptyStateHandler: emptyStateHandler,
115
- viewMoreItem: viewMoreItem,
116
114
  cache: cache,
117
115
  onViewMore: onViewMore,
118
116
  autoFocusSearch: autoFocusSearch
@@ -10,15 +10,13 @@ import { css, jsx } from '@emotion/react';
10
10
  import { FormattedMessage } from 'react-intl-next';
11
11
  import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext';
12
12
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
13
- import { fg } from '@atlaskit/platform-feature-flags';
14
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
14
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '../../analytics';
16
15
  import editorUGCToken from '../../ugc-tokens/get-editor-ugc-token';
17
- import { ViewMore as ViewMoreNext } from '../components/ViewMore';
16
+ import { ViewMore } from '../components/ViewMore';
18
17
  import { DEVICE_BREAKPOINT_NUMBERS, ELEMENT_BROWSER_ID, ELEMENT_BROWSER_LIST_ID, GRID_SIZE, INLINE_SIDEBAR_HEIGHT, SIDEBAR_HEADING_WRAPPER_HEIGHT, SIDEBAR_WIDTH } from '../constants';
19
18
  import useContainerWidth from '../hooks/use-container-width';
20
19
  import useSelectAndFocusOnArrowNavigation from '../hooks/use-select-and-focus-on-arrow-navigation';
21
- import { ViewMore } from '../ViewMore';
22
20
  import CategoryList from './CategoryList';
23
21
  import ElementList from './ElementList/ElementList';
24
22
  import ElementSearch from './ElementSearch';
@@ -120,7 +118,6 @@ function StatelessElementBrowser(props) {
120
118
  items,
121
119
  onSelectItem,
122
120
  onInsertItem,
123
- viewMoreItem,
124
121
  onViewMore,
125
122
  selectedCategory,
126
123
  onSelectCategory,
@@ -166,7 +163,7 @@ function StatelessElementBrowser(props) {
166
163
  focusOnViewMore,
167
164
  onKeyDown,
168
165
  setFocusOnSearch
169
- } = useSelectAndFocusOnArrowNavigation(items.length - 1, columnCount, fg('platform_editor_refactor_view_more') ? !!onViewMore : !!viewMoreItem, itemIsDisabled, isFocusSearch, autoFocusSearch);
166
+ } = useSelectAndFocusOnArrowNavigation(items.length - 1, columnCount, !!onViewMore, itemIsDisabled, isFocusSearch, autoFocusSearch);
170
167
  useEffect(() => {
171
168
  fireAnalyticsEvent(props.createAnalyticsEvent)({
172
169
  payload: {
@@ -258,7 +255,6 @@ function StatelessElementBrowser(props) {
258
255
  setFocusOnSearch: setFocusOnSearch,
259
256
  onKeyPress: onItemsEnterTabKeyPress,
260
257
  onKeyDown: onKeyDown,
261
- viewMoreItem: viewMoreItem,
262
258
  onViewMore: onViewMore,
263
259
  focusOnViewMore: focusOnViewMore,
264
260
  cache: cache
@@ -309,7 +305,6 @@ function MobileBrowser({
309
305
  searchTerm,
310
306
  createAnalyticsEvent,
311
307
  emptyStateHandler,
312
- viewMoreItem,
313
308
  onViewMore,
314
309
  cache,
315
310
  focusOnEmptyStateButton = false
@@ -361,12 +356,9 @@ function MobileBrowser({
361
356
  selectedCategory: selectedCategory,
362
357
  searchTerm: searchTerm,
363
358
  cache: cache
364
- })), onViewMore && fg('platform_editor_refactor_view_more') && jsx(ViewMoreNext, {
359
+ })), onViewMore && jsx(ViewMore, {
365
360
  onViewMore: onViewMore,
366
361
  focus: focusOnViewMore
367
- }), viewMoreItem && !fg('platform_editor_refactor_view_more') && jsx(ViewMore, {
368
- item: viewMoreItem,
369
- focus: focusOnViewMore
370
362
  }))
371
363
  );
372
364
  }
@@ -40,9 +40,9 @@ export const placeholderTextMessages = defineMessages({
40
40
  defaultMessage: ' to insert elements',
41
41
  description: 'Text after slash in long empty node placeholder'
42
42
  },
43
- syncBlockPlaceholderText: {
44
- id: 'fabric.editor.syncBlockPlaceholderText',
45
- defaultMessage: 'Add content then copy this synced block to access it across spaces',
46
- description: 'Placeholder text for sync block'
43
+ sourceSyncBlockPlaceholderText: {
44
+ id: 'fabric.editor.sourceSyncBlockPlaceholderText',
45
+ defaultMessage: 'Add content you want to reuse. Copy and paste this block to sync in other locations.',
46
+ description: 'Placeholder text for source sync block'
47
47
  }
48
48
  });
@@ -12,7 +12,7 @@ export const textColorMessages = defineMessages({
12
12
  },
13
13
  textColorHighlightTooltip: {
14
14
  id: 'fabric.editor.textColorHighlightTooltip',
15
- defaultMessage: 'Text and Highlight color',
15
+ defaultMessage: 'Text and highlight color',
16
16
  description: 'Tooltip of menu that provides access to various colors of highlight.'
17
17
  }
18
18
  });
@@ -4,7 +4,7 @@ import { isFedRamp } from './environment';
4
4
  import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
5
5
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
6
6
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
7
- const packageVersion = "111.7.1";
7
+ const packageVersion = "111.7.3";
8
8
  const sanitiseSentryEvents = (data, _hint) => {
9
9
  // Remove URL as it has UGC
10
10
  // Ignored via go/ees007
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "111.7.1";
17
+ const packageVersion = "111.7.3";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -1,6 +1,7 @@
1
1
  import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
2
2
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
5
  const MAXIMUM_BROWSER_SCROLLBAR_WIDTH = 20;
5
6
 
6
7
  /*
@@ -79,19 +80,36 @@ export const calculateToolbarPositionAboveSelection = toolbarTitle => (editorVie
79
80
  left: Math.max(0, left - wrapperBounds.left)
80
81
  };
81
82
  };
82
- /*
83
- Calculates the position of the floating toolbar relative to the selection.
84
- This is a re-implementation which closely matches the behaviour on Confluence renderer.
85
- The main difference is the popup is always above the selection.
86
- Things to consider:
87
- - stick as close to the head X release coordinates as possible
88
- - coordinates of head X and getBoundingClientRect() are absolute in client viewport (not including scroll offsets)
89
- - popup may appear in '.fabric-editor-popup-scroll-parent' (or body)
90
- - we use the toolbarRect to center align toolbar
91
- - use wrapperBounds to clamp values
92
- - editorView.dom bounds differ to wrapperBounds, convert at the end
93
- */
94
- export const calculateToolbarPositionTrackHead = toolbarTitle => (editorView, nextPos) => {
83
+ const findContainingElement = editorView => {
84
+ // First, try to find .fabric-editor-popup-scroll-parent
85
+ const scrollParent = editorView.dom.closest('.fabric-editor-popup-scroll-parent');
86
+ if (scrollParent) {
87
+ return {
88
+ container: scrollParent,
89
+ isFixed: false
90
+ };
91
+ } else {
92
+ // If no scroll parent, look for a fixed positioned parent
93
+ let fixedParent = editorView.dom.parentElement;
94
+ while (fixedParent && fixedParent !== document.body) {
95
+ const computedStyle = window.getComputedStyle(fixedParent);
96
+ if (computedStyle.position === 'fixed') {
97
+ return {
98
+ container: fixedParent,
99
+ isFixed: true
100
+ };
101
+ }
102
+ fixedParent = fixedParent.parentElement;
103
+ }
104
+ }
105
+
106
+ // Fall back to document.body if no fixed parent found
107
+ return {
108
+ container: document.body,
109
+ isFixed: false
110
+ };
111
+ };
112
+ export const calculateToolbarPositionTrackHeadOld = toolbarTitle => (editorView, nextPos) => {
95
113
  const toolbar = document.querySelector(`div[aria-label="${toolbarTitle}"]`);
96
114
  if (!toolbar) {
97
115
  return nextPos;
@@ -161,6 +179,124 @@ export const calculateToolbarPositionTrackHead = toolbarTitle => (editorView, ne
161
179
  };
162
180
  };
163
181
 
182
+ /**
183
+ * Same logic as calculateToolbarPositionTrackHeadOld, but with the following changes:
184
+ * - Uses a cached container to avoid repeated DOM traversal and getComputedStyle calls
185
+ * - Works when editor is nested within a fixed positioned parent, such as within a modal or sidebar
186
+ */
187
+ export const calculateToolbarPositionTrackHeadNew = toolbarTitle => {
188
+ // Cache the container to avoid repeated DOM traversal and getComputedStyle calls
189
+ let cachedContainer = null;
190
+ let isFixedContainer = false;
191
+ let cachedEditorDom = null;
192
+ return (editorView, nextPos) => {
193
+ const toolbar = document.querySelector(`div[aria-label="${toolbarTitle}"]`);
194
+ if (!toolbar) {
195
+ return nextPos;
196
+ }
197
+
198
+ // Find and cache the container (only recalculates if editor DOM changed)
199
+ if (cachedEditorDom !== editorView.dom) {
200
+ cachedEditorDom = editorView.dom;
201
+ const {
202
+ container,
203
+ isFixed
204
+ } = findContainingElement(editorView);
205
+ cachedContainer = container;
206
+ isFixedContainer = isFixed;
207
+ }
208
+ if (!cachedContainer) {
209
+ return nextPos;
210
+ }
211
+ const container = cachedContainer;
212
+ const containerBounds = container.getBoundingClientRect();
213
+ const selection = window && window.getSelection();
214
+ const moreRovoOptionsButton = document.querySelector('button[aria-label="More Rovo options"], [aria-label="More Rovo options"]');
215
+ const isMoreRovoOptionsButtonVisible = !!moreRovoOptionsButton && moreRovoOptionsButton instanceof HTMLElement && !!moreRovoOptionsButton.offsetParent;
216
+ let range = null;
217
+ if (isMoreRovoOptionsButtonVisible && fg('platform_editor_ai_generic_prep_for_aifc')) {
218
+ if (selection && selection.getRangeAt && selection.rangeCount > 0) {
219
+ const maybeRange = selection.getRangeAt(0);
220
+ if (maybeRange instanceof Range) {
221
+ range = maybeRange;
222
+ }
223
+ }
224
+ } else {
225
+ if (selection && !selection.isCollapsed && selection.getRangeAt && selection.rangeCount > 0) {
226
+ const maybeRange = selection.getRangeAt(0);
227
+ if (maybeRange instanceof Range) {
228
+ range = maybeRange;
229
+ }
230
+ }
231
+ }
232
+ if (!range) {
233
+ return nextPos;
234
+ }
235
+ const toolbarRect = toolbar.getBoundingClientRect();
236
+ const {
237
+ head,
238
+ anchor
239
+ } = editorView.state.selection;
240
+ const topCoords = editorView.coordsAtPos(Math.min(head, anchor));
241
+ const bottomCoords = editorView.coordsAtPos(Math.max(head, anchor) - Math.min(range.endOffset, 1));
242
+ let top;
243
+ // If not the same line AND we are selecting downwards, display toolbar below.
244
+ if (head > anchor && topCoords.top !== bottomCoords.top) {
245
+ // We are taking the previous pos to the maxium, so avoid end of line positions
246
+ // returning the next line's rect.
247
+ top = (bottomCoords.top || 0) + toolbarRect.height / 1.15;
248
+ } else {
249
+ top = (topCoords.top || 0) - toolbarRect.height * 1.5;
250
+ }
251
+ let left = (head > anchor ? bottomCoords.right : topCoords.left) - toolbarRect.width / 2;
252
+
253
+ // Place toolbar below selection if not sufficient space above
254
+ if (top < containerBounds.top) {
255
+ ({
256
+ top,
257
+ left
258
+ } = getCoordsBelowSelection(bottomCoords, toolbarRect));
259
+ }
260
+ let leftCoord = Math.max(0, left - containerBounds.left);
261
+ if (leftCoord + toolbarRect.width > containerBounds.width) {
262
+ const scrollbarWidth = MAXIMUM_BROWSER_SCROLLBAR_WIDTH;
263
+ leftCoord = Math.max(0, containerBounds.width - (toolbarRect.width + scrollbarWidth));
264
+ }
265
+
266
+ // Apply scroll offset only for non-fixed containers
267
+ // Fixed positioned elements don't scroll with the page
268
+ const scrollOffset = isFixedContainer ? 0 : container.scrollTop;
269
+ return {
270
+ top: top - containerBounds.top + scrollOffset,
271
+ left: leftCoord
272
+ };
273
+ };
274
+ };
275
+
276
+ /*
277
+ Calculates the position of the floating toolbar relative to the selection.
278
+ This implementation works in multiple scenarios:
279
+ - Standard scrollable containers with .fabric-editor-popup-scroll-parent
280
+ - Fixed positioned parent containers
281
+ - Falls back to document.body
282
+
283
+ The function automatically detects the container type and applies the appropriate
284
+ positioning logic and scroll offset handling.
285
+
286
+ Things to consider:
287
+ - stick as close to the head X release coordinates as possible
288
+ - coordinates of head X and getBoundingClientRect() are absolute in client viewport
289
+ - popup may appear in '.fabric-editor-popup-scroll-parent', fixed parent, or body
290
+ - we use the toolbarRect to center align toolbar
291
+ - use container bounds to clamp values
292
+ - for fixed positioning, no scroll offsets are applied
293
+ - for scrollable containers, scroll offsets are included
294
+ */
295
+ export const calculateToolbarPositionTrackHead = toolbarTitle => {
296
+ const isSelToolbarFixEnabled = expValEquals('platform_editor_sel_toolbar_fix', 'isEnabled', true);
297
+ return isSelToolbarFixEnabled ? calculateToolbarPositionTrackHeadNew(toolbarTitle) : calculateToolbarPositionTrackHeadOld(toolbarTitle);
298
+ };
299
+
164
300
  /**
165
301
  * Returns the coordintes at the bottom the selection.
166
302
  */