@atlaskit/editor-common 116.24.3 → 116.24.5

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 (38) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/extensibility/Extension/Lozenge/ExtensionLabel.js +11 -17
  3. package/dist/cjs/extensibility/Extension/Lozenge/LozengeComponent.js +6 -2
  4. package/dist/cjs/extensibility/Extension/Lozenge/index.js +4 -2
  5. package/dist/cjs/extensibility/Extension.js +2 -0
  6. package/dist/cjs/extensibility/ExtensionComponent.js +6 -2
  7. package/dist/cjs/extensibility/MultiBodiedExtension/index.js +75 -9
  8. package/dist/cjs/extensibility/extensionNodeView.js +3 -1
  9. package/dist/cjs/extensions/extension-handlers.js +3 -0
  10. package/dist/cjs/monitoring/error.js +1 -1
  11. package/dist/cjs/ui/DropList/index.js +1 -1
  12. package/dist/es2019/extensibility/Extension/Lozenge/ExtensionLabel.js +10 -16
  13. package/dist/es2019/extensibility/Extension/Lozenge/LozengeComponent.js +6 -2
  14. package/dist/es2019/extensibility/Extension/Lozenge/index.js +4 -2
  15. package/dist/es2019/extensibility/Extension.js +2 -0
  16. package/dist/es2019/extensibility/ExtensionComponent.js +7 -3
  17. package/dist/es2019/extensibility/MultiBodiedExtension/index.js +66 -5
  18. package/dist/es2019/extensibility/extensionNodeView.js +3 -1
  19. package/dist/es2019/extensions/extension-handlers.js +3 -0
  20. package/dist/es2019/monitoring/error.js +1 -1
  21. package/dist/es2019/ui/DropList/index.js +1 -1
  22. package/dist/esm/extensibility/Extension/Lozenge/ExtensionLabel.js +10 -16
  23. package/dist/esm/extensibility/Extension/Lozenge/LozengeComponent.js +6 -2
  24. package/dist/esm/extensibility/Extension/Lozenge/index.js +4 -2
  25. package/dist/esm/extensibility/Extension.js +2 -0
  26. package/dist/esm/extensibility/ExtensionComponent.js +6 -2
  27. package/dist/esm/extensibility/MultiBodiedExtension/index.js +76 -10
  28. package/dist/esm/extensibility/extensionNodeView.js +3 -1
  29. package/dist/esm/extensions/extension-handlers.js +3 -0
  30. package/dist/esm/monitoring/error.js +1 -1
  31. package/dist/esm/ui/DropList/index.js +1 -1
  32. package/dist/types/extensibility/Extension/Lozenge/ExtensionLabel.d.ts +3 -2
  33. package/dist/types/extensibility/Extension/Lozenge/LozengeComponent.d.ts +2 -1
  34. package/dist/types/extensibility/Extension/Lozenge/index.d.ts +1 -0
  35. package/dist/types/extensibility/Extension.d.ts +1 -0
  36. package/dist/types/extensibility/ExtensionComponent.d.ts +1 -0
  37. package/dist/types/extensibility/extensionNodeView.d.ts +3 -1
  38. package/package.json +4 -4
@@ -5,10 +5,11 @@ import _extends from "@babel/runtime/helpers/extends";
5
5
  * @jsx jsx
6
6
  */
7
7
 
8
- import React, { Fragment, useState } from 'react';
8
+ import React, { Fragment, useEffect, useRef, useState } from 'react';
9
9
 
10
10
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic
11
11
  import { css, jsx } from '@emotion/react';
12
+ import { bind } from 'bind-event-listener';
12
13
  import classnames from 'classnames';
13
14
  import EditorFileIcon from '@atlaskit/icon/core/file';
14
15
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -52,6 +53,62 @@ const MultiBodiedExtensionFrames = ({
52
53
  ref: articleRef
53
54
  });
54
55
  };
56
+ const isSelectionInsideNode = (selection, node, getPos) => {
57
+ const nodeStartPosition = getPos();
58
+ if (typeof nodeStartPosition !== 'number' || !selection) {
59
+ return false;
60
+ }
61
+ const nodeEndPosition = nodeStartPosition + node.nodeSize;
62
+
63
+ /*
64
+ selection starts within MBE ||
65
+ selection ends within MBE ||
66
+ selection includes MBE
67
+ */
68
+ return nodeStartPosition < selection.from && selection.from < nodeEndPosition || nodeStartPosition < selection.to && selection.to < nodeEndPosition || nodeStartPosition >= selection.from && selection.to >= nodeEndPosition;
69
+ };
70
+ const useIsSelectionInsideNode = (editorView, node, getPos, enabled) => {
71
+ const nodeRef = useRef(node);
72
+ const [isSelectionInside, setIsSelectionInside] = useState(() => enabled && isSelectionInsideNode(editorView.state.selection, node, getPos));
73
+ nodeRef.current = node;
74
+ useEffect(() => {
75
+ if (!enabled) {
76
+ return;
77
+ }
78
+ let animationFrameId;
79
+ const updateSelectionInsideNode = () => {
80
+ setIsSelectionInside(isSelectionInsideNode(editorView.state.selection, nodeRef.current, getPos));
81
+ };
82
+ const scheduleUpdateSelectionInsideNode = () => {
83
+ if (animationFrameId !== undefined) {
84
+ cancelAnimationFrame(animationFrameId);
85
+ }
86
+ animationFrameId = requestAnimationFrame(updateSelectionInsideNode);
87
+ };
88
+ const ownerDocument = editorView.dom.ownerDocument;
89
+ const unbindSelectionChange = bind(ownerDocument, {
90
+ listener: scheduleUpdateSelectionInsideNode,
91
+ type: 'selectionchange'
92
+ });
93
+ const unbindKeyUp = bind(editorView.dom, {
94
+ listener: scheduleUpdateSelectionInsideNode,
95
+ type: 'keyup'
96
+ });
97
+ const unbindMouseUp = bind(editorView.dom, {
98
+ listener: scheduleUpdateSelectionInsideNode,
99
+ type: 'mouseup'
100
+ });
101
+ return () => {
102
+ if (animationFrameId !== undefined) {
103
+ cancelAnimationFrame(animationFrameId);
104
+ }
105
+ unbindSelectionChange();
106
+ unbindKeyUp();
107
+ unbindMouseUp();
108
+ };
109
+ }, [editorView, getPos, enabled]);
110
+ return enabled && isSelectionInside;
111
+ };
55
112
 
56
113
  // Similar to the one in platform/packages/editor/editor-common/src/extensibility/Extension/Lozenge.tsx
57
114
  const getWrapperTitleContent = (imageData, title, showMacroInteractionDesignUpdates) => {
@@ -166,8 +223,11 @@ const MultiBodiedExtensionWithWidth = ({
166
223
  });
167
224
  mbeWrapperStyles = breakoutStyles;
168
225
  }
226
+ const shouldUseNativeTabsPresentation = fg('confluence_frontend_native_tabs_extension');
227
+ const isSelectionInsideMultiBodiedExtension = useIsSelectionInsideNode(editorView, node, getPos, shouldUseNativeTabsPresentation);
228
+ const isMultiBodiedExtensionActive = isNodeSelected || isSelectionInsideMultiBodiedExtension;
169
229
  const wrapperClassNames = classnames('multiBodiedExtension--wrapper', 'extension-container', 'block', {
170
- 'with-border': showMacroInteractionDesignUpdates,
230
+ 'with-border': showMacroInteractionDesignUpdates && (shouldUseNativeTabsPresentation ? isMultiBodiedExtensionActive : true),
171
231
  'with-danger-overlay': showMacroInteractionDesignUpdates,
172
232
  'with-padding-background-styles': showMacroInteractionDesignUpdates,
173
233
  'with-margin-styles': showMacroInteractionDesignUpdates && !isNodeNested
@@ -189,7 +249,7 @@ const MultiBodiedExtensionWithWidth = ({
189
249
  }
190
250
  };
191
251
  return jsx(Fragment, null, showMacroInteractionDesignUpdates && !isLivePageViewMode && jsx(ExtensionLozenge, {
192
- isNodeSelected: isNodeSelected,
252
+ isNodeSelected: shouldUseNativeTabsPresentation ? isMultiBodiedExtensionActive : isNodeSelected,
193
253
  node: node,
194
254
  showMacroInteractionDesignUpdates: true,
195
255
  customContainerStyles: mbeWrapperStyles,
@@ -197,12 +257,13 @@ const MultiBodiedExtensionWithWidth = ({
197
257
  isNodeNested: isNodeNested,
198
258
  setIsNodeHovered: setIsNodeHovered,
199
259
  isBodiedMacro: true,
260
+ isMultiBodiedMacro: shouldUseNativeTabsPresentation,
200
261
  pluginInjectionApi: pluginInjectionApi
201
262
  }), jsx("div", {
202
263
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
203
264
  className: wrapperClassNames,
204
265
  css: [/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
205
- fg('confluence_frontend_native_tabs_extension') ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
266
+ shouldUseNativeTabsPresentation ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
206
267
  showMacroInteractionDesignUpdates && !isLivePageViewMode && hoverStyles],
207
268
  "data-testid": "multiBodiedExtension--wrapper-editor",
208
269
  "data-layout": node.attrs.layout
@@ -218,7 +279,7 @@ const MultiBodiedExtensionWithWidth = ({
218
279
  onBlur: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? () => {} : undefined
219
280
  }, jsx("div", {
220
281
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
221
- css: fg('confluence_frontend_native_tabs_extension') ? overlayStyles : overlayStylesOld
282
+ css: shouldUseNativeTabsPresentation ? overlayStyles : overlayStylesOld
222
283
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
223
284
  ,
224
285
  className: overlayClassNames,
@@ -275,6 +275,7 @@ export class ExtensionNode extends ReactNodeView {
275
275
  providerFactory: props.providerFactory,
276
276
  handleContentDOMRef: forwardRef,
277
277
  extensionHandlers: props.extensionHandlers,
278
+ extensionLoadingHandlers: props.extensionLoadingHandlers,
278
279
  editorAppearance: (_props$extensionNodeV = props.extensionNodeViewOptions) === null || _props$extensionNodeV === void 0 ? void 0 : _props$extensionNodeV.appearance,
279
280
  pluginInjectionApi: props.pluginInjectionApi,
280
281
  macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags,
@@ -286,11 +287,12 @@ export class ExtensionNode extends ReactNodeView {
286
287
  }
287
288
 
288
289
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
289
- export default function ExtensionNodeView(portalProviderAPI, eventDispatcher, providerFactory, extensionHandlers, extensionNodeViewOptions, pluginInjectionApi, macroInteractionDesignFeatureFlags, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, rendererExtensionHandlers, intl) {
290
+ export default function ExtensionNodeView(portalProviderAPI, eventDispatcher, providerFactory, extensionHandlers, extensionLoadingHandlers, extensionNodeViewOptions, pluginInjectionApi, macroInteractionDesignFeatureFlags, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, rendererExtensionHandlers, intl) {
290
291
  return (node, view, getPos) => {
291
292
  return new ExtensionNode(node, view, getPos, portalProviderAPI, eventDispatcher, {
292
293
  providerFactory,
293
294
  extensionHandlers,
295
+ extensionLoadingHandlers,
294
296
  extensionNodeViewOptions,
295
297
  pluginInjectionApi,
296
298
  macroInteractionDesignFeatureFlags,
@@ -63,6 +63,9 @@ function isUnknownConfluenceMacroWithBody(extensionNode) {
63
63
  function ExtensionLoading(props) {
64
64
  const intl = useIntl();
65
65
  const extensionNode = props.node;
66
+ if (!props.error && !props.timedOut && props.loadingFallback) {
67
+ return /*#__PURE__*/React.createElement(React.Fragment, null, props.loadingFallback);
68
+ }
66
69
  if (props.error || props.timedOut) {
67
70
  // eslint-disable-next-line no-console
68
71
  console.error('Error rendering extension', props.error);
@@ -14,7 +14,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
14
14
  const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
15
15
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
16
16
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
17
- const packageVersion = "116.24.2";
17
+ const packageVersion = "116.24.4";
18
18
  const sanitiseSentryEvents = (data, _hint) => {
19
19
  // Remove URL as it has UGC
20
20
  // 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 = "116.24.2";
17
+ const packageVersion = "116.24.4";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -10,6 +10,7 @@ import { css, jsx } from '@emotion/react';
10
10
  import classnames from 'classnames';
11
11
  import { FormattedMessage, defineMessages } from 'react-intl';
12
12
  import CustomizeIcon from '@atlaskit/icon/core/customize';
13
+ import { fg } from '@atlaskit/platform-feature-flags';
13
14
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
14
15
  import { Box, xcss } from '@atlaskit/primitives';
15
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -108,32 +109,25 @@ var i18n = defineMessages({
108
109
  description: 'Text in tooltip that tells user they can configure the specific macro.'
109
110
  }
110
111
  });
111
- export var getShouldShowBodiedMacroLabel = function getShouldShowBodiedMacroLabel(isBodiedMacro, isNodeHovered, showLivePagesBodiedMacrosRendererView, showBodiedExtensionRendererView, showUpdatedLivePages1PBodiedExtensionUI) {
112
- // Bodied macros show the label by default except for the new live pages 1P bodied macro experience where we only show it on hover
113
- if (!isBodiedMacro || showUpdatedLivePages1PBodiedExtensionUI) {
114
- return isNodeHovered;
115
- }
116
- if (!showLivePagesBodiedMacrosRendererView) {
117
- return true;
118
- } // Keep showing labels as usual for default experience for bodied macros
119
- return !!(isNodeHovered && !showBodiedExtensionRendererView); // For the new live pages bodied macro experience, we only show the label on hover in the "edit" view
120
- };
121
112
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
122
113
  export var ExtensionLabel = function ExtensionLabel(_ref) {
123
114
  var text = _ref.text,
124
115
  extensionName = _ref.extensionName,
125
116
  customContainerStyles = _ref.customContainerStyles,
126
117
  isNodeNested = _ref.isNodeNested,
118
+ isNodeSelected = _ref.isNodeSelected,
127
119
  setIsNodeHovered = _ref.setIsNodeHovered,
128
120
  isBodiedMacro = _ref.isBodiedMacro,
129
121
  showUpdatedLivePages1PBodiedExtensionUI = _ref.showUpdatedLivePages1PBodiedExtensionUI,
130
122
  showLivePagesBodiedMacrosRendererView = _ref.showLivePagesBodiedMacrosRendererView,
131
123
  showBodiedExtensionRendererView = _ref.showBodiedExtensionRendererView,
132
- _pluginInjectionApi = _ref.pluginInjectionApi;
124
+ _pluginInjectionApi = _ref.pluginInjectionApi,
125
+ isMultiBodiedMacro = _ref.isMultiBodiedMacro;
133
126
  var isInlineExtension = extensionName === 'inlineExtension';
134
127
  var showDefaultBodiedStyles = isBodiedMacro;
128
+ var shouldUseMultiBodiedMacroPresentation = isMultiBodiedMacro && fg('confluence_frontend_native_tabs_extension');
135
129
  var containerClassNames = classnames({
136
- bodied: isBodiedMacro
130
+ bodied: isBodiedMacro && !shouldUseMultiBodiedMacroPresentation
137
131
  });
138
132
  var labelClassNames = classnames('extension-label', {
139
133
  nested: isNodeNested,
@@ -144,8 +138,8 @@ export var ExtensionLabel = function ExtensionLabel(_ref) {
144
138
  'with-bodied-macro-live-page-styles': isBodiedMacro && showLivePagesBodiedMacrosRendererView,
145
139
  'always-hide-label': isBodiedMacro && showBodiedExtensionRendererView,
146
140
  // Need this separate class since we don't ever want to show the label during view mode
147
- 'remove-left-margin': !isBodiedMacro && !isInlineExtension && !isNodeNested,
148
- 'remove-nested-left-margin': isNodeNested && !isBodiedMacro && !isInlineExtension
141
+ 'remove-left-margin': (!isBodiedMacro || shouldUseMultiBodiedMacroPresentation) && !isInlineExtension && !isNodeNested,
142
+ 'remove-nested-left-margin': isNodeNested && (!isBodiedMacro || shouldUseMultiBodiedMacroPresentation) && !isInlineExtension
149
143
  });
150
144
  var iconClassNames = classnames({
151
145
  'extension-icon': true
@@ -197,12 +191,12 @@ export var ExtensionLabel = function ExtensionLabel(_ref) {
197
191
  // Ignored via go/ees005
198
192
  // eslint-disable-next-line react/jsx-props-no-spreading
199
193
  }, tooltipProps, {
200
- css: [labelStyles, !showLivePagesBodiedMacrosRendererView && showLabelStyles, (!isBodiedMacro || showUpdatedLivePages1PBodiedExtensionUI) && hideLabelStyles]
194
+ css: [labelStyles, !showLivePagesBodiedMacrosRendererView && showLabelStyles, (!isBodiedMacro || showUpdatedLivePages1PBodiedExtensionUI || shouldUseMultiBodiedMacroPresentation && !isNodeSelected) && hideLabelStyles]
201
195
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
202
196
  ,
203
197
  className: labelClassNames
204
198
  }), text, jsx("span", {
205
- css: [iconStyles, isBodiedMacro && bodiedMacroIconStyles]
199
+ css: [iconStyles, isBodiedMacro && !shouldUseMultiBodiedMacroPresentation && bodiedMacroIconStyles]
206
200
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
207
201
  ,
208
202
  className: iconClassNames,
@@ -29,13 +29,15 @@ export var LozengeComponent = function LozengeComponent(_ref) {
29
29
  customContainerStyles = _ref.customContainerStyles,
30
30
  isNodeHovered = _ref.isNodeHovered,
31
31
  isNodeNested = _ref.isNodeNested,
32
+ isNodeSelected = _ref.isNodeSelected,
32
33
  setIsNodeHovered = _ref.setIsNodeHovered,
33
34
  isBodiedMacro = _ref.isBodiedMacro,
34
35
  showLivePagesBodiedMacrosRendererView = _ref.showLivePagesBodiedMacrosRendererView,
35
36
  showUpdatedLivePages1PBodiedExtensionUI = _ref.showUpdatedLivePages1PBodiedExtensionUI,
36
37
  showBodiedExtensionRendererView = _ref.showBodiedExtensionRendererView,
37
38
  setShowBodiedExtensionRendererView = _ref.setShowBodiedExtensionRendererView,
38
- pluginInjectionApi = _ref.pluginInjectionApi;
39
+ pluginInjectionApi = _ref.pluginInjectionApi,
40
+ isMultiBodiedMacro = _ref.isMultiBodiedMacro;
39
41
  var capitalizedTitle = capitalizeFirstLetter(title);
40
42
  if (showMacroInteractionDesignUpdates) {
41
43
  return jsx(Fragment, null, jsx(ExtensionLabel, {
@@ -43,13 +45,15 @@ export var LozengeComponent = function LozengeComponent(_ref) {
43
45
  extensionName: extensionName,
44
46
  isNodeHovered: isNodeHovered,
45
47
  isNodeNested: isNodeNested,
48
+ isNodeSelected: isNodeSelected,
46
49
  customContainerStyles: customContainerStyles,
47
50
  setIsNodeHovered: setIsNodeHovered,
48
51
  isBodiedMacro: isBodiedMacro,
49
52
  showLivePagesBodiedMacrosRendererView: showLivePagesBodiedMacrosRendererView,
50
53
  showUpdatedLivePages1PBodiedExtensionUI: showUpdatedLivePages1PBodiedExtensionUI,
51
54
  showBodiedExtensionRendererView: showBodiedExtensionRendererView,
52
- pluginInjectionApi: pluginInjectionApi
55
+ pluginInjectionApi: pluginInjectionApi,
56
+ isMultiBodiedMacro: isMultiBodiedMacro
53
57
  }), showLivePagesBodiedMacrosRendererView && isBodiedMacro && jsx(EditToggle, {
54
58
  isNodeHovered: isNodeHovered,
55
59
  setIsNodeHovered: setIsNodeHovered,
@@ -54,7 +54,8 @@ var ExtensionLozenge = /*#__PURE__*/function (_Component) {
54
54
  showUpdatedLivePages1PBodiedExtensionUI = _this$props.showUpdatedLivePages1PBodiedExtensionUI,
55
55
  showBodiedExtensionRendererView = _this$props.showBodiedExtensionRendererView,
56
56
  setShowBodiedExtensionRendererView = _this$props.setShowBodiedExtensionRendererView,
57
- pluginInjectionApi = _this$props.pluginInjectionApi;
57
+ pluginInjectionApi = _this$props.pluginInjectionApi,
58
+ isMultiBodiedMacro = _this$props.isMultiBodiedMacro;
58
59
  var _this$props$node$attr = _this.props.node.attrs,
59
60
  parameters = _this$props$node$attr.parameters,
60
61
  extensionKey = _this$props$node$attr.extensionKey;
@@ -78,7 +79,8 @@ var ExtensionLozenge = /*#__PURE__*/function (_Component) {
78
79
  showUpdatedLivePages1PBodiedExtensionUI: showUpdatedLivePages1PBodiedExtensionUI,
79
80
  showBodiedExtensionRendererView: showBodiedExtensionRendererView,
80
81
  setShowBodiedExtensionRendererView: setShowBodiedExtensionRendererView,
81
- pluginInjectionApi: pluginInjectionApi
82
+ pluginInjectionApi: pluginInjectionApi,
83
+ isMultiBodiedMacro: isMultiBodiedMacro
82
84
  });
83
85
  });
84
86
  return _this;
@@ -25,6 +25,7 @@ export var Extension = /*#__PURE__*/function (_Component) {
25
25
  editorView = _this$props.editorView,
26
26
  handleContentDOMRef = _this$props.handleContentDOMRef,
27
27
  extensionHandlers = _this$props.extensionHandlers,
28
+ extensionLoadingHandlers = _this$props.extensionLoadingHandlers,
28
29
  references = _this$props.references,
29
30
  editorAppearance = _this$props.editorAppearance,
30
31
  pluginInjectionApi = _this$props.pluginInjectionApi,
@@ -50,6 +51,7 @@ export var Extension = /*#__PURE__*/function (_Component) {
50
51
  extensionProvider: extensionProvider,
51
52
  handleContentDOMRef: handleContentDOMRef,
52
53
  extensionHandlers: extensionHandlers,
54
+ extensionLoadingHandlers: extensionLoadingHandlers,
53
55
  editorAppearance: editorAppearance,
54
56
  pluginInjectionApi: pluginInjectionApi,
55
57
  eventDispatcher: eventDispatcher,
@@ -140,6 +140,7 @@ var ExtensionComponentInner = /*#__PURE__*/function (_Component) {
140
140
  var _pmNode$marks;
141
141
  var _this$props = _this.props,
142
142
  extensionHandlers = _this$props.extensionHandlers,
143
+ extensionLoadingHandlers = _this$props.extensionLoadingHandlers,
143
144
  editorView = _this$props.editorView,
144
145
  showBodiedExtensionRendererView = _this$props.showBodiedExtensionRendererView,
145
146
  rendererExtensionHandlers = _this$props.rendererExtensionHandlers;
@@ -175,6 +176,7 @@ var ExtensionComponentInner = /*#__PURE__*/function (_Component) {
175
176
  }
176
177
  }
177
178
  var result;
179
+ var loadingFallback = extensionLoadingHandlers !== null && extensionLoadingHandlers !== void 0 && extensionLoadingHandlers[extensionType] ? getExtensionRenderer(extensionLoadingHandlers[extensionType])(node, editorView.state.doc, actions) : undefined;
178
180
  if (extensionHandlers && extensionHandlers[extensionType]) {
179
181
  var render = getExtensionRenderer(extensionHandlers[extensionType]);
180
182
  result = render(node, editorView.state.doc, actions);
@@ -187,18 +189,20 @@ var ExtensionComponentInner = /*#__PURE__*/function (_Component) {
187
189
  return /*#__PURE__*/React.createElement(NodeRenderer, {
188
190
  node: node,
189
191
  references: _this.props.references,
190
- actions: actions
192
+ actions: actions,
193
+ loadingFallback: loadingFallback
191
194
  });
192
195
  }
193
196
  return /*#__PURE__*/React.createElement(NodeRenderer, {
194
197
  node: node,
195
198
  references: _this.props.references,
196
199
  isSelected: isSelected,
200
+ loadingFallback: loadingFallback,
197
201
  showUnknownMacroPlaceholder: fg('tinymce_display_unknown_macro_body_content')
198
202
  });
199
203
  }
200
204
  }
201
- return result;
205
+ return result !== null && result !== void 0 ? result : loadingFallback;
202
206
  });
203
207
  return _this;
204
208
  }
@@ -1,7 +1,7 @@
1
1
  import _objectDestructuringEmpty from "@babel/runtime/helpers/objectDestructuringEmpty";
2
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
2
  import _extends from "@babel/runtime/helpers/extends";
4
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
6
  var _excluded = ["url"];
7
7
  /* eslint-disable @atlaskit/design-system/prefer-primitives */
@@ -10,10 +10,11 @@ var _excluded = ["url"];
10
10
  * @jsx jsx
11
11
  */
12
12
 
13
- import React, { Fragment, useState } from 'react';
13
+ import React, { Fragment, useEffect, useRef, useState } from 'react';
14
14
 
15
15
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic
16
16
  import { css, jsx } from '@emotion/react';
17
+ import { bind } from 'bind-event-listener';
17
18
  import classnames from 'classnames';
18
19
  import EditorFileIcon from '@atlaskit/icon/core/file';
19
20
  import { fg } from '@atlaskit/platform-feature-flags';
@@ -56,6 +57,67 @@ var MultiBodiedExtensionFrames = function MultiBodiedExtensionFrames(_ref) {
56
57
  ref: articleRef
57
58
  });
58
59
  };
60
+ var isSelectionInsideNode = function isSelectionInsideNode(selection, node, getPos) {
61
+ var nodeStartPosition = getPos();
62
+ if (typeof nodeStartPosition !== 'number' || !selection) {
63
+ return false;
64
+ }
65
+ var nodeEndPosition = nodeStartPosition + node.nodeSize;
66
+
67
+ /*
68
+ selection starts within MBE ||
69
+ selection ends within MBE ||
70
+ selection includes MBE
71
+ */
72
+ return nodeStartPosition < selection.from && selection.from < nodeEndPosition || nodeStartPosition < selection.to && selection.to < nodeEndPosition || nodeStartPosition >= selection.from && selection.to >= nodeEndPosition;
73
+ };
74
+ var useIsSelectionInsideNode = function useIsSelectionInsideNode(editorView, node, getPos, enabled) {
75
+ var nodeRef = useRef(node);
76
+ var _useState = useState(function () {
77
+ return enabled && isSelectionInsideNode(editorView.state.selection, node, getPos);
78
+ }),
79
+ _useState2 = _slicedToArray(_useState, 2),
80
+ isSelectionInside = _useState2[0],
81
+ setIsSelectionInside = _useState2[1];
82
+ nodeRef.current = node;
83
+ useEffect(function () {
84
+ if (!enabled) {
85
+ return;
86
+ }
87
+ var animationFrameId;
88
+ var updateSelectionInsideNode = function updateSelectionInsideNode() {
89
+ setIsSelectionInside(isSelectionInsideNode(editorView.state.selection, nodeRef.current, getPos));
90
+ };
91
+ var scheduleUpdateSelectionInsideNode = function scheduleUpdateSelectionInsideNode() {
92
+ if (animationFrameId !== undefined) {
93
+ cancelAnimationFrame(animationFrameId);
94
+ }
95
+ animationFrameId = requestAnimationFrame(updateSelectionInsideNode);
96
+ };
97
+ var ownerDocument = editorView.dom.ownerDocument;
98
+ var unbindSelectionChange = bind(ownerDocument, {
99
+ listener: scheduleUpdateSelectionInsideNode,
100
+ type: 'selectionchange'
101
+ });
102
+ var unbindKeyUp = bind(editorView.dom, {
103
+ listener: scheduleUpdateSelectionInsideNode,
104
+ type: 'keyup'
105
+ });
106
+ var unbindMouseUp = bind(editorView.dom, {
107
+ listener: scheduleUpdateSelectionInsideNode,
108
+ type: 'mouseup'
109
+ });
110
+ return function () {
111
+ if (animationFrameId !== undefined) {
112
+ cancelAnimationFrame(animationFrameId);
113
+ }
114
+ unbindSelectionChange();
115
+ unbindKeyUp();
116
+ unbindMouseUp();
117
+ };
118
+ }, [editorView, getPos, enabled]);
119
+ return enabled && isSelectionInside;
120
+ };
59
121
 
60
122
  // Similar to the one in platform/packages/editor/editor-common/src/extensibility/Extension/Lozenge.tsx
61
123
  var getWrapperTitleContent = function getWrapperTitleContent(imageData, title, showMacroInteractionDesignUpdates) {
@@ -115,10 +177,10 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
115
177
  node: node,
116
178
  type: 'image'
117
179
  });
118
- var _useState = useState(0),
119
- _useState2 = _slicedToArray(_useState, 2),
120
- activeChildIndex = _useState2[0],
121
- setActiveChildIndex = _useState2[1];
180
+ var _useState3 = useState(0),
181
+ _useState4 = _slicedToArray(_useState3, 2),
182
+ activeChildIndex = _useState4[0],
183
+ setActiveChildIndex = _useState4[1];
122
184
  // Adding to avoid aliasing `this` for the callbacks
123
185
  var updateActiveChild = React.useCallback(function (index) {
124
186
  if (typeof index !== 'number') {
@@ -168,8 +230,11 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
168
230
  breakoutStyles = _extends({}, (_objectDestructuringEmpty(_calculateBreakoutSty), _calculateBreakoutSty));
169
231
  mbeWrapperStyles = breakoutStyles;
170
232
  }
233
+ var shouldUseNativeTabsPresentation = fg('confluence_frontend_native_tabs_extension');
234
+ var isSelectionInsideMultiBodiedExtension = useIsSelectionInsideNode(editorView, node, getPos, shouldUseNativeTabsPresentation);
235
+ var isMultiBodiedExtensionActive = isNodeSelected || isSelectionInsideMultiBodiedExtension;
171
236
  var wrapperClassNames = classnames('multiBodiedExtension--wrapper', 'extension-container', 'block', {
172
- 'with-border': showMacroInteractionDesignUpdates,
237
+ 'with-border': showMacroInteractionDesignUpdates && (shouldUseNativeTabsPresentation ? isMultiBodiedExtensionActive : true),
173
238
  'with-danger-overlay': showMacroInteractionDesignUpdates,
174
239
  'with-padding-background-styles': showMacroInteractionDesignUpdates,
175
240
  'with-margin-styles': showMacroInteractionDesignUpdates && !isNodeNested
@@ -191,7 +256,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
191
256
  }
192
257
  };
193
258
  return jsx(Fragment, null, showMacroInteractionDesignUpdates && !isLivePageViewMode && jsx(ExtensionLozenge, {
194
- isNodeSelected: isNodeSelected,
259
+ isNodeSelected: shouldUseNativeTabsPresentation ? isMultiBodiedExtensionActive : isNodeSelected,
195
260
  node: node,
196
261
  showMacroInteractionDesignUpdates: true,
197
262
  customContainerStyles: mbeWrapperStyles,
@@ -199,12 +264,13 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
199
264
  isNodeNested: isNodeNested,
200
265
  setIsNodeHovered: setIsNodeHovered,
201
266
  isBodiedMacro: true,
267
+ isMultiBodiedMacro: shouldUseNativeTabsPresentation,
202
268
  pluginInjectionApi: pluginInjectionApi
203
269
  }), jsx("div", {
204
270
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
205
271
  className: wrapperClassNames,
206
272
  css: [/* eslint-disable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
207
- fg('confluence_frontend_native_tabs_extension') ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
273
+ shouldUseNativeTabsPresentation ? mbeExtensionWrapperCSSStyles : mbeExtensionWrapperCSSStylesOld, /* eslint-enable @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage */
208
274
  showMacroInteractionDesignUpdates && !isLivePageViewMode && hoverStyles],
209
275
  "data-testid": "multiBodiedExtension--wrapper-editor",
210
276
  "data-layout": node.attrs.layout
@@ -224,7 +290,7 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
224
290
  onBlur: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? function () {} : undefined
225
291
  }, jsx("div", {
226
292
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
227
- css: fg('confluence_frontend_native_tabs_extension') ? overlayStyles : overlayStylesOld
293
+ css: shouldUseNativeTabsPresentation ? overlayStyles : overlayStylesOld
228
294
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
229
295
  ,
230
296
  className: overlayClassNames,
@@ -313,6 +313,7 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
313
313
  providerFactory: props.providerFactory,
314
314
  handleContentDOMRef: forwardRef,
315
315
  extensionHandlers: props.extensionHandlers,
316
+ extensionLoadingHandlers: props.extensionLoadingHandlers,
316
317
  editorAppearance: (_props$extensionNodeV = props.extensionNodeViewOptions) === null || _props$extensionNodeV === void 0 ? void 0 : _props$extensionNodeV.appearance,
317
318
  pluginInjectionApi: props.pluginInjectionApi,
318
319
  macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags,
@@ -325,11 +326,12 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
325
326
  }(ReactNodeView);
326
327
 
327
328
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
328
- export default function ExtensionNodeView(portalProviderAPI, eventDispatcher, providerFactory, extensionHandlers, extensionNodeViewOptions, pluginInjectionApi, macroInteractionDesignFeatureFlags, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, rendererExtensionHandlers, intl) {
329
+ export default function ExtensionNodeView(portalProviderAPI, eventDispatcher, providerFactory, extensionHandlers, extensionLoadingHandlers, extensionNodeViewOptions, pluginInjectionApi, macroInteractionDesignFeatureFlags, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, rendererExtensionHandlers, intl) {
329
330
  return function (node, view, getPos) {
330
331
  return new ExtensionNode(node, view, getPos, portalProviderAPI, eventDispatcher, {
331
332
  providerFactory: providerFactory,
332
333
  extensionHandlers: extensionHandlers,
334
+ extensionLoadingHandlers: extensionLoadingHandlers,
333
335
  extensionNodeViewOptions: extensionNodeViewOptions,
334
336
  pluginInjectionApi: pluginInjectionApi,
335
337
  macroInteractionDesignFeatureFlags: macroInteractionDesignFeatureFlags,
@@ -109,6 +109,9 @@ function isUnknownConfluenceMacroWithBody(extensionNode) {
109
109
  function ExtensionLoading(props) {
110
110
  var intl = useIntl();
111
111
  var extensionNode = props.node;
112
+ if (!props.error && !props.timedOut && props.loadingFallback) {
113
+ return /*#__PURE__*/React.createElement(React.Fragment, null, props.loadingFallback);
114
+ }
112
115
  if (props.error || props.timedOut) {
113
116
  // eslint-disable-next-line no-console
114
117
  console.error('Error rendering extension', props.error);
@@ -20,7 +20,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
20
20
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
21
21
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
22
22
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
23
- var packageVersion = "116.24.2";
23
+ var packageVersion = "116.24.4";
24
24
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
25
25
  // Remove URL as it has UGC
26
26
  // Ignored via go/ees007
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import { fg } from '@atlaskit/platform-feature-flags';
22
22
  import Layer from '../Layer';
23
23
  var packageName = "@atlaskit/editor-common";
24
- var packageVersion = "116.24.2";
24
+ var packageVersion = "116.24.4";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -5,13 +5,14 @@
5
5
  import { type CSSProperties } from 'react';
6
6
  import { jsx } from '@emotion/react';
7
7
  import type { ExtensionsPluginInjectionAPI } from '../../types';
8
- export declare const getShouldShowBodiedMacroLabel: (isBodiedMacro: boolean | undefined, isNodeHovered: boolean | undefined, showLivePagesBodiedMacrosRendererView: boolean | undefined, showBodiedExtensionRendererView: boolean | undefined, showUpdatedLivePages1PBodiedExtensionUI: boolean | undefined) => boolean | undefined;
9
8
  type ExtensionLabelProps = {
10
9
  customContainerStyles?: CSSProperties;
11
10
  extensionName: string;
12
11
  isBodiedMacro?: boolean;
12
+ isMultiBodiedMacro?: boolean;
13
13
  isNodeHovered?: boolean;
14
14
  isNodeNested?: boolean;
15
+ isNodeSelected?: boolean;
15
16
  pluginInjectionApi?: ExtensionsPluginInjectionAPI;
16
17
  setIsNodeHovered?: (isHovered: boolean) => void;
17
18
  showBodiedExtensionRendererView?: boolean;
@@ -19,5 +20,5 @@ type ExtensionLabelProps = {
19
20
  showUpdatedLivePages1PBodiedExtensionUI?: boolean;
20
21
  text: string;
21
22
  };
22
- export declare const ExtensionLabel: ({ text, extensionName, customContainerStyles, isNodeNested, setIsNodeHovered, isBodiedMacro, showUpdatedLivePages1PBodiedExtensionUI, showLivePagesBodiedMacrosRendererView, showBodiedExtensionRendererView, pluginInjectionApi: _pluginInjectionApi, }: ExtensionLabelProps) => jsx.JSX.Element;
23
+ export declare const ExtensionLabel: ({ text, extensionName, customContainerStyles, isNodeNested, isNodeSelected, setIsNodeHovered, isBodiedMacro, showUpdatedLivePages1PBodiedExtensionUI, showLivePagesBodiedMacrosRendererView, showBodiedExtensionRendererView, pluginInjectionApi: _pluginInjectionApi, isMultiBodiedMacro, }: ExtensionLabelProps) => jsx.JSX.Element;
23
24
  export {};
@@ -11,6 +11,7 @@ type LozengeComponentProps = {
11
11
  customContainerStyles?: CSSProperties;
12
12
  extensionName: string;
13
13
  isBodiedMacro?: boolean;
14
+ isMultiBodiedMacro?: boolean;
14
15
  isNodeHovered?: boolean;
15
16
  isNodeNested?: boolean;
16
17
  isNodeSelected?: boolean;
@@ -26,5 +27,5 @@ type LozengeComponentProps = {
26
27
  showUpdatedLivePages1PBodiedExtensionUI?: boolean;
27
28
  title: string;
28
29
  };
29
- export declare const LozengeComponent: ({ lozengeData, extensionName, title, params, renderImage, showMacroInteractionDesignUpdates, customContainerStyles, isNodeHovered, isNodeNested, setIsNodeHovered, isBodiedMacro, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, showBodiedExtensionRendererView, setShowBodiedExtensionRendererView, pluginInjectionApi, }: LozengeComponentProps) => jsx.JSX.Element;
30
+ export declare const LozengeComponent: ({ lozengeData, extensionName, title, params, renderImage, showMacroInteractionDesignUpdates, customContainerStyles, isNodeHovered, isNodeNested, isNodeSelected, setIsNodeHovered, isBodiedMacro, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, showBodiedExtensionRendererView, setShowBodiedExtensionRendererView, pluginInjectionApi, isMultiBodiedMacro, }: LozengeComponentProps) => jsx.JSX.Element;
30
31
  export {};
@@ -10,6 +10,7 @@ import type { ExtensionsPluginInjectionAPI } from '../../types';
10
10
  export interface Props {
11
11
  customContainerStyles?: CSSProperties;
12
12
  isBodiedMacro?: boolean;
13
+ isMultiBodiedMacro?: boolean;
13
14
  isNodeHovered?: boolean;
14
15
  isNodeNested?: boolean;
15
16
  isNodeSelected?: boolean;
@@ -13,6 +13,7 @@ export interface Props {
13
13
  editorView: EditorView;
14
14
  eventDispatcher?: EventDispatcher;
15
15
  extensionHandlers: ExtensionHandlers;
16
+ extensionLoadingHandlers?: ExtensionHandlers;
16
17
  getPos: ProsemirrorGetPosHandler;
17
18
  handleContentDOMRef: (node: HTMLElement | null) => void;
18
19
  macroInteractionDesignFeatureFlags?: MacroInteractionDesignFeatureFlags;
@@ -12,6 +12,7 @@ export interface Props {
12
12
  editorView: EditorView;
13
13
  eventDispatcher?: EventDispatcher;
14
14
  extensionHandlers: ExtensionHandlers;
15
+ extensionLoadingHandlers?: ExtensionHandlers;
15
16
  extensionProvider?: Promise<ExtensionProvider>;
16
17
  getPos: ProsemirrorGetPosHandler;
17
18
  handleContentDOMRef: (node: HTMLElement | null) => void;