@atlaskit/editor-common 112.18.2 → 112.18.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 (34) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/extensibility/Extension/Extension/index.js +1 -2
  3. package/dist/cjs/extensibility/ExtensionNodeWrapper.js +2 -0
  4. package/dist/cjs/extensibility/extensionNodeView.js +112 -1
  5. package/dist/cjs/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +2 -6
  6. package/dist/cjs/monitoring/error.js +1 -1
  7. package/dist/cjs/node-anchor/node-anchor-provider.js +6 -12
  8. package/dist/cjs/react-node-view/index.js +6 -3
  9. package/dist/cjs/ui/DropList/index.js +1 -1
  10. package/dist/es2019/extensibility/Extension/Extension/index.js +2 -3
  11. package/dist/es2019/extensibility/ExtensionNodeWrapper.js +2 -0
  12. package/dist/es2019/extensibility/extensionNodeView.js +100 -0
  13. package/dist/es2019/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +3 -6
  14. package/dist/es2019/monitoring/error.js +1 -1
  15. package/dist/es2019/node-anchor/node-anchor-provider.js +6 -12
  16. package/dist/es2019/react-node-view/index.js +4 -2
  17. package/dist/es2019/ui/DropList/index.js +1 -1
  18. package/dist/esm/extensibility/Extension/Extension/index.js +2 -3
  19. package/dist/esm/extensibility/ExtensionNodeWrapper.js +2 -0
  20. package/dist/esm/extensibility/extensionNodeView.js +112 -1
  21. package/dist/esm/link/LinkPicker/HyperlinkAddToolbar/HyperlinkAddToolbar.js +3 -7
  22. package/dist/esm/monitoring/error.js +1 -1
  23. package/dist/esm/node-anchor/node-anchor-provider.js +6 -12
  24. package/dist/esm/react-node-view/index.js +6 -3
  25. package/dist/esm/ui/DropList/index.js +1 -1
  26. package/dist/types/analytics/types/ai-autocomplete-events.d.ts +1 -1
  27. package/dist/types/analytics/types/ai-streaming.d.ts +6 -0
  28. package/dist/types/extensibility/extensionNodeView.d.ts +30 -1
  29. package/dist/types/react-node-view/index.d.ts +1 -1
  30. package/dist/types-ts4.5/analytics/types/ai-autocomplete-events.d.ts +1 -1
  31. package/dist/types-ts4.5/analytics/types/ai-streaming.d.ts +6 -0
  32. package/dist/types-ts4.5/extensibility/extensionNodeView.d.ts +30 -1
  33. package/dist/types-ts4.5/react-node-view/index.d.ts +1 -1
  34. package/package.json +4 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 112.18.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`d1a0ee6dbcefd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d1a0ee6dbcefd) -
8
+ Clean up feature gate platform_editor_native_anchor_patch_2
9
+ - [`8ebeaa8fb64ac`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8ebeaa8fb64ac) -
10
+ Remove stale feature flag platform_editor_link_picker_width_fix (final value: true)
11
+ - [`fb317c7b6ef38`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fb317c7b6ef38) -
12
+ Add Autocomplete Conclusion user flow
13
+ - Updated dependencies
14
+
15
+ ## 112.18.3
16
+
17
+ ### Patch Changes
18
+
19
+ - [`0a265af52321f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0a265af52321f) -
20
+ Clean up stale feature flag platform_editor_extension_styles, keeping the enabled code path
21
+ - [`3f798d9934a76`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3f798d9934a76) -
22
+ [ux] EDITOR-5487 skip react portal initial render when hydration for toc extension node view
23
+ - Updated dependencies
24
+
3
25
  ## 112.18.2
4
26
 
5
27
  ### Patch Changes
@@ -143,7 +143,6 @@ function ExtensionWithPluginState(props) {
143
143
  setIsNodeHovered(didHover);
144
144
  }
145
145
  };
146
- var extensionContentStyles = (0, _expValEquals.expValEquals)('platform_editor_extension_styles', 'isEnabled', true) ? _styles2.extensionContent : _styles2.content;
147
146
  return (0, _react2.jsx)(_react.Fragment, null, !showLegacyContentHeader && showMacroInteractionDesignUpdates && !isLivePageViewMode && (0, _react2.jsx)(_Lozenge.default, {
148
147
  isNodeSelected: isNodeSelected,
149
148
  isNodeHovered: isNodeHovered,
@@ -218,7 +217,7 @@ function ExtensionWithPluginState(props) {
218
217
  "data-testid": "extension-content"
219
218
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
220
219
  ,
221
- css: extensionContentStyles
220
+ css: _styles2.extensionContent
222
221
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
223
222
  ,
224
223
  className: contentClassNames
@@ -78,7 +78,9 @@ var ExtensionNodeWrapper = exports.ExtensionNodeWrapper = function ExtensionNode
78
78
  relative: showMacroInteractionDesignUpdates
79
79
  });
80
80
  return (0, _react2.jsx)("span", {
81
+ "data-testId": "extension-node-wrapper"
81
82
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
83
+ ,
82
84
  className: wrapperClassNames,
83
85
  css: [styles, (0, _expValEquals.expValEquals)('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles]
84
86
  }, children, nodeType === 'inlineExtension' && _whitespace.ZERO_WIDTH_SPACE);
@@ -12,9 +12,11 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
12
12
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
13
13
  var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
14
14
  var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
15
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
16
  var _react = _interopRequireDefault(require("react"));
16
17
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
18
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
19
+ var _coreUtils = require("../core-utils");
18
20
  var _reactNodeView = _interopRequireDefault(require("../react-node-view"));
19
21
  var _Extension = require("./Extension");
20
22
  var _ExtensionNodeWrapper = require("./ExtensionNodeWrapper");
@@ -28,8 +30,23 @@ function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototyp
28
30
  // project whilst investigating block nodes. We will revisit the Extension node view there too.
29
31
  var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
30
32
  function ExtensionNode() {
33
+ var _this;
31
34
  (0, _classCallCheck2.default)(this, ExtensionNode);
32
- return _callSuper(this, ExtensionNode, arguments);
35
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
36
+ args[_key] = arguments[_key];
37
+ }
38
+ _this = _callSuper(this, ExtensionNode, [].concat(args));
39
+ /**
40
+ * Track whether we found and are reusing SSR'd DOM.
41
+ * When true, we skip React Portal rendering on first init to preserve SSR content.
42
+ */
43
+ (0, _defineProperty2.default)(_this, "didReuseSsrDom", false);
44
+ /**
45
+ * Track whether this is the first init call.
46
+ * SSR content preservation only happens on the very first init.
47
+ */
48
+ (0, _defineProperty2.default)(_this, "isFirstInit", true);
49
+ return _this;
33
50
  }
34
51
  (0, _inherits2.default)(ExtensionNode, _ReactNodeView);
35
52
  return (0, _createClass2.default)(ExtensionNode, [{
@@ -47,6 +64,15 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
47
64
  key: "createDomRef",
48
65
  value: function createDomRef() {
49
66
  if (!(0, _platformFeatureFlags.fg)('confluence_connect_macro_preset_height')) {
67
+ // Try to reuse SSR'd DOM node on first init only
68
+ // This preserves SSR content and avoids TTVC mutations during hydration
69
+ if (!(0, _coreUtils.isSSR)() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && (0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
70
+ var ssrElement = this.findSSRElement();
71
+ if (ssrElement) {
72
+ this.didReuseSsrDom = true;
73
+ return ssrElement;
74
+ }
75
+ }
50
76
  return _superPropGet(ExtensionNode, "createDomRef", this, 3)([]);
51
77
  }
52
78
  if (!this.node.isInline) {
@@ -62,6 +88,83 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
62
88
  return htmlElement;
63
89
  }
64
90
 
91
+ /**
92
+ * Cache for SSR element lookup to avoid repeated DOM queries.
93
+ * undefined = not yet searched, null = searched but not found, HTMLElement = found
94
+ */
95
+ }, {
96
+ key: "findSSRElement",
97
+ value:
98
+ /**
99
+ * Attempts to find an existing SSR'd DOM element for this extension node by extensionKey and localId
100
+ * which should uniquely identify the
101
+ * extension node within the editor content.
102
+ *
103
+ * @returns The SSR'd element if found, otherwise null
104
+ */
105
+ function findSSRElement() {
106
+ if (this.cachedSsrElement !== undefined) {
107
+ return this.cachedSsrElement || null;
108
+ }
109
+ var extensionKey = this.node.attrs.extensionKey;
110
+ var localId = this.node.attrs.localId;
111
+ var editorDom = this.view.dom;
112
+ if (extensionKey && localId) {
113
+ var selector = "[extensionkey=\"".concat(extensionKey, "\"][localid=\"").concat(localId, "\"]");
114
+ var element = editorDom.querySelector(selector);
115
+ if (element && element instanceof HTMLElement) {
116
+ this.cachedSsrElement = element;
117
+ return element;
118
+ }
119
+ }
120
+ this.cachedSsrElement = null;
121
+ return null;
122
+ }
123
+
124
+ /**
125
+ * Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
126
+ * This preserves the SSR content without React unnecessarily re-rendering it.
127
+ */
128
+ }, {
129
+ key: "init",
130
+ value: function init() {
131
+ if (!(0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
132
+ _superPropGet(ExtensionNode, "init", this, 3)([]);
133
+ } else {
134
+ if (!(0, _coreUtils.isSSR)() && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc') {
135
+ var ssrElement = this.findSSRElement();
136
+ var shouldSkipInitRender = ssrElement !== null;
137
+ _superPropGet(ExtensionNode, "init", this, 3)([shouldSkipInitRender]);
138
+ if (shouldSkipInitRender) {
139
+ this.isFirstInit = false;
140
+ }
141
+ } else {
142
+ _superPropGet(ExtensionNode, "init", this, 3)([]);
143
+ }
144
+ }
145
+ return this;
146
+ }
147
+ }, {
148
+ key: "update",
149
+ value: function update(node, decorations, _innerDecorations) {
150
+ var validUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {
151
+ return true;
152
+ };
153
+ // Remove extensionNodeWrapper aka span.relative if we previously reused SSR DOM
154
+ // control is back to React afterwards
155
+ if (this.didReuseSsrDom && (0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
156
+ var ssrElement = this.findSSRElement();
157
+ if (ssrElement) {
158
+ var extensionNodeWrapper = ssrElement.querySelector('[data-testId="extension-node-wrapper"]');
159
+ if (extensionNodeWrapper) {
160
+ extensionNodeWrapper.remove();
161
+ }
162
+ this.didReuseSsrDom = false;
163
+ }
164
+ }
165
+ return _superPropGet(ExtensionNode, "update", this, 3)([node, decorations, _innerDecorations, validUpdate]);
166
+ }
167
+
65
168
  /**
66
169
  * When interacting with input elements inside an extension's body, the events
67
170
  * bubble up to the editor and get handled by it. This almost always gets in the way
@@ -85,6 +188,9 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
85
188
  if (this.node.isInline) {
86
189
  return;
87
190
  }
191
+ if (this.didReuseSsrDom) {
192
+ return;
193
+ }
88
194
  var contentDomWrapper = document.createElement('div');
89
195
  contentDomWrapper.className = "".concat(this.node.type.name, "-content-dom-wrapper");
90
196
  var isBodiedExtension = this.node.type.name === 'bodiedExtension';
@@ -112,6 +218,11 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
112
218
  key: "render",
113
219
  value: function render(props, forwardRef) {
114
220
  var _props$extensionNodeV;
221
+ // If we reused SSR'd DOM on first init, don't render React Portal
222
+ // The SSR content is already perfect and doesn't need re-rendering
223
+ if (this.didReuseSsrDom && this.isFirstInit) {
224
+ return null;
225
+ }
115
226
  return /*#__PURE__*/_react.default.createElement(_ExtensionNodeWrapper.ExtensionNodeWrapper, {
116
227
  nodeType: this.node.type.name,
117
228
  macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags
@@ -26,7 +26,6 @@ var _adfSchema = require("@atlaskit/adf-schema");
26
26
  var _withAnalyticsEvents = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsEvents"));
27
27
  var _ = _interopRequireDefault(require("@atlaskit/icon-object/glyph/page/16"));
28
28
  var _crossCircle = _interopRequireDefault(require("@atlaskit/icon/core/cross-circle"));
29
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
30
29
  var _primitives = require("@atlaskit/primitives");
31
30
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
32
31
  var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
@@ -876,9 +875,7 @@ var HyperlinkLinkAddToolbar = exports.HyperlinkLinkAddToolbar = /*#__PURE__*/fun
876
875
  selectedIndex = _this$state1.selectedIndex,
877
876
  displayUrl = _this$state1.displayUrl,
878
877
  displayText = _this$state1.displayText;
879
- var _this$props6 = this.props,
880
- formatMessage = _this$props6.intl.formatMessage,
881
- activityProvider = _this$props6.activityProvider;
878
+ var formatMessage = this.props.intl.formatMessage;
882
879
  var formatClearLinkText = formatMessage(messages.clearLink);
883
880
  var screenReaderDescriptionId = 'search-recent-links-field-description';
884
881
  var linkSearchListId = 'hyperlink-search-list';
@@ -890,7 +887,6 @@ var HyperlinkLinkAddToolbar = exports.HyperlinkLinkAddToolbar = /*#__PURE__*/fun
890
887
  // as the Aria design pattern for combobox does not work in this case
891
888
  // for details: https://a11y-internal.atlassian.net/browse/AK-740
892
889
  var screenReaderText = browser.safari && this.getScreenReaderText();
893
- var containerWidth = (0, _platformFeatureFlags.fg)('platform_editor_link_picker_width_fix') ? _ToolbarComponents.narrowContainerWidth : !!activityProvider && _ToolbarComponents.containerWithProvider;
894
890
  var hyperlinkElement = (0, _react2.jsx)("div", {
895
891
  "aria-label": formatMessage(messages.hyperlinkAriaLabel)
896
892
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -899,7 +895,7 @@ var HyperlinkLinkAddToolbar = exports.HyperlinkLinkAddToolbar = /*#__PURE__*/fun
899
895
  "data-testid": "hyperlink-add-toolbar"
900
896
  }, (0, _react2.jsx)("div", {
901
897
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
902
- css: [_ToolbarComponents.container, containerWidth, containerPadding],
898
+ css: [_ToolbarComponents.container, _ToolbarComponents.narrowContainerWidth, containerPadding],
903
899
  ref: this.wrapperRef
904
900
  }, (0, _react2.jsx)("label", {
905
901
  htmlFor: linkSearchInputId,
@@ -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 = "112.18.1";
22
+ var packageVersion = "112.18.3";
23
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
24
24
  // Remove URL as it has UGC
25
25
  // Ignored via go/ees007
@@ -8,7 +8,6 @@ exports.getNodeIdProvider = exports.NodeAnchorProvider = void 0;
8
8
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
9
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
12
11
  var _expVal = require("@atlaskit/tmp-editor-statsig/expVal");
13
12
  var _utils = require("../utils");
14
13
  var _dynamicBitArray = require("./dynamic-bit-array");
@@ -199,16 +198,11 @@ var isLimitedModeEnabled = function isLimitedModeEnabled(editorView) {
199
198
  // This allows access to the node ids anywhere.
200
199
  var getNodeIdProvider = exports.getNodeIdProvider = function getNodeIdProvider(editorView) {
201
200
  if (!nodeIdProviderMap.has(editorView)) {
202
- if ((0, _platformFeatureFlags.fg)('platform_editor_native_anchor_patch_2')) {
203
- // if the limited mode flag is on, enable limited mode based on the threshold
204
- // only for the first time
205
- var limitedMode = isLimitedModeEnabled(editorView);
206
- var isEmptyDoc = (0, _utils.isEmptyDocument)(editorView.state.doc);
207
- var _provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
208
- nodeIdProviderMap.set(editorView, _provider);
209
- return _provider;
210
- }
211
- var provider = new NodeAnchorProvider();
201
+ // if the limited mode flag is on, enable limited mode based on the threshold
202
+ // only for the first time
203
+ var limitedMode = isLimitedModeEnabled(editorView);
204
+ var isEmptyDoc = (0, _utils.isEmptyDocument)(editorView.state.doc);
205
+ var provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
212
206
  nodeIdProviderMap.set(editorView, provider);
213
207
  return provider;
214
208
  }
@@ -217,7 +211,7 @@ var getNodeIdProvider = exports.getNodeIdProvider = function getNodeIdProvider(e
217
211
  // in some cases we need to re-check limited mode state
218
212
  // Confluence editor can start with an empty doc and then load content later
219
213
  // so we need to check first time from an empty doc to a non-empty doc
220
- if (nodeIdProvider.isEmptyDoc() && !(0, _utils.isEmptyDocument)(editorView.state.doc) && (0, _platformFeatureFlags.fg)('platform_editor_native_anchor_patch_2')) {
214
+ if (nodeIdProvider.isEmptyDoc() && !(0, _utils.isEmptyDocument)(editorView.state.doc)) {
221
215
  // set empty doc to false regardless of limited mode state
222
216
  nodeIdProvider.setEmptyDoc(false);
223
217
  if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
@@ -79,6 +79,7 @@ var ReactNodeView = exports.default = /*#__PURE__*/function () {
79
79
  key: "init",
80
80
  value: function init() {
81
81
  var _this2 = this;
82
+ var shouldSkipInitRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
82
83
  this.domRef = this.createDomRef();
83
84
  this.setDomAttrs(this.node, this.domRef);
84
85
  var _ref = this.getContentDOM() || {
@@ -105,9 +106,11 @@ var ReactNodeView = exports.default = /*#__PURE__*/function () {
105
106
  trackingEnabled && (0, _utils.startMeasureReactNodeViewRendered)({
106
107
  nodeTypeName: this.node.type.name
107
108
  });
108
- this.renderReactComponent(function () {
109
- return _this2.render(_this2.reactComponentProps, _this2.handleRef);
110
- });
109
+ if (!shouldSkipInitRender) {
110
+ this.renderReactComponent(function () {
111
+ return _this2.render(_this2.reactComponentProps, _this2.handleRef);
112
+ });
113
+ }
111
114
  trackingEnabled && (0, _utils.stopMeasureReactNodeViewRendered)({
112
115
  nodeTypeName: this.node.type.name,
113
116
  dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
@@ -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 = "112.18.1";
27
+ var packageVersion = "112.18.3";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -18,7 +18,7 @@ import { shouldExtensionBreakout } from '../../utils/should-extension-breakout';
18
18
  import ExtensionLozenge from '../Lozenge';
19
19
  import { overlay } from '../styles';
20
20
  import { isEmptyBodiedMacro } from './extension-utils';
21
- import { content, contentWrapper, extensionContent, header, overflowWrapperStyles, widerLayoutClassName, wrapperStyleInheritedCursor } from './styles';
21
+ import { contentWrapper, extensionContent, header, overflowWrapperStyles, widerLayoutClassName, wrapperStyleInheritedCursor } from './styles';
22
22
  const hoverStyles = css({
23
23
  '&:hover': {
24
24
  boxShadow: `0 0 0 1px ${"var(--ds-border-input, #8C8F97)"}`
@@ -143,7 +143,6 @@ function ExtensionWithPluginState(props) {
143
143
  setIsNodeHovered(didHover);
144
144
  }
145
145
  };
146
- const extensionContentStyles = expValEquals('platform_editor_extension_styles', 'isEnabled', true) ? extensionContent : content;
147
146
  return jsx(Fragment, null, !showLegacyContentHeader && showMacroInteractionDesignUpdates && !isLivePageViewMode && jsx(ExtensionLozenge, {
148
147
  isNodeSelected: isNodeSelected,
149
148
  isNodeHovered: isNodeHovered,
@@ -214,7 +213,7 @@ function ExtensionWithPluginState(props) {
214
213
  "data-testid": "extension-content"
215
214
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
216
215
  ,
217
- css: extensionContentStyles
216
+ css: extensionContent
218
217
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
219
218
  ,
220
219
  className: contentClassNames
@@ -72,7 +72,9 @@ export const ExtensionNodeWrapper = ({
72
72
  relative: showMacroInteractionDesignUpdates
73
73
  });
74
74
  return jsx("span", {
75
+ "data-testId": "extension-node-wrapper"
75
76
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
77
+ ,
76
78
  className: wrapperClassNames,
77
79
  css: [styles, expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles]
78
80
  }, children, nodeType === 'inlineExtension' && ZERO_WIDTH_SPACE);
@@ -1,6 +1,8 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import React from 'react';
2
3
  import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
+ import { isSSR } from '../core-utils';
4
6
  import ReactNodeView from '../react-node-view';
5
7
  import { Extension } from './Extension';
6
8
  import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
@@ -10,6 +12,19 @@ import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
10
12
  // The ReactNodeView api will be visited in the second phase of the selections
11
13
  // project whilst investigating block nodes. We will revisit the Extension node view there too.
12
14
  export class ExtensionNode extends ReactNodeView {
15
+ constructor(...args) {
16
+ super(...args);
17
+ /**
18
+ * Track whether we found and are reusing SSR'd DOM.
19
+ * When true, we skip React Portal rendering on first init to preserve SSR content.
20
+ */
21
+ _defineProperty(this, "didReuseSsrDom", false);
22
+ /**
23
+ * Track whether this is the first init call.
24
+ * SSR content preservation only happens on the very first init.
25
+ */
26
+ _defineProperty(this, "isFirstInit", true);
27
+ }
13
28
  ignoreMutation(mutation) {
14
29
  // Extensions can perform async operations that will change the DOM.
15
30
  // To avoid having their tree rebuilt, we need to ignore the mutation
@@ -21,6 +36,15 @@ export class ExtensionNode extends ReactNodeView {
21
36
  // Reserve height by setting a minimum height for the extension node view element
22
37
  createDomRef() {
23
38
  if (!fg('confluence_connect_macro_preset_height')) {
39
+ // Try to reuse SSR'd DOM node on first init only
40
+ // This preserves SSR content and avoids TTVC mutations during hydration
41
+ if (!isSSR() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
42
+ const ssrElement = this.findSSRElement();
43
+ if (ssrElement) {
44
+ this.didReuseSsrDom = true;
45
+ return ssrElement;
46
+ }
47
+ }
24
48
  return super.createDomRef();
25
49
  }
26
50
  if (!this.node.isInline) {
@@ -36,6 +60,74 @@ export class ExtensionNode extends ReactNodeView {
36
60
  return htmlElement;
37
61
  }
38
62
 
63
+ /**
64
+ * Cache for SSR element lookup to avoid repeated DOM queries.
65
+ * undefined = not yet searched, null = searched but not found, HTMLElement = found
66
+ */
67
+
68
+ /**
69
+ * Attempts to find an existing SSR'd DOM element for this extension node by extensionKey and localId
70
+ * which should uniquely identify the
71
+ * extension node within the editor content.
72
+ *
73
+ * @returns The SSR'd element if found, otherwise null
74
+ */
75
+ findSSRElement() {
76
+ if (this.cachedSsrElement !== undefined) {
77
+ return this.cachedSsrElement || null;
78
+ }
79
+ const extensionKey = this.node.attrs.extensionKey;
80
+ const localId = this.node.attrs.localId;
81
+ const editorDom = this.view.dom;
82
+ if (extensionKey && localId) {
83
+ const selector = `[extensionkey="${extensionKey}"][localid="${localId}"]`;
84
+ const element = editorDom.querySelector(selector);
85
+ if (element && element instanceof HTMLElement) {
86
+ this.cachedSsrElement = element;
87
+ return element;
88
+ }
89
+ }
90
+ this.cachedSsrElement = null;
91
+ return null;
92
+ }
93
+
94
+ /**
95
+ * Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
96
+ * This preserves the SSR content without React unnecessarily re-rendering it.
97
+ */
98
+ init() {
99
+ if (!expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
100
+ super.init();
101
+ } else {
102
+ if (!isSSR() && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc') {
103
+ const ssrElement = this.findSSRElement();
104
+ const shouldSkipInitRender = ssrElement !== null;
105
+ super.init(shouldSkipInitRender);
106
+ if (shouldSkipInitRender) {
107
+ this.isFirstInit = false;
108
+ }
109
+ } else {
110
+ super.init();
111
+ }
112
+ }
113
+ return this;
114
+ }
115
+ update(node, decorations, _innerDecorations, validUpdate = () => true) {
116
+ // Remove extensionNodeWrapper aka span.relative if we previously reused SSR DOM
117
+ // control is back to React afterwards
118
+ if (this.didReuseSsrDom && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
119
+ const ssrElement = this.findSSRElement();
120
+ if (ssrElement) {
121
+ const extensionNodeWrapper = ssrElement.querySelector('[data-testId="extension-node-wrapper"]');
122
+ if (extensionNodeWrapper) {
123
+ extensionNodeWrapper.remove();
124
+ }
125
+ this.didReuseSsrDom = false;
126
+ }
127
+ }
128
+ return super.update(node, decorations, _innerDecorations, validUpdate);
129
+ }
130
+
39
131
  /**
40
132
  * When interacting with input elements inside an extension's body, the events
41
133
  * bubble up to the editor and get handled by it. This almost always gets in the way
@@ -55,6 +147,9 @@ export class ExtensionNode extends ReactNodeView {
55
147
  if (this.node.isInline) {
56
148
  return;
57
149
  }
150
+ if (this.didReuseSsrDom) {
151
+ return;
152
+ }
58
153
  const contentDomWrapper = document.createElement('div');
59
154
  contentDomWrapper.className = `${this.node.type.name}-content-dom-wrapper`;
60
155
  const isBodiedExtension = this.node.type.name === 'bodiedExtension';
@@ -80,6 +175,11 @@ export class ExtensionNode extends ReactNodeView {
80
175
  }
81
176
  render(props, forwardRef) {
82
177
  var _props$extensionNodeV;
178
+ // If we reused SSR'd DOM on first init, don't render React Portal
179
+ // The SSR content is already perfect and doesn't need re-rendering
180
+ if (this.didReuseSsrDom && this.isFirstInit) {
181
+ return null;
182
+ }
83
183
  return /*#__PURE__*/React.createElement(ExtensionNodeWrapper, {
84
184
  nodeType: this.node.type.name,
85
185
  macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags
@@ -17,7 +17,6 @@ import { isSafeUrl } from '@atlaskit/adf-schema';
17
17
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
18
18
  import Page16Icon from '@atlaskit/icon-object/glyph/page/16';
19
19
  import CrossCircleIcon from '@atlaskit/icon/core/cross-circle';
20
- import { fg } from '@atlaskit/platform-feature-flags';
21
20
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
22
21
  import { Pressable, xcss } from '@atlaskit/primitives';
23
22
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -27,7 +26,7 @@ import { Announcer, PanelTextInput } from '../../../ui';
27
26
  import { normalizeUrl } from '../../../utils';
28
27
  import { browser as browserLegacy, getBrowserInfo } from '../../../utils/browser';
29
28
  import LinkSearchList from '../../LinkSearch/LinkSearchList';
30
- import { container, containerWithProvider, narrowContainerWidth, inputWrapper } from '../../LinkSearch/ToolbarComponents';
29
+ import { container, narrowContainerWidth, inputWrapper } from '../../LinkSearch/ToolbarComponents';
31
30
  import { transformTimeStamp } from '../../LinkSearch/transformTimeStamp';
32
31
  import { filterUniqueItems, mapContentTypeToIcon, sha1, wordCount } from './utils';
33
32
 
@@ -729,8 +728,7 @@ export class HyperlinkLinkAddToolbar extends PureComponent {
729
728
  const {
730
729
  intl: {
731
730
  formatMessage
732
- },
733
- activityProvider
731
+ }
734
732
  } = this.props;
735
733
  const formatClearLinkText = formatMessage(messages.clearLink);
736
734
  const screenReaderDescriptionId = 'search-recent-links-field-description';
@@ -743,7 +741,6 @@ export class HyperlinkLinkAddToolbar extends PureComponent {
743
741
  // as the Aria design pattern for combobox does not work in this case
744
742
  // for details: https://a11y-internal.atlassian.net/browse/AK-740
745
743
  const screenReaderText = browser.safari && this.getScreenReaderText();
746
- const containerWidth = fg('platform_editor_link_picker_width_fix') ? narrowContainerWidth : !!activityProvider && containerWithProvider;
747
744
  const hyperlinkElement = jsx("div", {
748
745
  "aria-label": formatMessage(messages.hyperlinkAriaLabel)
749
746
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -752,7 +749,7 @@ export class HyperlinkLinkAddToolbar extends PureComponent {
752
749
  "data-testid": "hyperlink-add-toolbar"
753
750
  }, jsx("div", {
754
751
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
755
- css: [container, containerWidth, containerPadding],
752
+ css: [container, narrowContainerWidth, containerPadding],
756
753
  ref: this.wrapperRef
757
754
  }, jsx("label", {
758
755
  htmlFor: linkSearchInputId,
@@ -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 = "112.18.1";
7
+ const packageVersion = "112.18.3";
8
8
  const sanitiseSentryEvents = (data, _hint) => {
9
9
  // Remove URL as it has UGC
10
10
  // Ignored via go/ees007
@@ -1,5 +1,4 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { fg } from '@atlaskit/platform-feature-flags';
3
2
  import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
4
3
  import { isEmptyDocument } from '../utils';
5
4
  import { DynamicBitArray } from './dynamic-bit-array';
@@ -173,16 +172,11 @@ const isLimitedModeEnabled = editorView => {
173
172
  // This allows access to the node ids anywhere.
174
173
  export const getNodeIdProvider = editorView => {
175
174
  if (!nodeIdProviderMap.has(editorView)) {
176
- if (fg('platform_editor_native_anchor_patch_2')) {
177
- // if the limited mode flag is on, enable limited mode based on the threshold
178
- // only for the first time
179
- const limitedMode = isLimitedModeEnabled(editorView);
180
- const isEmptyDoc = isEmptyDocument(editorView.state.doc);
181
- const provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
182
- nodeIdProviderMap.set(editorView, provider);
183
- return provider;
184
- }
185
- const provider = new NodeAnchorProvider();
175
+ // if the limited mode flag is on, enable limited mode based on the threshold
176
+ // only for the first time
177
+ const limitedMode = isLimitedModeEnabled(editorView);
178
+ const isEmptyDoc = isEmptyDocument(editorView.state.doc);
179
+ const provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
186
180
  nodeIdProviderMap.set(editorView, provider);
187
181
  return provider;
188
182
  }
@@ -191,7 +185,7 @@ export const getNodeIdProvider = editorView => {
191
185
  // in some cases we need to re-check limited mode state
192
186
  // Confluence editor can start with an empty doc and then load content later
193
187
  // so we need to check first time from an empty doc to a non-empty doc
194
- if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc) && fg('platform_editor_native_anchor_patch_2')) {
188
+ if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc)) {
195
189
  // set empty doc to false regardless of limited mode state
196
190
  nodeIdProvider.setEmptyDoc(false);
197
191
  if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
@@ -51,7 +51,7 @@ export default class ReactNodeView {
51
51
  * constructor, which leads to some methods being undefined during the
52
52
  * first render.
53
53
  */
54
- init() {
54
+ init(shouldSkipInitRender = false) {
55
55
  this.domRef = this.createDomRef();
56
56
  this.setDomAttrs(this.node, this.domRef);
57
57
  const {
@@ -80,7 +80,9 @@ export default class ReactNodeView {
80
80
  trackingEnabled && startMeasureReactNodeViewRendered({
81
81
  nodeTypeName: this.node.type.name
82
82
  });
83
- this.renderReactComponent(() => this.render(this.reactComponentProps, this.handleRef));
83
+ if (!shouldSkipInitRender) {
84
+ this.renderReactComponent(() => this.render(this.reactComponentProps, this.handleRef));
85
+ }
84
86
  trackingEnabled && stopMeasureReactNodeViewRendered({
85
87
  nodeTypeName: this.node.type.name,
86
88
  dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
@@ -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 = "112.18.1";
17
+ const packageVersion = "112.18.3";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -23,7 +23,7 @@ import { shouldExtensionBreakout } from '../../utils/should-extension-breakout';
23
23
  import ExtensionLozenge from '../Lozenge';
24
24
  import { overlay } from '../styles';
25
25
  import { isEmptyBodiedMacro } from './extension-utils';
26
- import { content, contentWrapper, extensionContent, header, overflowWrapperStyles, widerLayoutClassName, wrapperStyleInheritedCursor } from './styles';
26
+ import { contentWrapper, extensionContent, header, overflowWrapperStyles, widerLayoutClassName, wrapperStyleInheritedCursor } from './styles';
27
27
  var hoverStyles = css({
28
28
  '&:hover': {
29
29
  boxShadow: "0 0 0 1px ".concat("var(--ds-border-input, #8C8F97)")
@@ -136,7 +136,6 @@ function ExtensionWithPluginState(props) {
136
136
  setIsNodeHovered(didHover);
137
137
  }
138
138
  };
139
- var extensionContentStyles = expValEquals('platform_editor_extension_styles', 'isEnabled', true) ? extensionContent : content;
140
139
  return jsx(Fragment, null, !showLegacyContentHeader && showMacroInteractionDesignUpdates && !isLivePageViewMode && jsx(ExtensionLozenge, {
141
140
  isNodeSelected: isNodeSelected,
142
141
  isNodeHovered: isNodeHovered,
@@ -211,7 +210,7 @@ function ExtensionWithPluginState(props) {
211
210
  "data-testid": "extension-content"
212
211
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
213
212
  ,
214
- css: extensionContentStyles
213
+ css: extensionContent
215
214
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
216
215
  ,
217
216
  className: contentClassNames
@@ -70,7 +70,9 @@ export var ExtensionNodeWrapper = function ExtensionNodeWrapper(_ref) {
70
70
  relative: showMacroInteractionDesignUpdates
71
71
  });
72
72
  return jsx("span", {
73
+ "data-testId": "extension-node-wrapper"
73
74
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
75
+ ,
74
76
  className: wrapperClassNames,
75
77
  css: [styles, expValEquals('cc_editor_ttvc_release_bundle_one', 'extensionHoverRefactor', true) && hoverStyles]
76
78
  }, children, nodeType === 'inlineExtension' && ZERO_WIDTH_SPACE);
@@ -4,12 +4,14 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
4
4
  import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
5
5
  import _get from "@babel/runtime/helpers/get";
6
6
  import _inherits from "@babel/runtime/helpers/inherits";
7
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
7
8
  function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
9
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
10
  function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
10
11
  import React from 'react';
11
12
  import { fg } from '@atlaskit/platform-feature-flags';
12
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
14
+ import { isSSR } from '../core-utils';
13
15
  import ReactNodeView from '../react-node-view';
14
16
  import { Extension } from './Extension';
15
17
  import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
@@ -20,8 +22,23 @@ import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
20
22
  // project whilst investigating block nodes. We will revisit the Extension node view there too.
21
23
  export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
22
24
  function ExtensionNode() {
25
+ var _this;
23
26
  _classCallCheck(this, ExtensionNode);
24
- return _callSuper(this, ExtensionNode, arguments);
27
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
28
+ args[_key] = arguments[_key];
29
+ }
30
+ _this = _callSuper(this, ExtensionNode, [].concat(args));
31
+ /**
32
+ * Track whether we found and are reusing SSR'd DOM.
33
+ * When true, we skip React Portal rendering on first init to preserve SSR content.
34
+ */
35
+ _defineProperty(_this, "didReuseSsrDom", false);
36
+ /**
37
+ * Track whether this is the first init call.
38
+ * SSR content preservation only happens on the very first init.
39
+ */
40
+ _defineProperty(_this, "isFirstInit", true);
41
+ return _this;
25
42
  }
26
43
  _inherits(ExtensionNode, _ReactNodeView);
27
44
  return _createClass(ExtensionNode, [{
@@ -39,6 +56,15 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
39
56
  key: "createDomRef",
40
57
  value: function createDomRef() {
41
58
  if (!fg('confluence_connect_macro_preset_height')) {
59
+ // Try to reuse SSR'd DOM node on first init only
60
+ // This preserves SSR content and avoids TTVC mutations during hydration
61
+ if (!isSSR() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
62
+ var ssrElement = this.findSSRElement();
63
+ if (ssrElement) {
64
+ this.didReuseSsrDom = true;
65
+ return ssrElement;
66
+ }
67
+ }
42
68
  return _superPropGet(ExtensionNode, "createDomRef", this, 3)([]);
43
69
  }
44
70
  if (!this.node.isInline) {
@@ -54,6 +80,83 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
54
80
  return htmlElement;
55
81
  }
56
82
 
83
+ /**
84
+ * Cache for SSR element lookup to avoid repeated DOM queries.
85
+ * undefined = not yet searched, null = searched but not found, HTMLElement = found
86
+ */
87
+ }, {
88
+ key: "findSSRElement",
89
+ value:
90
+ /**
91
+ * Attempts to find an existing SSR'd DOM element for this extension node by extensionKey and localId
92
+ * which should uniquely identify the
93
+ * extension node within the editor content.
94
+ *
95
+ * @returns The SSR'd element if found, otherwise null
96
+ */
97
+ function findSSRElement() {
98
+ if (this.cachedSsrElement !== undefined) {
99
+ return this.cachedSsrElement || null;
100
+ }
101
+ var extensionKey = this.node.attrs.extensionKey;
102
+ var localId = this.node.attrs.localId;
103
+ var editorDom = this.view.dom;
104
+ if (extensionKey && localId) {
105
+ var selector = "[extensionkey=\"".concat(extensionKey, "\"][localid=\"").concat(localId, "\"]");
106
+ var element = editorDom.querySelector(selector);
107
+ if (element && element instanceof HTMLElement) {
108
+ this.cachedSsrElement = element;
109
+ return element;
110
+ }
111
+ }
112
+ this.cachedSsrElement = null;
113
+ return null;
114
+ }
115
+
116
+ /**
117
+ * Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
118
+ * This preserves the SSR content without React unnecessarily re-rendering it.
119
+ */
120
+ }, {
121
+ key: "init",
122
+ value: function init() {
123
+ if (!expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
124
+ _superPropGet(ExtensionNode, "init", this, 3)([]);
125
+ } else {
126
+ if (!isSSR() && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc') {
127
+ var ssrElement = this.findSSRElement();
128
+ var shouldSkipInitRender = ssrElement !== null;
129
+ _superPropGet(ExtensionNode, "init", this, 3)([shouldSkipInitRender]);
130
+ if (shouldSkipInitRender) {
131
+ this.isFirstInit = false;
132
+ }
133
+ } else {
134
+ _superPropGet(ExtensionNode, "init", this, 3)([]);
135
+ }
136
+ }
137
+ return this;
138
+ }
139
+ }, {
140
+ key: "update",
141
+ value: function update(node, decorations, _innerDecorations) {
142
+ var validUpdate = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {
143
+ return true;
144
+ };
145
+ // Remove extensionNodeWrapper aka span.relative if we previously reused SSR DOM
146
+ // control is back to React afterwards
147
+ if (this.didReuseSsrDom && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
148
+ var ssrElement = this.findSSRElement();
149
+ if (ssrElement) {
150
+ var extensionNodeWrapper = ssrElement.querySelector('[data-testId="extension-node-wrapper"]');
151
+ if (extensionNodeWrapper) {
152
+ extensionNodeWrapper.remove();
153
+ }
154
+ this.didReuseSsrDom = false;
155
+ }
156
+ }
157
+ return _superPropGet(ExtensionNode, "update", this, 3)([node, decorations, _innerDecorations, validUpdate]);
158
+ }
159
+
57
160
  /**
58
161
  * When interacting with input elements inside an extension's body, the events
59
162
  * bubble up to the editor and get handled by it. This almost always gets in the way
@@ -77,6 +180,9 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
77
180
  if (this.node.isInline) {
78
181
  return;
79
182
  }
183
+ if (this.didReuseSsrDom) {
184
+ return;
185
+ }
80
186
  var contentDomWrapper = document.createElement('div');
81
187
  contentDomWrapper.className = "".concat(this.node.type.name, "-content-dom-wrapper");
82
188
  var isBodiedExtension = this.node.type.name === 'bodiedExtension';
@@ -104,6 +210,11 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
104
210
  key: "render",
105
211
  value: function render(props, forwardRef) {
106
212
  var _props$extensionNodeV;
213
+ // If we reused SSR'd DOM on first init, don't render React Portal
214
+ // The SSR content is already perfect and doesn't need re-rendering
215
+ if (this.didReuseSsrDom && this.isFirstInit) {
216
+ return null;
217
+ }
107
218
  return /*#__PURE__*/React.createElement(ExtensionNodeWrapper, {
108
219
  nodeType: this.node.type.name,
109
220
  macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags
@@ -28,7 +28,6 @@ import { isSafeUrl } from '@atlaskit/adf-schema';
28
28
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
29
29
  import Page16Icon from '@atlaskit/icon-object/glyph/page/16';
30
30
  import CrossCircleIcon from '@atlaskit/icon/core/cross-circle';
31
- import { fg } from '@atlaskit/platform-feature-flags';
32
31
  // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- to be migrated to @atlaskit/primitives/compiled – go/akcss
33
32
  import { Pressable, xcss } from '@atlaskit/primitives';
34
33
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -38,7 +37,7 @@ import { Announcer, PanelTextInput } from '../../../ui';
38
37
  import { normalizeUrl } from '../../../utils';
39
38
  import { browser as browserLegacy, getBrowserInfo } from '../../../utils/browser';
40
39
  import LinkSearchList from '../../LinkSearch/LinkSearchList';
41
- import { container, containerWithProvider, narrowContainerWidth, inputWrapper } from '../../LinkSearch/ToolbarComponents';
40
+ import { container, narrowContainerWidth, inputWrapper } from '../../LinkSearch/ToolbarComponents';
42
41
  import { transformTimeStamp } from '../../LinkSearch/transformTimeStamp';
43
42
  import { filterUniqueItems, mapContentTypeToIcon, sha1, wordCount } from './utils';
44
43
 
@@ -873,9 +872,7 @@ export var HyperlinkLinkAddToolbar = /*#__PURE__*/function (_PureComponent) {
873
872
  selectedIndex = _this$state1.selectedIndex,
874
873
  displayUrl = _this$state1.displayUrl,
875
874
  displayText = _this$state1.displayText;
876
- var _this$props6 = this.props,
877
- formatMessage = _this$props6.intl.formatMessage,
878
- activityProvider = _this$props6.activityProvider;
875
+ var formatMessage = this.props.intl.formatMessage;
879
876
  var formatClearLinkText = formatMessage(messages.clearLink);
880
877
  var screenReaderDescriptionId = 'search-recent-links-field-description';
881
878
  var linkSearchListId = 'hyperlink-search-list';
@@ -887,7 +884,6 @@ export var HyperlinkLinkAddToolbar = /*#__PURE__*/function (_PureComponent) {
887
884
  // as the Aria design pattern for combobox does not work in this case
888
885
  // for details: https://a11y-internal.atlassian.net/browse/AK-740
889
886
  var screenReaderText = browser.safari && this.getScreenReaderText();
890
- var containerWidth = fg('platform_editor_link_picker_width_fix') ? narrowContainerWidth : !!activityProvider && containerWithProvider;
891
887
  var hyperlinkElement = jsx("div", {
892
888
  "aria-label": formatMessage(messages.hyperlinkAriaLabel)
893
889
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -896,7 +892,7 @@ export var HyperlinkLinkAddToolbar = /*#__PURE__*/function (_PureComponent) {
896
892
  "data-testid": "hyperlink-add-toolbar"
897
893
  }, jsx("div", {
898
894
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
899
- css: [container, containerWidth, containerPadding],
895
+ css: [container, narrowContainerWidth, containerPadding],
900
896
  ref: this.wrapperRef
901
897
  }, jsx("label", {
902
898
  htmlFor: linkSearchInputId,
@@ -10,7 +10,7 @@ import { isFedRamp } from './environment';
10
10
  import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
11
11
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
12
12
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
13
- var packageVersion = "112.18.1";
13
+ var packageVersion = "112.18.3";
14
14
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
15
15
  // Remove URL as it has UGC
16
16
  // Ignored via go/ees007
@@ -1,7 +1,6 @@
1
1
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
2
  import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
- import { fg } from '@atlaskit/platform-feature-flags';
5
4
  import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
6
5
  import { isEmptyDocument } from '../utils';
7
6
  import { DynamicBitArray } from './dynamic-bit-array';
@@ -193,16 +192,11 @@ var isLimitedModeEnabled = function isLimitedModeEnabled(editorView) {
193
192
  // This allows access to the node ids anywhere.
194
193
  export var getNodeIdProvider = function getNodeIdProvider(editorView) {
195
194
  if (!nodeIdProviderMap.has(editorView)) {
196
- if (fg('platform_editor_native_anchor_patch_2')) {
197
- // if the limited mode flag is on, enable limited mode based on the threshold
198
- // only for the first time
199
- var limitedMode = isLimitedModeEnabled(editorView);
200
- var isEmptyDoc = isEmptyDocument(editorView.state.doc);
201
- var _provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
202
- nodeIdProviderMap.set(editorView, _provider);
203
- return _provider;
204
- }
205
- var provider = new NodeAnchorProvider();
195
+ // if the limited mode flag is on, enable limited mode based on the threshold
196
+ // only for the first time
197
+ var limitedMode = isLimitedModeEnabled(editorView);
198
+ var isEmptyDoc = isEmptyDocument(editorView.state.doc);
199
+ var provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
206
200
  nodeIdProviderMap.set(editorView, provider);
207
201
  return provider;
208
202
  }
@@ -211,7 +205,7 @@ export var getNodeIdProvider = function getNodeIdProvider(editorView) {
211
205
  // in some cases we need to re-check limited mode state
212
206
  // Confluence editor can start with an empty doc and then load content later
213
207
  // so we need to check first time from an empty doc to a non-empty doc
214
- if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc) && fg('platform_editor_native_anchor_patch_2')) {
208
+ if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc)) {
215
209
  // set empty doc to false regardless of limited mode state
216
210
  nodeIdProvider.setEmptyDoc(false);
217
211
  if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
@@ -61,6 +61,7 @@ var ReactNodeView = /*#__PURE__*/function () {
61
61
  key: "init",
62
62
  value: function init() {
63
63
  var _this2 = this;
64
+ var shouldSkipInitRender = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
64
65
  this.domRef = this.createDomRef();
65
66
  this.setDomAttrs(this.node, this.domRef);
66
67
  var _ref = this.getContentDOM() || {
@@ -87,9 +88,11 @@ var ReactNodeView = /*#__PURE__*/function () {
87
88
  trackingEnabled && startMeasureReactNodeViewRendered({
88
89
  nodeTypeName: this.node.type.name
89
90
  });
90
- this.renderReactComponent(function () {
91
- return _this2.render(_this2.reactComponentProps, _this2.handleRef);
92
- });
91
+ if (!shouldSkipInitRender) {
92
+ this.renderReactComponent(function () {
93
+ return _this2.render(_this2.reactComponentProps, _this2.handleRef);
94
+ });
95
+ }
93
96
  trackingEnabled && stopMeasureReactNodeViewRendered({
94
97
  nodeTypeName: this.node.type.name,
95
98
  dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
@@ -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 = "112.18.1";
24
+ var packageVersion = "112.18.3";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -6,6 +6,6 @@ type AiAutocompleteInvokedAEP = TrackAEP<ACTION.INVOKED, ACTION_SUBJECT.AI_AUTOC
6
6
  type AiAutocompleteViewedAEP = TrackAEP<ACTION.SUGGESTION_VIEWED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
7
7
  type AiAutocompleteAcceptedAEP = TrackAEP<ACTION.SUGGESTION_INSERTED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
8
8
  type AiAutocompleteRejectedAEP = TrackAEP<ACTION.SUGGESTION_DISMISSED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
9
- export type TriggerType = 'summary-heading' | 'summary-first-lines' | 'summary-panel' | 'cmd+shift+space';
9
+ export type TriggerType = 'summary-heading' | 'summary-first-lines' | 'summary-panel' | 'conclusion-heading' | 'conclusion-last-lines' | 'cmd+shift+space';
10
10
  export type AiAutocompleteEventPayload = AiAutocompleteInvokedAEP | AiAutocompleteViewedAEP | AiAutocompleteAcceptedAEP | AiAutocompleteRejectedAEP;
11
11
  export {};
@@ -15,11 +15,17 @@ type AIStreamingNoDocChangeAEP = OperationalAEP<ACTION.NO_DOC_CHANGE_FOUND, ACTI
15
15
  }>;
16
16
  type AIStreamingInvalidCommandAEP = OperationalAEP<ACTION.INVALID_COMMAND_FOUND, ACTION_SUBJECT.AI_STREAMING, ACTION_SUBJECT_ID.EXPERIENCE_APPLICATION, {
17
17
  ancestors?: string[];
18
+ anchorNodeType?: string;
19
+ destinationParentNodeType?: string;
18
20
  errorMessage?: string;
19
21
  errorStack?: string;
20
22
  fragments?: string[];
23
+ parentNodeType?: string;
21
24
  repaired: boolean;
25
+ sourceNodeType?: string;
26
+ sourceParentNodeType?: string;
22
27
  success: boolean;
28
+ validationReason?: string;
23
29
  }>;
24
30
  type AIStreamingUpdateStreamError = OperationalAEP<ACTION.ERRORED, ACTION_SUBJECT.AI_STREAMING, ACTION_SUBJECT_ID.UPDATE_STREAM, {
25
31
  docSize: number;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { ADFEntity } from '@atlaskit/adf-utils/types';
3
3
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
4
- import type { EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { Decoration, DecorationSource, EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { EventDispatcher } from '../event-dispatcher';
6
6
  import type { ExtensionHandlers } from '../extensions';
7
7
  import type { PortalProviderAPI } from '../portal';
@@ -25,11 +25,40 @@ interface ReactExtensionNodeProps {
25
25
  showUpdatedLivePages1PBodiedExtensionUI?: (node: ADFEntity) => boolean;
26
26
  }
27
27
  export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNodeView<ReactExtensionNodeProps & AdditionalParams> {
28
+ /**
29
+ * Track whether we found and are reusing SSR'd DOM.
30
+ * When true, we skip React Portal rendering on first init to preserve SSR content.
31
+ */
32
+ private didReuseSsrDom;
33
+ /**
34
+ * Track whether this is the first init call.
35
+ * SSR content preservation only happens on the very first init.
36
+ */
37
+ private isFirstInit;
28
38
  ignoreMutation(mutation: MutationRecord | {
29
39
  target: Node;
30
40
  type: 'selection';
31
41
  }): boolean;
32
42
  createDomRef(): HTMLElement;
43
+ /**
44
+ * Cache for SSR element lookup to avoid repeated DOM queries.
45
+ * undefined = not yet searched, null = searched but not found, HTMLElement = found
46
+ */
47
+ private cachedSsrElement;
48
+ /**
49
+ * Attempts to find an existing SSR'd DOM element for this extension node by extensionKey and localId
50
+ * which should uniquely identify the
51
+ * extension node within the editor content.
52
+ *
53
+ * @returns The SSR'd element if found, otherwise null
54
+ */
55
+ private findSSRElement;
56
+ /**
57
+ * Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
58
+ * This preserves the SSR content without React unnecessarily re-rendering it.
59
+ */
60
+ init(): this;
61
+ update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
33
62
  /**
34
63
  * When interacting with input elements inside an extension's body, the events
35
64
  * bubble up to the editor and get handled by it. This almost always gets in the way
@@ -32,7 +32,7 @@ export default class ReactNodeView<P = ReactComponentProps> implements NodeView
32
32
  * constructor, which leads to some methods being undefined during the
33
33
  * first render.
34
34
  */
35
- init(): this;
35
+ init(shouldSkipInitRender?: boolean): this;
36
36
  private renderReactComponent;
37
37
  createDomRef(): HTMLElement;
38
38
  getContentDOM(): {
@@ -6,6 +6,6 @@ type AiAutocompleteInvokedAEP = TrackAEP<ACTION.INVOKED, ACTION_SUBJECT.AI_AUTOC
6
6
  type AiAutocompleteViewedAEP = TrackAEP<ACTION.SUGGESTION_VIEWED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
7
7
  type AiAutocompleteAcceptedAEP = TrackAEP<ACTION.SUGGESTION_INSERTED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
8
8
  type AiAutocompleteRejectedAEP = TrackAEP<ACTION.SUGGESTION_DISMISSED, ACTION_SUBJECT.AI_AUTOCOMPLETE, undefined, undefined, undefined>;
9
- export type TriggerType = 'summary-heading' | 'summary-first-lines' | 'summary-panel' | 'cmd+shift+space';
9
+ export type TriggerType = 'summary-heading' | 'summary-first-lines' | 'summary-panel' | 'conclusion-heading' | 'conclusion-last-lines' | 'cmd+shift+space';
10
10
  export type AiAutocompleteEventPayload = AiAutocompleteInvokedAEP | AiAutocompleteViewedAEP | AiAutocompleteAcceptedAEP | AiAutocompleteRejectedAEP;
11
11
  export {};
@@ -15,11 +15,17 @@ type AIStreamingNoDocChangeAEP = OperationalAEP<ACTION.NO_DOC_CHANGE_FOUND, ACTI
15
15
  }>;
16
16
  type AIStreamingInvalidCommandAEP = OperationalAEP<ACTION.INVALID_COMMAND_FOUND, ACTION_SUBJECT.AI_STREAMING, ACTION_SUBJECT_ID.EXPERIENCE_APPLICATION, {
17
17
  ancestors?: string[];
18
+ anchorNodeType?: string;
19
+ destinationParentNodeType?: string;
18
20
  errorMessage?: string;
19
21
  errorStack?: string;
20
22
  fragments?: string[];
23
+ parentNodeType?: string;
21
24
  repaired: boolean;
25
+ sourceNodeType?: string;
26
+ sourceParentNodeType?: string;
22
27
  success: boolean;
28
+ validationReason?: string;
23
29
  }>;
24
30
  type AIStreamingUpdateStreamError = OperationalAEP<ACTION.ERRORED, ACTION_SUBJECT.AI_STREAMING, ACTION_SUBJECT_ID.UPDATE_STREAM, {
25
31
  docSize: number;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { ADFEntity } from '@atlaskit/adf-utils/types';
3
3
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
4
- import type { EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { Decoration, DecorationSource, EditorView, NodeView } from '@atlaskit/editor-prosemirror/view';
5
5
  import type { EventDispatcher } from '../event-dispatcher';
6
6
  import type { ExtensionHandlers } from '../extensions';
7
7
  import type { PortalProviderAPI } from '../portal';
@@ -25,11 +25,40 @@ interface ReactExtensionNodeProps {
25
25
  showUpdatedLivePages1PBodiedExtensionUI?: (node: ADFEntity) => boolean;
26
26
  }
27
27
  export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNodeView<ReactExtensionNodeProps & AdditionalParams> {
28
+ /**
29
+ * Track whether we found and are reusing SSR'd DOM.
30
+ * When true, we skip React Portal rendering on first init to preserve SSR content.
31
+ */
32
+ private didReuseSsrDom;
33
+ /**
34
+ * Track whether this is the first init call.
35
+ * SSR content preservation only happens on the very first init.
36
+ */
37
+ private isFirstInit;
28
38
  ignoreMutation(mutation: MutationRecord | {
29
39
  target: Node;
30
40
  type: 'selection';
31
41
  }): boolean;
32
42
  createDomRef(): HTMLElement;
43
+ /**
44
+ * Cache for SSR element lookup to avoid repeated DOM queries.
45
+ * undefined = not yet searched, null = searched but not found, HTMLElement = found
46
+ */
47
+ private cachedSsrElement;
48
+ /**
49
+ * Attempts to find an existing SSR'd DOM element for this extension node by extensionKey and localId
50
+ * which should uniquely identify the
51
+ * extension node within the editor content.
52
+ *
53
+ * @returns The SSR'd element if found, otherwise null
54
+ */
55
+ private findSSRElement;
56
+ /**
57
+ * Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
58
+ * This preserves the SSR content without React unnecessarily re-rendering it.
59
+ */
60
+ init(): this;
61
+ update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
33
62
  /**
34
63
  * When interacting with input elements inside an extension's body, the events
35
64
  * bubble up to the editor and get handled by it. This almost always gets in the way
@@ -32,7 +32,7 @@ export default class ReactNodeView<P = ReactComponentProps> implements NodeView
32
32
  * constructor, which leads to some methods being undefined during the
33
33
  * first render.
34
34
  */
35
- init(): this;
35
+ init(shouldSkipInitRender?: boolean): this;
36
36
  private renderReactComponent;
37
37
  createDomRef(): HTMLElement;
38
38
  getContentDOM(): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "112.18.2",
3
+ "version": "112.18.4",
4
4
  "description": "A package that contains common classes and components for editor and renderer",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -70,16 +70,16 @@
70
70
  "@atlaskit/platform-feature-flags": "^1.1.0",
71
71
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
72
72
  "@atlaskit/primitives": "^18.1.0",
73
- "@atlaskit/profilecard": "^24.48.0",
73
+ "@atlaskit/profilecard": "^24.49.0",
74
74
  "@atlaskit/prosemirror-history": "^0.2.0",
75
- "@atlaskit/react-ufo": "^5.11.0",
75
+ "@atlaskit/react-ufo": "^5.12.0",
76
76
  "@atlaskit/section-message": "^8.12.0",
77
77
  "@atlaskit/smart-card": "^43.31.0",
78
78
  "@atlaskit/smart-user-picker": "^9.2.0",
79
79
  "@atlaskit/spinner": "^19.1.0",
80
80
  "@atlaskit/task-decision": "^19.3.0",
81
81
  "@atlaskit/textfield": "^8.3.0",
82
- "@atlaskit/tmp-editor-statsig": "^54.5.0",
82
+ "@atlaskit/tmp-editor-statsig": "^55.0.0",
83
83
  "@atlaskit/tokens": "^11.4.0",
84
84
  "@atlaskit/tooltip": "^21.1.0",
85
85
  "@atlaskit/width-detector": "^5.0.0",
@@ -214,9 +214,6 @@
214
214
  "p2m-drop-down-motion": {
215
215
  "type": "boolean"
216
216
  },
217
- "platform_editor_link_picker_width_fix": {
218
- "type": "boolean"
219
- },
220
217
  "platform_editor_content_mode_button_mvp": {
221
218
  "type": "boolean"
222
219
  },
@@ -253,9 +250,6 @@
253
250
  "platform_editor_ally_remove_role_tabpanel": {
254
251
  "type": "boolean"
255
252
  },
256
- "platform_editor_native_anchor_patch_2": {
257
- "type": "boolean"
258
- },
259
253
  "platform_forge_ui_support_images_in_adfrenderer": {
260
254
  "type": "boolean"
261
255
  },