@atlaskit/renderer 137.1.3 → 137.1.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.
@@ -10,6 +10,7 @@ import React, { useContext, useState } from 'react';
10
10
  import { WidthConsumer } from '@atlaskit/editor-common/ui';
11
11
  import { RendererCssClassName } from '../../consts';
12
12
  import { calcBreakoutWidth } from '@atlaskit/editor-common/utils';
13
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
13
14
  import { useMultiBodiedExtensionActions } from './multiBodiedExtension/actions';
14
15
  import { useMultiBodiedExtensionContext } from './multiBodiedExtension/context';
15
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -28,10 +29,12 @@ const containerStyles = css({
28
29
  }
29
30
  });
30
31
  const MultiBodiedExtensionChildrenContainer = ({
31
- children
32
+ children,
33
+ frameId
32
34
  }) => {
33
35
  return jsx("article", {
34
- "data-testid": "multiBodiedExtension--frames"
36
+ "data-testid": "multiBodiedExtension--frames",
37
+ "data-multibodiedextension-frames-id": frameId
35
38
  }, children);
36
39
  };
37
40
  const MultiBodiedExtensionNavigation = ({
@@ -41,6 +44,23 @@ const MultiBodiedExtensionNavigation = ({
41
44
  "data-testid": "multiBodiedExtension-navigation"
42
45
  }, children);
43
46
  };
47
+ const getContainerActiveFrameStyles = (activeChildIndex, frameId) => {
48
+ return fg('platform_editor_nested_mbe_frames') ?
49
+ // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
50
+ css`
51
+ &
52
+ [data-multibodiedextension-frames-id='${frameId}']
53
+ > [data-extension-frame='true']:nth-of-type(${activeChildIndex + 1}) {
54
+ display: block;
55
+ }
56
+ ` :
57
+ // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
58
+ css`
59
+ & [data-extension-frame='true']:nth-of-type(${activeChildIndex + 1}) {
60
+ display: block;
61
+ }
62
+ `;
63
+ };
44
64
  const MultiBodiedExtensionWrapperLegacy = ({
45
65
  width,
46
66
  path,
@@ -128,10 +148,16 @@ const MultiBodiedExtension = props => {
128
148
  extensionType,
129
149
  extensionKey
130
150
  });
151
+ // Used by the gated active-frame styles to scope selection to this MBE instance.
152
+ // Renderer frames are direct children of this article, so the id prevents a parent
153
+ // MBE selector from reaching into nested MBEs.
154
+ const frameId = React.useId();
131
155
  const actions = useMultiBodiedExtensionActions({
132
156
  updateActiveChild: setActiveChildIndex,
133
157
  children,
134
- childrenContainer: jsx(MultiBodiedExtensionChildrenContainer, null, children),
158
+ childrenContainer: jsx(MultiBodiedExtensionChildrenContainer, {
159
+ frameId: frameId
160
+ }, children),
135
161
  allowBodiedOverride: extensionContext === null || extensionContext === void 0 ? void 0 : (_extensionContext$pri = extensionContext.privateProps) === null || _extensionContext$pri === void 0 ? void 0 : _extensionContext$pri.__allowBodiedOverride,
136
162
  extensionKey,
137
163
  extensionType,
@@ -165,17 +191,14 @@ const MultiBodiedExtension = props => {
165
191
  return jsx(React.Fragment, null, jsx(MultiBodiedExtensionNavigation, null, jsx(NodeRenderer, {
166
192
  node: node,
167
193
  actions: actions
168
- })), jsx(MultiBodiedExtensionChildrenContainer, null, children));
194
+ })), jsx(MultiBodiedExtensionChildrenContainer, {
195
+ frameId: frameId
196
+ }, children));
169
197
  }
170
- }, [loading, extensionContext, marks, extensionKey, extensionType, parameters, content, getContent, localId, actions, children]);
198
+ }, [loading, extensionContext, marks, extensionKey, extensionType, parameters, content, getContent, localId, actions, children, frameId]);
171
199
 
172
200
  // make the frame visible
173
- // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
174
- const containerActiveFrameStyles = css`
175
- & [data-extension-frame='true']:nth-of-type(${activeChildIndex + 1}) {
176
- display: block;
177
- }
178
- `;
201
+ const containerActiveFrameStyles = getContainerActiveFrameStyles(activeChildIndex, frameId);
179
202
  if (expValEquals('platform_editor_renderer_extension_width_fix', 'isEnabled', true)) {
180
203
  const isTopLevel = path.length < 1;
181
204
  const useCenterWrapper = isTopLevel && ['wide', 'full-width'].includes(layout);
@@ -6,7 +6,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
7
  const getMediaClientConfigForRenderer = provider => {
8
8
  // eslint-disable-next-line @atlaskit/platform/no-preconditioning
9
- return provider.viewAndUploadMediaClientConfig && fg('platform_media_video_captions') && fg('platform_editor_video_caption_commit') ? provider.viewAndUploadMediaClientConfig : provider.viewMediaClientConfig;
9
+ return provider.viewAndUploadMediaClientConfig && fg('platform_media_video_captions') ? provider.viewAndUploadMediaClientConfig : provider.viewMediaClientConfig;
10
10
  };
11
11
  export const EditorMediaClientProvider = ({
12
12
  children,
@@ -4,7 +4,7 @@
4
4
  */
5
5
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
6
6
  import { css, jsx } from '@emotion/react';
7
- import React, { useCallback, useRef, Suspense, lazy } from 'react';
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
8
  import { bind } from 'bind-event-listener';
9
9
  import { getDocument } from '@atlaskit/browser-apis';
10
10
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
@@ -12,8 +12,9 @@ import { ExpandIconWrapper, ExpandLayoutWrapperWithRef, expandMessages, WidthPro
12
12
  import { akEditorLineHeight, akEditorSwoopCubicBezier, akLayoutGutterOffset } from '@atlaskit/editor-shared-styles';
13
13
  import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
14
14
  import Tooltip from '@atlaskit/tooltip/Tooltip';
15
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
15
16
  import { fg } from '@atlaskit/platform-feature-flags/fg';
16
- import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
17
+ import { getExpandSearchText } from './utils/expand-search-text';
17
18
  import _uniqueId from 'lodash/uniqueId';
18
19
  import { injectIntl } from 'react-intl';
19
20
  import { MODE, PLATFORM } from '../analytics/events';
@@ -153,17 +154,6 @@ const clearNextSiblingMarginTopStyle = css({
153
154
  marginTop: '0 !important'
154
155
  }
155
156
  });
156
-
157
- // Lazy-loaded children component
158
- const LazyChildren = /*#__PURE__*/lazy(() => {
159
- return Promise.resolve({
160
- default: ({
161
- children
162
- }) => {
163
- return /*#__PURE__*/React.createElement(React.Fragment, null, children);
164
- }
165
- });
166
- });
167
157
  const Container = props => {
168
158
  return jsx("div", {
169
159
  css: [containerStyles, props['data-node-type'] === 'expand' && containerStylesDataNodeTypeExpand, props.expanded && containerStylesExpanded, props.focused && containerStylesFocused],
@@ -223,12 +213,19 @@ function Expand({
223
213
  localId,
224
214
  nestedHeaderIds,
225
215
  rendererContentMode,
226
- loadBodyContent,
227
- searchText
216
+ node
228
217
  }) {
229
- const [expanded, setExpanded] = React.useState(false);
230
- const [focused, setFocused] = React.useState(false);
231
- const [hasLoadedChildren, setHasLoadedChildren] = React.useState(false);
218
+ const [expanded, setExpanded] = useState(false);
219
+ const [focused, setFocused] = useState(false);
220
+ /**
221
+ * PGXT-9021: latches on the first open so the body stays mounted once rendered, including after
222
+ * the expand is collapsed again. Remounting it would re-run every macro and Forge data fetch
223
+ * inside on each reopen, which is both slower and visibly reloads content the reader has already
224
+ * seen. The saving this gate exists for is at initial load, where the body has never been opened,
225
+ * so nothing is given up by keeping it after that. Never set on the server, so the server and the
226
+ * client's first render agree and hydration cannot desync.
227
+ */
228
+ const [hasBeenExpanded, setHasBeenExpanded] = useState(false);
232
229
  const isMobile = false;
233
230
  const label = intl.formatMessage(expanded ? expandMessages.collapseNode : expandMessages.expandNode);
234
231
  const {
@@ -238,16 +235,12 @@ function Expand({
238
235
  const contentWrapperRef = useRef(null);
239
236
  const handleFocus = useCallback(() => setFocused(true), []);
240
237
  const handleBlur = useCallback(() => setFocused(false), []);
241
- const expandForBrowserFind = useCallback(() => {
242
- setHasLoadedChildren(true);
238
+ // Both state updates happen in the same handler so they land in one render, rather than the
239
+ // latch reacting to `expanded` from an effect.
240
+ const openBody = useCallback(() => {
243
241
  setExpanded(true);
242
+ setHasBeenExpanded(true);
244
243
  }, []);
245
- const shouldRenderLazyChildren = hasLoadedChildren || loadBodyContent;
246
- // Only render the lightweight text placeholder when lazy load is ON and
247
- // children haven't been loaded yet. When lazy load is OFF, children are
248
- // always in the DOM — hidden="until-found" on the wrapper already makes
249
- // them searchable by browser find, so no placeholder is needed.
250
- const shouldRenderBrowserFindText = !shouldRenderLazyChildren && searchText && fg('hot-121622_lazy_load_expand_content') && expValEquals('platform_editor_close_expand_find', 'isEnabled', true);
251
244
 
252
245
  // Feature-detect hidden="until-found" support via the beforematch event.
253
246
  // Chrome 102+ and Firefox 130+ support it; Safari does not yet.
@@ -256,8 +249,8 @@ function Expand({
256
249
  // Initialised as false and set in useEffect to avoid SSR/client hydration mismatch —
257
250
  // useMemo would return true on the client's first render in supported browsers,
258
251
  // differing from the server snapshot which always produces false.
259
- const [supportsHiddenUntilFound, setSupportsHiddenUntilFound] = React.useState(false);
260
- React.useEffect(() => {
252
+ const [supportsHiddenUntilFound, setSupportsHiddenUntilFound] = useState(false);
253
+ useEffect(() => {
261
254
  const doc = getDocument();
262
255
  setSupportsHiddenUntilFound(doc !== null && doc !== void 0 && doc.body ? 'onbeforematch' in doc.body : false);
263
256
  }, []);
@@ -273,13 +266,13 @@ function Expand({
273
266
  // In unsupported browsers (Safari), we skip this entirely and fall back to the normal
274
267
  // CSS hiding (visibility:hidden + height:0), which doesn't support find-in-page but
275
268
  // still works correctly for expand/collapse.
276
- React.useEffect(() => {
269
+ useEffect(() => {
277
270
  const contentContainer = contentContainerRef.current;
278
271
  const contentWrapper = contentWrapperRef.current;
279
272
  if (!contentWrapper) {
280
273
  return;
281
274
  }
282
- if (supportsHiddenUntilFound && expValEquals('platform_editor_close_expand_find', 'isEnabled', true) && !expanded) {
275
+ if (supportsHiddenUntilFound && isExperimentEnabled('platform_editor_close_expand_find') && !expanded) {
283
276
  contentWrapper.setAttribute('hidden', 'until-found');
284
277
  // Override the CSS visibility:hidden from contentContainerStyles — hidden="until-found"
285
278
  // now handles hiding via content-visibility:hidden, which allows browser find to index
@@ -293,31 +286,27 @@ function Expand({
293
286
  contentWrapper.style.visibility = '';
294
287
  }
295
288
  }, [expanded, supportsHiddenUntilFound]);
296
- React.useEffect(() => {
297
- if (!expValEquals('platform_editor_close_expand_find', 'isEnabled', true) || expanded) {
289
+ useEffect(() => {
290
+ if (!isExperimentEnabled('platform_editor_close_expand_find') || expanded) {
298
291
  return;
299
292
  }
300
293
  const contentWrapper = contentWrapperRef.current;
301
294
  const unbindWrapperBeforeMatch = contentWrapper && supportsHiddenUntilFound ? bind(contentWrapper, {
302
295
  type: 'beforematch',
303
- listener: expandForBrowserFind
296
+ listener: openBody
304
297
  }) : undefined;
305
298
  return () => {
306
299
  unbindWrapperBeforeMatch === null || unbindWrapperBeforeMatch === void 0 ? void 0 : unbindWrapperBeforeMatch();
307
300
  };
308
- }, [expandForBrowserFind, expanded, supportsHiddenUntilFound]);
309
- let expandContent = children;
310
- if (shouldRenderBrowserFindText) {
311
- // Browser find path: keep a lightweight text mirror in the closed expand
312
- // so Ctrl+F can index it without mounting the rich children tree.
313
- expandContent = jsx("span", null, searchText);
314
- } else if (!shouldRenderLazyChildren && fg('hot-121622_lazy_load_expand_content')) {
315
- expandContent = null;
316
- } else if (fg('hot-121622_lazy_load_expand_content')) {
317
- expandContent = jsx(Suspense, {
318
- fallback: jsx("div", null, intl.formatMessage(expandMessages.loading))
319
- }, jsx(LazyChildren, null, children));
320
- }
301
+ }, [expanded, openBody, supportsHiddenUntilFound]);
302
+
303
+ // Until the expand is first opened, stand in a plain-text mirror of the body so
304
+ // hidden="until-found" keeps the content findable by browser find without mounting the real
305
+ // subtree. The beforematch listener above expands before the browser scrolls to its match.
306
+ // Computed lazily: a nested expand is not mounted until its ancestor opens, so its mirror is
307
+ // never built on initial load.
308
+ const searchText = useMemo(() => node && fg('hot-121622_lazy_load_expand_content') ? getExpandSearchText(node) : undefined, [node]);
309
+ const expandContent = searchText && !expanded && !hasBeenExpanded ? jsx("span", null, searchText) : children;
321
310
  return jsx(Container, {
322
311
  "data-testid": `expand-container-${nodeType}-${id}`,
323
312
  "data-node-type": nodeType,
@@ -327,15 +316,8 @@ function Expand({
327
316
  expanded: expanded,
328
317
  focused: focused
329
318
  }, nestedHeaderIds && nestedHeaderIds.length > 0 ? jsx(ActiveHeaderIdConsumer, {
330
- nestedHeaderIds: nestedHeaderIds
331
- // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
332
- ,
333
- onNestedHeaderIdMatch: () => {
334
- if (!hasLoadedChildren) {
335
- setHasLoadedChildren(true);
336
- }
337
- setExpanded(true);
338
- }
319
+ nestedHeaderIds: nestedHeaderIds,
320
+ onNestedHeaderIdMatch: openBody
339
321
  }) : null, jsx(TitleContainer
340
322
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
341
323
  , {
@@ -343,12 +325,11 @@ function Expand({
343
325
  e.preventDefault();
344
326
  e.stopPropagation();
345
327
  fireExpandToggleAnalytics(nodeType, expanded, fireAnalyticsEvent);
346
-
347
- // Mark children as loaded when expanding for the first time
348
- if (!expanded && !hasLoadedChildren) {
349
- setHasLoadedChildren(true);
328
+ if (expanded) {
329
+ setExpanded(false);
330
+ } else {
331
+ openBody();
350
332
  }
351
- setExpanded(!expanded);
352
333
  e.persist();
353
334
  // @ts-ignore detail doesn't exist on type
354
335
  e.detail ? handleBlur() : handleFocus();
@@ -383,7 +364,7 @@ function Expand({
383
364
  id: id
384
365
  }, title || intl.formatMessage(expandMessages.expandDefaultTitle))), jsx(ContentContainer, {
385
366
  expanded: expanded,
386
- enableBrowserFind: supportsHiddenUntilFound && expValEquals('platform_editor_close_expand_find', 'isEnabled', true),
367
+ enableBrowserFind: supportsHiddenUntilFound && isExperimentEnabled('platform_editor_close_expand_find'),
387
368
  contentRef: contentContainerRef
388
369
  }, jsx("div", {
389
370
  className: `${nodeType}-content-wrapper`,
@@ -60,7 +60,7 @@ export const DEGRADED_SEVERITY_THRESHOLD = 3000;
60
60
  const TABLE_INFO_TIMEOUT = 10000;
61
61
  const RENDER_EVENT_SAMPLE_RATE = 0.1;
62
62
  const packageName = "@atlaskit/renderer";
63
- const packageVersion = "137.1.2";
63
+ const packageVersion = "137.1.4";
64
64
  const setAsQueryContainerStyles = css({
65
65
  containerName: 'ak-renderer-wrapper',
66
66
  containerType: 'inline-size'
@@ -0,0 +1,84 @@
1
+ import { findChildrenByMark } from '@atlaskit/editor-prosemirror/utils';
2
+
3
+ /**
4
+ * Minimal structural view of an ADF entity. `parameters.nestedContent` holds raw ADF JSON rather
5
+ * than ProseMirror nodes, so it cannot be walked with the model API.
6
+ */
7
+
8
+ /** Separates text from adjacent blocks so phrases cannot fuse across block boundaries. */
9
+ const BLOCK_SEPARATOR = ' ';
10
+ const asText = value => typeof value === 'string' ? value : '';
11
+
12
+ /**
13
+ * Extracts text from raw ADF JSON.
14
+ *
15
+ * Needed because some extensions stash a whole ADF subtree in `attrs.parameters.nestedContent`
16
+ * instead of in their node content — Confluence does this when it coerces nesting the schema
17
+ * cannot represent (an expand more than two collapsible layers deep, say). Such a node is a
18
+ * ProseMirror leaf, so the model walk cannot see the subtree even though it renders on the page
19
+ * via a nested renderer. Recurses, because nestedContent routinely holds further nested content.
20
+ */
21
+ const adfEntityText = entity => {
22
+ var _entity$attrs, _entity$attrs$paramet, _entity$content;
23
+ if (!entity) {
24
+ return '';
25
+ }
26
+ const parts = [];
27
+ if (entity.type === 'text') {
28
+ parts.push(asText(entity.text));
29
+ }
30
+ const nestedContent = (_entity$attrs = entity.attrs) === null || _entity$attrs === void 0 ? void 0 : (_entity$attrs$paramet = _entity$attrs.parameters) === null || _entity$attrs$paramet === void 0 ? void 0 : _entity$attrs$paramet.nestedContent;
31
+ if (nestedContent) {
32
+ // Prefer the real subtree over `attrs.text`, which is only a placeholder label for it.
33
+ parts.push(adfEntityText(nestedContent));
34
+ } else {
35
+ var _entity$attrs2;
36
+ parts.push(asText((_entity$attrs2 = entity.attrs) === null || _entity$attrs2 === void 0 ? void 0 : _entity$attrs2.text));
37
+ }
38
+ (_entity$content = entity.content) === null || _entity$content === void 0 ? void 0 : _entity$content.forEach(child => parts.push(adfEntityText(child)));
39
+ return parts.filter(Boolean).join(BLOCK_SEPARATOR);
40
+ };
41
+
42
+ /**
43
+ * `textBetween` drops every non-text leaf unless the node spec declares `leafText`, and no ADF
44
+ * node does. Leaves carry their visible text in attrs, so recover it here.
45
+ */
46
+ const leafText = leaf => {
47
+ var _leaf$attrs, _leaf$attrs$parameter, _leaf$attrs2;
48
+ const nestedContent = (_leaf$attrs = leaf.attrs) === null || _leaf$attrs === void 0 ? void 0 : (_leaf$attrs$parameter = _leaf$attrs.parameters) === null || _leaf$attrs$parameter === void 0 ? void 0 : _leaf$attrs$parameter.nestedContent;
49
+ if (nestedContent) {
50
+ return adfEntityText(nestedContent);
51
+ }
52
+ return asText((_leaf$attrs2 = leaf.attrs) === null || _leaf$attrs2 === void 0 ? void 0 : _leaf$attrs2.text);
53
+ };
54
+ const hasInlineComment = node => findChildrenByMark(node, node.type.schema.marks.annotation, true).some(annotation => annotation.node.marks.some(mark => mark.attrs.annotationType === 'inlineComment'));
55
+
56
+ /** `null` is a cached "no mirror for this node", as distinct from `undefined` for a cache miss. */
57
+ const searchTextCache = new WeakMap();
58
+
59
+ /**
60
+ * Plain-text mirror of an expand's body, rendered in its place while collapsed so browser
61
+ * find-in-page can still reach the content.
62
+ *
63
+ * Cached on the node. ProseMirror nodes are immutable and `render-document` memoises
64
+ * `nodeFromJSON`, so the same node instance is reused across renders — including across the
65
+ * serializer rebuilds that invalidate the module-level `memoizeOne` caches.
66
+ *
67
+ * @returns the mirror text, or `undefined` if this expand must keep its body rendered.
68
+ */
69
+ export const getExpandSearchText = node => {
70
+ var _cached;
71
+ let cached = searchTextCache.get(node);
72
+ if (cached === undefined) {
73
+ cached = hasInlineComment(node) ?
74
+ // Withhold the mirror, which makes Expand keep rendering `children`. Comment
75
+ // navigation walks the DOM to find the annotated node and scrolls it into view, so
76
+ // the annotation has to exist as a real element — a flat text mirror carries no
77
+ // annotation marks and cannot stand in for it. Without this, stepping through
78
+ // comments with the arrow keys silently fails to reach any comment inside a
79
+ // collapsed expand. Costs the lazy-load win for these expands, deliberately.
80
+ null : node.textBetween(0, node.content.size, BLOCK_SEPARATOR, leafText);
81
+ searchTextCache.set(node, cached);
82
+ }
83
+ return (_cached = cached) !== null && _cached !== void 0 ? _cached : undefined;
84
+ };
@@ -16,7 +16,7 @@ import TextWrapperComponent from './nodes/text-wrapper';
16
16
  import { isNestedHeaderLinksEnabled } from './utils/links';
17
17
  import { getColumnWidths } from '@atlaskit/editor-common/utils';
18
18
  import { getMarksByOrder, isSameMark } from '@atlaskit/editor-common/validator';
19
- import { findChildrenByMark, findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
19
+ import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
20
20
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
21
21
  import { fg } from '@atlaskit/platform-feature-flags/fg';
22
22
  import { getText } from '../utils';
@@ -729,25 +729,14 @@ var ReactSerializer = /*#__PURE__*/function () {
729
729
  value: function getExpandProps(node) {
730
730
  var _this7 = this;
731
731
  var _path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
732
- var loadBodyContent = false;
733
- if (fg('hot-121622_lazy_load_expand_content')) {
734
- var annotations = findChildrenByMark(node, node.type.schema.marks.annotation, true);
735
- // Force rendering children if there are inline comments to support comments navigation
736
- // which relies on the HTML node to be present.
737
- loadBodyContent = annotations.some(function (annotation) {
738
- return annotation.node.marks.some(function (mark) {
739
- return mark.attrs.annotationType === 'inlineComment';
740
- });
741
- });
742
- }
743
-
744
- // Only compute searchText when the browser find experiment is enabled,
745
- // to avoid unnecessary node.textContent string allocations per expand node.
746
- var searchText = expValEquals('platform_editor_close_expand_find', 'isEnabled', true) ? node.textContent : undefined;
732
+ // Expand receives the node rather than a precomputed string so it can derive the collapsed
733
+ // text mirror only when it actually renders one — a nested expand is not mounted until its
734
+ // ancestor opens and so that derivation can reach content the model walk cannot, such as
735
+ // the ADF stashed in a coerced extension's `parameters.nestedContent`. Expand owns the
736
+ // feature gate check.
747
737
  if (!isNestedHeaderLinksEnabled(this.allowHeadingAnchorLinks)) {
748
738
  return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
749
- loadBodyContent: loadBodyContent,
750
- searchText: searchText
739
+ node: node
751
740
  });
752
741
  }
753
742
  var nestedHeaderIds = findChildrenByType(node, node.type.schema.nodes.heading).map(function (_ref4) {
@@ -756,8 +745,7 @@ var ReactSerializer = /*#__PURE__*/function () {
756
745
  });
757
746
  return _objectSpread(_objectSpread({}, this.getProps(node)), {}, {
758
747
  nestedHeaderIds: nestedHeaderIds,
759
- loadBodyContent: loadBodyContent,
760
- searchText: searchText
748
+ node: node
761
749
  });
762
750
  }
763
751
 
@@ -1,6 +1,6 @@
1
- import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
2
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
- var _templateObject;
2
+ import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
3
+ var _templateObject, _templateObject2;
4
4
  /* eslint-disable @atlaskit/design-system/prefer-primitives, @atlaskit/design-system/consistent-css-prop-usage */
5
5
  /**
6
6
  * @jsxRuntime classic
@@ -13,6 +13,7 @@ import React, { useContext, useState } from 'react';
13
13
  import { WidthConsumer } from '@atlaskit/editor-common/ui';
14
14
  import { RendererCssClassName } from '../../consts';
15
15
  import { calcBreakoutWidth } from '@atlaskit/editor-common/utils';
16
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
16
17
  import { useMultiBodiedExtensionActions } from './multiBodiedExtension/actions';
17
18
  import { useMultiBodiedExtensionContext } from './multiBodiedExtension/context';
18
19
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
@@ -31,9 +32,11 @@ var containerStyles = css({
31
32
  }
32
33
  });
33
34
  var MultiBodiedExtensionChildrenContainer = function MultiBodiedExtensionChildrenContainer(_ref) {
34
- var children = _ref.children;
35
+ var children = _ref.children,
36
+ frameId = _ref.frameId;
35
37
  return jsx("article", {
36
- "data-testid": "multiBodiedExtension--frames"
38
+ "data-testid": "multiBodiedExtension--frames",
39
+ "data-multibodiedextension-frames-id": frameId
37
40
  }, children);
38
41
  };
39
42
  var MultiBodiedExtensionNavigation = function MultiBodiedExtensionNavigation(_ref2) {
@@ -42,6 +45,11 @@ var MultiBodiedExtensionNavigation = function MultiBodiedExtensionNavigation(_re
42
45
  "data-testid": "multiBodiedExtension-navigation"
43
46
  }, children);
44
47
  };
48
+ var getContainerActiveFrameStyles = function getContainerActiveFrameStyles(activeChildIndex, frameId) {
49
+ return fg('platform_editor_nested_mbe_frames') ? // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
50
+ css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n\t\t\t\t&\n\t\t\t\t\t[data-multibodiedextension-frames-id='", "']\n\t\t\t\t\t> [data-extension-frame='true']:nth-of-type(", ") {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\t\t\t"])), frameId, activeChildIndex + 1) : // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
51
+ css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n\t\t\t\t& [data-extension-frame='true']:nth-of-type(", ") {\n\t\t\t\t\tdisplay: block;\n\t\t\t\t}\n\t\t\t"])), activeChildIndex + 1);
52
+ };
45
53
  var MultiBodiedExtensionWrapperLegacy = function MultiBodiedExtensionWrapperLegacy(_ref3) {
46
54
  var width = _ref3.width,
47
55
  path = _ref3.path,
@@ -128,10 +136,16 @@ var MultiBodiedExtension = function MultiBodiedExtension(props) {
128
136
  }),
129
137
  loading = _useMultiBodiedExtens.loading,
130
138
  extensionContext = _useMultiBodiedExtens.extensionContext;
139
+ // Used by the gated active-frame styles to scope selection to this MBE instance.
140
+ // Renderer frames are direct children of this article, so the id prevents a parent
141
+ // MBE selector from reaching into nested MBEs.
142
+ var frameId = React.useId();
131
143
  var actions = useMultiBodiedExtensionActions({
132
144
  updateActiveChild: setActiveChildIndex,
133
145
  children: children,
134
- childrenContainer: jsx(MultiBodiedExtensionChildrenContainer, null, children),
146
+ childrenContainer: jsx(MultiBodiedExtensionChildrenContainer, {
147
+ frameId: frameId
148
+ }, children),
135
149
  allowBodiedOverride: extensionContext === null || extensionContext === void 0 || (_extensionContext$pri = extensionContext.privateProps) === null || _extensionContext$pri === void 0 ? void 0 : _extensionContext$pri.__allowBodiedOverride,
136
150
  extensionKey: extensionKey,
137
151
  extensionType: extensionType,
@@ -165,13 +179,14 @@ var MultiBodiedExtension = function MultiBodiedExtension(props) {
165
179
  return jsx(React.Fragment, null, jsx(MultiBodiedExtensionNavigation, null, jsx(NodeRenderer, {
166
180
  node: node,
167
181
  actions: actions
168
- })), jsx(MultiBodiedExtensionChildrenContainer, null, children));
182
+ })), jsx(MultiBodiedExtensionChildrenContainer, {
183
+ frameId: frameId
184
+ }, children));
169
185
  }
170
- }, [loading, extensionContext, marks, extensionKey, extensionType, parameters, content, getContent, localId, actions, children]);
186
+ }, [loading, extensionContext, marks, extensionKey, extensionType, parameters, content, getContent, localId, actions, children, frameId]);
171
187
 
172
188
  // make the frame visible
173
- // eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression
174
- var containerActiveFrameStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n\t\t& [data-extension-frame='true']:nth-of-type(", ") {\n\t\t\tdisplay: block;\n\t\t}\n\t"])), activeChildIndex + 1);
189
+ var containerActiveFrameStyles = getContainerActiveFrameStyles(activeChildIndex, frameId);
175
190
  if (expValEquals('platform_editor_renderer_extension_width_fix', 'isEnabled', true)) {
176
191
  var _isTopLevel = path.length < 1;
177
192
  var _useCenterWrapper = _isTopLevel && ['wide', 'full-width'].includes(layout);
@@ -7,7 +7,7 @@ import { fg } from '@atlaskit/platform-feature-flags/fg';
7
7
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
8
  var getMediaClientConfigForRenderer = function getMediaClientConfigForRenderer(provider) {
9
9
  // eslint-disable-next-line @atlaskit/platform/no-preconditioning
10
- return provider.viewAndUploadMediaClientConfig && fg('platform_media_video_captions') && fg('platform_editor_video_caption_commit') ? provider.viewAndUploadMediaClientConfig : provider.viewMediaClientConfig;
10
+ return provider.viewAndUploadMediaClientConfig && fg('platform_media_video_captions') ? provider.viewAndUploadMediaClientConfig : provider.viewMediaClientConfig;
11
11
  };
12
12
  export var EditorMediaClientProvider = function EditorMediaClientProvider(_ref) {
13
13
  var children = _ref.children,