@atlaskit/editor-core 219.7.2 → 219.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -227,7 +227,11 @@ const editorContentStyles = {
227
227
  expandStylesMixin_fg_platform_visual_refresh_icons: "_1ev7kb7n _1ocgttxp",
228
228
  expandStylesMixin_without_fg_platform_editor_nested_dnd_styles_changes: "_1w8qq98m _omzvglyw _bqvk1osq _1h9p16ux _19lestnw _14j01n1a _1pm0idpf _1p3gidpf _1d9kt94y _113e1o8l",
229
229
  expandDenseStyles: "_18mb3mia _rrwb3mia",
230
- extensionDiffStyles: "",
230
+ extensionStyles: "_1a64bimv _hdxx1gly _xxyv1rtt _1xxp1tmw _1yb8kb7n _1g5bglyw _15vp15s3 _s9d56x5g _efyrkb7n _bp3fglyw _1tfz1nu9 _14ao1nu9 _1hpkkb7n _1e6ukb7n _1wcvidpf _1pt1idpf _1iq2r4us _1j23bimv _17xs1rtt _7u261tmw _1oo0glyw _1sfk1j28 _z5jxclii _et601yvi _gwkf1j28 _ul13r4us _4kr1h2mm _1qyx1kdv _1clfstnw _pj5bb3bt _1q5aidpf _1mvvidpf _1r6qidpf _1o9tidpf _1g3g1osq _1mglglyw _1cx01ial _am787wq0 _11mi1j28 _bw1x1j28 _ucr81j28 _12mi1j28 _jn1o1osq _6bv41osq _1oxabimv _1qn21gly _f2dr1j28 _68b9clii _1wb01yvi _mwpb1j28 _yyxzr4us _1eah1j28 _thp91j28 _11vt1j28 _4t5m1j28 _lnnb1rtt _wwen1tmw _1uw8kb7n _1kckglyw _1y3y15s3 _w5kn6x5g _1nq1kb7n _1nl0glyw _itji1nu9 _1bby1nu9 _vy7vkb7n _1dtlkb7n _l3rpidpf _wwmdidpf _1r6wr4us _1we4bimv _1nx11rtt _iehe1tmw _7hj6glyw _1gw2oqnp _1nb7oqnp _1890oqnp _mxneidpf _nzqyidpf _1ey5idpf _10qboqnp _mkj8oqnp _1o70oqnp _1oaoidpf _d40vidpf _1xipidpf _pgy3idpf _1ft6idpf _1gfbidpf _fkv9idpf _18gqidpf _jchyidpf _16uk1j28 _1h9u1j28 _36v61j28 _gg19r4us _1g5dr4us _oackr4us _1jtp1j28 _1f311j28 _18rv1j28 _swvw1j28 _1j9x1j28 _1dva1j28 _1mnz1j28 _bq4v1j28 _hl5f1j28 _crev1j28 _1d631j28 _28m71j28 _vi00bimv _1b2sbimv _124rbimv _1hvp1gly _gu7z1gly _1otv1gly _vpzk1rtt _1cas1rtt _o16g1tmw _14ye1tmw _6bknkb7n _1u6pkb7n _1vx5glyw _b841glyw _1oek15s3 _cw2a15s3 _6qzd6x5g _1xbj6x5g _1oa1kb7n _14ookb7n _rst4glyw _31aeglyw _1mwo1nu9 _iahl1nu9 _1abbbimv _1td9bimv _61jobimv _pzvn1gly _1mqj1gly _11bn1gly _qyzc1sou _1cjx1sou _1ie21sou _11dk1nu9 _hle21nu9 _dtkmkb7n _jf2hkb7n _h7tgkb7n _dwq7kb7n _ujyhidpf _1upkidpf _1mrzidpf _1tsoidpf _ib8er4us _15wnr4us _ko3dbimv _v8pmbimv _1hux1rtt _10ke1rtt _a3hl1tmw _1yqx1tmw _1y96glyw _505cglyw _5l361j28 _1ryt1j28 _1n4tclii _1oztclii _qkq9clii _1n5a1yvi _jn3m1yvi _btw31yvi _13is15vq _8cmh15vq _1qmbewfl _14thewfl _190516cs _15z51osq _b4z71osq _1iizoqnp _1vsooqnp _o1s4idpf _1swgidpf _1oknoqnp _1bs5oqnp _13e0idpf _1mxyidpf _wwc7oqnp _8vqxoqnp _1wmeidpf _la9widpf _1yssoqnp _xxgeoqnp _mkvnidpf _1by3idpf _6yf3idpf _ibadidpf _oeksidpf _miq6idpf _9bm6idpf _1noyidpf _b6ceidpf _dlfnidpf",
231
+ extensionStylesDense: "_1s773mia _bqje3mia",
232
+ extensionStylesLegacyDense: "_1r7aqlaa",
233
+ extensionDiffStyles: "_ur7x49jj",
234
+ bodiedExtensionLayoutShiftFix: "_16ng1gkc _klqg1n1a _ptek1n1a _e1ae1n1a _13ey10ni _1bh8dik7 _1v7bia51 _1v3nfajl _1i6iidpf _gc15idpf _1utjidpf _csmsidpf _gogjidpf _gt60idpf _15kbidpf _sve5idpf _pmyyidpf _1jpsidpf _a3m4idpf _pfwgidpf _fo78glyw _1j2jidpf",
231
235
  findReplaceStyles: "_9laafajl _1trh7xuz _1h36j5v0 _1uddtdv8",
232
236
  findReplaceStylesNewWithA11Y: "_xph31b66 _rq281nka _1bk513ow _17vzi7uo _ar1b1b18 _1ybwjocv _1mni17v8 _tfy618hq _11gt15cr _1bx3vj2t _1j061dxm _oa091nka _1ybf1nka _u1hx1up9 _1rn91up9 _wn3j1up9 _1ydu1up9 _11wp1up9 _u12f1ypf _13q91ypf _or3e1s89 _gzgh1s89 _ipvl1s89 _15r21s89 _1cpz1s89 _1lh5kz84 _1pvf1xf3 _7pge1xf3 _1h271xf3 _1us91xf3 _mxi51xf3 _1o191dzh _b9gt1dzh _rdw3qlfy _11bbqlfy _v91uqlfy _1k4sqlfy _1ecxqlfy _7gsu17v8 _12xo17v8 _briz1wdg _1cis1wdg _midr1wdg _1kd91wdg _1t9u1wdg _1me2qxcq _r8mlqxcq _1im23ney _1r5e3ney _1oci3ney _13bv3ney _1kac3ney _h2391jcr _1r791fb9 _1ebn1fb9 _1s101fb9 _1p5e1fb9 _1bkc1fb9 _50231ph4 _1c101ph4 _1s5oiro1 _1w9miro1 _w8rkiro1 _u854iro1 _o9w6iro1 _1sch1b66 _ztqp1nka _4temv9ra _r79ei7uo _1e4d1b18 _hje11ckf _sopm17v8 _4q84eawv _1t2d15cr _12dfvj2t _cle21ok8",
233
237
  findReplaceStylesNewWithCodeblockColorContrastFix: "_64o84viv",
@@ -428,14 +432,7 @@ export const EditorContentContainerCompiled = /*#__PURE__*/React.forwardRef((pro
428
432
  expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp')) && editorContentStyles.mediaCaptionStyles, fg('platform_editor_fix_media_in_renderer') && editorContentStyles.firstWrappedMediaStyles, editorContentStyles.telepointerStyle, /* This needs to be after telepointer styles as some overlapping rules have equal specificity, and so the order is significant */
429
433
  editorContentStyles.telepointerColorAndCommonStyle, editorContentStyles.gapCursorStyles, editorExperiment('platform_synced_block', true) && editorContentStyles.gapCursorStylesVisibilityFix, editorContentStyles.panelStyles, editorContentStyles.nestedPanelBorderStylesMixin, fg('platform_editor_nested_dnd_styles_changes') && editorContentStyles.panelStylesMixin_fg_platform_editor_nested_dnd_styles_changes, editorContentStyles.panelStylesMixin, editorContentStyles.mentionsStyles, editorContentStyles.tasksAndDecisionsStyles, contentMode === 'compact' && (expValEquals('confluence_compact_text_format', 'isEnabled', true) ||
430
434
  // eslint-disable-next-line @atlaskit/platform/no-preconditioning
431
- expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp')) && isDense && editorContentStyles.tasksAndDecisionsDenseStyles, editorContentStyles.gridStyles, editorContentStyles.blockMarksStyles, editorContentStyles.dateStyles,
432
- // eslint-disable-next-line @atlaskit/editor/enforce-todo-comment-format
433
- // TODO: uncomment and remove dynamic styles from getExtensionStyles
434
- // migrate this with packages/editor/editor-core/src/ui/EditorContentContainer/styles/extensionStyles.ts
435
- // suggest creating a new cssMap for the variant use case from the guide below
436
- // reference: https://atlassian.design/components/eslint-plugin-ui-styling-standard/no-dynamic-styles/usage
437
- // getExtensionStyles(contentMode),
438
- editorContentStyles.extensionDiffStyles, editorContentStyles.expandStylesBase, !useStandardNodeWidth && editorContentStyles.expandStyles, contentMode === 'compact' && (expValEquals('confluence_compact_text_format', 'isEnabled', true) ||
435
+ expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp')) && isDense && editorContentStyles.tasksAndDecisionsDenseStyles, editorContentStyles.gridStyles, editorContentStyles.blockMarksStyles, editorContentStyles.dateStyles, editorContentStyles.extensionStyles, (contentMode === 'compact' && expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp')) && editorContentStyles.extensionStylesDense, contentMode === 'compact' && expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && !expValEquals('confluence_compact_text_format', 'isEnabled', true) && !fg('platform_editor_content_mode_button_mvp') && editorContentStyles.extensionStylesLegacyDense, expValEquals('platform_editor_bodiedextension_layoutshift_fix', 'isEnabled', true) && editorContentStyles.bodiedExtensionLayoutShiftFix, editorContentStyles.extensionDiffStyles, editorContentStyles.expandStylesBase, !useStandardNodeWidth && editorContentStyles.expandStyles, contentMode === 'compact' && (expValEquals('confluence_compact_text_format', 'isEnabled', true) ||
439
436
  // eslint-disable-next-line @atlaskit/platform/no-preconditioning
440
437
  expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp')) && isDense && editorContentStyles.expandDenseStyles, fg('platform_editor_nested_dnd_styles_changes') ? editorContentStyles.expandStylesMixin_fg_platform_editor_nested_dnd_styles_changes : editorContentStyles.expandStylesMixin_without_fg_platform_editor_nested_dnd_styles_changes, editorContentStyles.expandStylesMixin_fg_platform_visual_refresh_icons, isChromeless && expValEquals('platform_editor_chromeless_expand_fix', 'isEnabled', true) && editorContentStyles.expandStylesMixin_experiment_platform_editor_chromeless_expand_fix, expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) ? editorContentStyles.findReplaceStylesNewWithA11Y : editorContentStyles.findReplaceStyles, expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && editorContentStyles.findReplaceStylesNewWithCodeblockColorContrastFix, !expValEquals('platform_editor_find_and_replace_improvements', 'isEnabled', true) && editorContentStyles.findReplaceStylesWithCodeblockColorContrastFix, editorContentStyles.textHighlightStyle, editorContentStyles.decisionStyles, expValEqualsNoExposure('platform_editor_blocktaskitem_node_tenantid', 'isEnabled', true) ? editorContentStyles.taskItemStylesWithBlockTaskItem : editorContentStyles.taskItemStyles, editorContentStyles.taskItemCheckboxStyles, editorContentStyles.decisionIconWithVisualRefresh, editorContentStyles.statusStyles, fg('platform-dst-lozenge-tag-badge-visual-uplifts') ? editorContentStyles.statusStylesTeam26 : fg('platform-component-visual-refresh') ? expValEqualsNoExposure('platform_editor_find_and_replace_improvements', 'isEnabled', true) ? editorContentStyles.statusStylesMixin_fg_platform_component_visual_refresh_with_search_match : editorContentStyles.statusStylesMixin_fg_platform_component_visual_refresh : expValEqualsNoExposure('platform_editor_find_and_replace_improvements', 'isEnabled', true) ? editorContentStyles.statusStylesMixin_without_fg_platform_component_visual_refresh_with_search_match : editorContentStyles.statusStylesMixin_without_fg_platform_component_visual_refresh, editorContentStyles.annotationStyles, expValEqualsNoExposure('platform_editor_find_and_replace_improvements', 'isEnabled', true) ? editorExperiment('platform_editor_block_menu', true) ? editorContentStyles.smartCardStylesWithSearchMatchAndBlockMenuDangerStyles : editorContentStyles.smartCardStylesWithSearchMatch : editorContentStyles.smartCardStyles, editorExperiment('platform_editor_preview_panel_responsiveness', true) && editorContentStyles.smartCardStylesWithSearchMatchAndPreviewPanelResponsiveness, (expValEqualsNoExposure('platform_editor_controls', 'cohort', 'variant1') || editorExperiment('platform_editor_preview_panel_linking_exp', true)) && editorContentStyles.editorControlsSmartCardStyles, editorContentStyles.embedCardStyles, editorContentStyles.unsupportedStyles, editorContentStyles.resizerStyles, editorContentStyles.layoutBaseStyles, expValEquals('platform_editor_table_excerpts_fix', 'isEnabled', true) && editorContentStyles.layoutBaseStylesWithTableExcerptsFix, fg('platform_editor_fix_media_in_renderer') && editorContentStyles.alignMultipleWrappedImageInLayoutStyles, editorExperiment('platform_synced_block', true) && editorContentStyles.syncBlockStylesBase, editorExperiment('platform_synced_block', true) &&
441
438
  // Apply sync block delta styles conditionally based on useStandardNodeWidth (negative margins or not)
@@ -5,6 +5,12 @@ import { getQuickInsertItemsFromModule, resolveImport } from '@atlaskit/editor-c
5
5
  import { combineProviders } from '@atlaskit/editor-common/provider-helpers';
6
6
  import { findInsertLocation } from '@atlaskit/editor-common/utils/analytics';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
8
+
9
+ // Structural shape of the markdown-mode plugin's slice of the injection API.
10
+ // Used to read `isMarkdownMode` without importing the `MarkdownModePlugin`
11
+ // type — that would pull editor-plugin-markdown-mode into editor-core's
12
+ // dependency graph and force every consuming product to rebuild.
13
+
8
14
  /**
9
15
  * Utils to send analytics event when a extension is inserted using quickInsert
10
16
  */
@@ -54,6 +60,15 @@ export async function extensionProviderToQuickInsertProvider(extensionProvider,
54
60
  const extensions = await extensionProvider.getExtensions();
55
61
  return {
56
62
  getItems: () => {
63
+ var _apiRef$current, _apiRef$current$markd, _apiRef$current$markd2;
64
+ // `extensionProvider` is supplied independently of the preset, so
65
+ // suppress its items in markdown mode where rich-only content cannot
66
+ // be inserted. See `MarkdownModeReader` above for why this is read
67
+ // via a structural cast rather than the typed plugin API.
68
+ const isMarkdownMode = (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : (_apiRef$current$markd = _apiRef$current.markdownMode) === null || _apiRef$current$markd === void 0 ? void 0 : (_apiRef$current$markd2 = _apiRef$current$markd.sharedState.currentState()) === null || _apiRef$current$markd2 === void 0 ? void 0 : _apiRef$current$markd2.isMarkdownMode;
69
+ if (isMarkdownMode) {
70
+ return Promise.resolve([]);
71
+ }
57
72
  const quickInsertItems = getQuickInsertItemsFromModule(extensions, item => {
58
73
  const Icon = Loadable({
59
74
  loader: item.icon,
@@ -81,8 +96,8 @@ export async function extensionProviderToQuickInsertProvider(extensionProvider,
81
96
  isDisabledOffline: true,
82
97
  action: (insert, state, source) => {
83
98
  if (typeof item.node === 'function') {
84
- var _apiRef$current, _apiRef$current$exten, _apiRef$current$exten2;
85
- const extensionAPI = apiRef === null || apiRef === void 0 ? void 0 : (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : (_apiRef$current$exten = _apiRef$current.extension) === null || _apiRef$current$exten === void 0 ? void 0 : (_apiRef$current$exten2 = _apiRef$current$exten.actions) === null || _apiRef$current$exten2 === void 0 ? void 0 : _apiRef$current$exten2.api();
99
+ var _apiRef$current2, _apiRef$current2$exte, _apiRef$current2$exte2;
100
+ const extensionAPI = apiRef === null || apiRef === void 0 ? void 0 : (_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 ? void 0 : (_apiRef$current2$exte = _apiRef$current2.extension) === null || _apiRef$current2$exte === void 0 ? void 0 : (_apiRef$current2$exte2 = _apiRef$current2$exte.actions) === null || _apiRef$current2$exte2 === void 0 ? void 0 : _apiRef$current2$exte2.api();
86
101
  // While this should only run when the extension some setups of editor
87
102
  // may not have the extension API
88
103
  if (extensionAPI) {
@@ -1,2 +1,2 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "219.7.1";
2
+ export const version = "219.7.3";
@@ -1,11 +1,11 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
6
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
5
7
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
8
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
9
  import React, { useCallback, useLayoutEffect, useMemo, useRef, useState, useEffect } from 'react';
10
10
  import { injectIntl } from 'react-intl';
11
11
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -25,6 +25,7 @@ import { processRawValue, processRawValueWithoutValidation } from '@atlaskit/edi
25
25
  import { ReactEditorViewContext } from '@atlaskit/editor-common/ui-react';
26
26
  import { analyticsEventKey, getAnalyticsEventSeverity } from '@atlaskit/editor-common/utils/analytics';
27
27
  import { isEmptyDocument } from '@atlaskit/editor-common/utils/document';
28
+ import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
28
29
  import { EditorState, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
29
30
  import { EditorView } from '@atlaskit/editor-prosemirror/view';
30
31
  import { EditorSSRRenderer } from '@atlaskit/editor-ssr-renderer';
@@ -56,6 +57,37 @@ import { useFireFullWidthEvent } from './ReactEditorView/useFireFullWidthEvent';
56
57
  var EDIT_AREA_ID = 'ak-editor-textarea';
57
58
  var SSR_TRACE_SEGMENT_NAME = 'reactEditorView';
58
59
  var bootStartTime = isPerformanceAPIAvailable() ? performance.now() : undefined;
60
+ // `markdown↔rich` toggles drop different node/mark sets, so the unique
61
+ // name set is enough to detect when a destructive rebuild is needed.
62
+ function sameNames(a, b) {
63
+ var setA = new Set(a);
64
+ var setB = new Set(b);
65
+ if (setA.size !== setB.size) {
66
+ return false;
67
+ }
68
+ var _iterator = _createForOfIteratorHelper(setA),
69
+ _step;
70
+ try {
71
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
72
+ var name = _step.value;
73
+ if (!setB.has(name)) {
74
+ return false;
75
+ }
76
+ }
77
+ } catch (err) {
78
+ _iterator.e(err);
79
+ } finally {
80
+ _iterator.f();
81
+ }
82
+ return true;
83
+ }
84
+ function schemaShapeChanged(current, next) {
85
+ return !sameNames(Object.keys(current.nodes), next.nodes.map(function (n) {
86
+ return n.name;
87
+ })) || !sameNames(Object.keys(current.marks), next.marks.map(function (m) {
88
+ return m.name;
89
+ }));
90
+ }
59
91
  export function ReactEditorView(props) {
60
92
  var _pluginInjectionAPI$c, _media, _linking, _document$querySelect, _props$render, _props$render2;
61
93
  // Should be always the first statement in the component
@@ -355,9 +387,10 @@ export function ReactEditorView(props) {
355
387
  _useState2 = _slicedToArray(_useState, 2),
356
388
  bumpConfigVersion = _useState2[1];
357
389
 
358
- // Preset reference last processed by the schema/API reconciliation below.
359
- // Used to skip that work when reconfigure is called with the same preset.
360
- var lastFilteredPresetRef = useRef(null);
390
+ // Preset reference last processed by reconfigureState. Used to skip the
391
+ // destructive work (plugin filter, schema rebuild) when reconfigure is
392
+ // called with the same preset.
393
+ var lastProcessedPresetRef = useRef(null);
361
394
  var reconfigureState = useCallback(function (props) {
362
395
  if (!viewRef.current) {
363
396
  return;
@@ -374,6 +407,35 @@ export function ReactEditorView(props) {
374
407
  var previousPluginNames = new Set(pluginInjectionAPI.current.getRegisteredPluginNames());
375
408
  var editorPlugins = createPluginsList(props.preset, 'allowBlockType' in props.editorProps ? props.editorProps : {}, pluginInjectionAPI.current);
376
409
 
410
+ // Capture once, before either downstream block updates the ref —
411
+ // both the filter and the schema rebuild are destructive and only
412
+ // want to run when the preset has actually changed.
413
+ var presetChanged = lastProcessedPresetRef.current !== props.preset;
414
+
415
+ // Build a candidate config from the *unfiltered* plugin list so we can
416
+ // decide whether the schema rebuild path will run. Both the rebuild
417
+ // decision and the drop-filter decision below depend on this answer,
418
+ // so it has to be computed up-front.
419
+ var buildConfig = function buildConfig(plugins) {
420
+ var c = processPluginsList(plugins);
421
+ if (expValEquals('platform_editor_appearance_shared_state', 'isEnabled', true)) {
422
+ var _c$pmPlugins;
423
+ (_c$pmPlugins = c.pmPlugins).push.apply(_c$pmPlugins, _toConsumableArray(pluginInjectionAPI.current.getInternalPMPlugins()));
424
+ }
425
+ return c;
426
+ };
427
+ var nextConfig = buildConfig(editorPlugins);
428
+
429
+ // `state.reconfigure` preserves the original schema, so a preset
430
+ // toggle that should change schema (markdown↔rich) needs a fresh
431
+ // `EditorState`. Resets all plugin state including undo history.
432
+ //
433
+ // Compare schema *shape* (node + mark name sets) rather than preset
434
+ // identity: consumers commonly recreate the preset object on every
435
+ // parent re-render, and a destructive rebuild on a no-op identity
436
+ // change tears down all plugin state (e.g. unmounts the AI palette).
437
+ var shouldRebuildSchema = presetChanged && schemaShapeChanged(viewRef.current.state.schema, nextConfig) && expValEqualsNoExposure('cc-markdown-mode', 'isEnabled', true);
438
+
377
439
  // `state.reconfigure` keeps the original schema, so switching presets
378
440
  // can leave the editor inconsistent in two ways:
379
441
  // 1. The new preset may add plugins that reference schema nodes or
@@ -382,17 +444,26 @@ export function ReactEditorView(props) {
382
444
  // injection API even when the new preset doesn't re-register
383
445
  // them, so listeners still fire against a state that no longer
384
446
  // has their pmPlugin.
385
- if (lastFilteredPresetRef.current !== props.preset && fg('platform_editor_reconfigure_filter_plugins')) {
386
- var _filterPluginsForReco = filterPluginsForReconfigure(editorPlugins, viewRef.current.state.schema, previousPluginNames),
387
- kept = _filterPluginsForReco.kept,
388
- dropped = _filterPluginsForReco.dropped;
389
- editorPlugins = kept;
390
-
391
- // Reconcile the injection API with the post-filter plugin set.
392
- // This evicts both the plugins we just dropped above (re-registered
393
- // by createPluginsList but no longer in editorPlugins) AND any
394
- // plugin from a previous preset that the new preset doesn't
395
- // re-register.
447
+ //
448
+ // When the schema is being rebuilt below, the new schema is built
449
+ // from the *unfiltered* plugin list — so dropping plugins whose
450
+ // nodes/marks the OLD schema lacks would wrongly remove the very
451
+ // plugins the rebuild is meant to admit. Skip the drop step in that
452
+ // case (purpose 1) but always reconcile the injection API
453
+ // (purpose 2). When NOT rebuilding, run both even under the
454
+ // `cc-markdown-mode` experiment, otherwise no-op preset identity
455
+ // changes would silently leave a broken plugin/schema mismatch.
456
+ if (presetChanged && fg('platform_editor_reconfigure_filter_plugins')) {
457
+ var dropped = [];
458
+ if (!shouldRebuildSchema) {
459
+ var _result = filterPluginsForReconfigure(editorPlugins, viewRef.current.state.schema, previousPluginNames);
460
+ if (_result.dropped.length > 0) {
461
+ editorPlugins = _result.kept;
462
+ // Plugin list changed — rebuild candidate config to match.
463
+ nextConfig = buildConfig(editorPlugins);
464
+ }
465
+ dropped = _result.dropped;
466
+ }
396
467
  var keptPluginNames = new Set(editorPlugins.map(function (p) {
397
468
  return p === null || p === void 0 ? void 0 : p.name;
398
469
  }).filter(function (n) {
@@ -406,33 +477,77 @@ export function ReactEditorView(props) {
406
477
  evictedFromApi: evictedFromApi
407
478
  });
408
479
  }
409
- lastFilteredPresetRef.current = props.preset;
410
- }
411
- config.current = processPluginsList(editorPlugins);
412
- if (expValEquals('platform_editor_appearance_shared_state', 'isEnabled', true)) {
413
- var _config$current$pmPlu2;
414
- (_config$current$pmPlu2 = config.current.pmPlugins).push.apply(_config$current$pmPlu2, _toConsumableArray(pluginInjectionAPI.current.getInternalPMPlugins()));
415
480
  }
481
+ config.current = nextConfig;
416
482
  var state = viewRef.current.state;
417
- var plugins = createPMPlugins({
418
- schema: state.schema,
419
- dispatch: dispatch,
420
- errorReporter: errorReporter,
421
- editorConfig: config.current,
422
- eventDispatcher: eventDispatcher,
423
- providerFactory: props.providerFactory,
424
- portalProviderAPI: props.portalProviderAPI,
425
- nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
426
- dispatchAnalyticsEvent: dispatchAnalyticsEvent,
427
- featureFlags: featureFlags,
428
- getIntl: function getIntl() {
429
- return props.intl;
430
- },
431
- onEditorStateUpdated: pluginInjectionAPI.current.onEditorViewUpdated
432
- });
433
- var newState = state.reconfigure({
434
- plugins: plugins
435
- });
483
+ var newState;
484
+ if (shouldRebuildSchema) {
485
+ var newSchema = createSchema(config.current);
486
+ var newDoc;
487
+ try {
488
+ newDoc = PMNode.fromJSON(newSchema, state.doc.toJSON());
489
+ } catch (e) {
490
+ // eslint-disable-next-line no-console
491
+ console.error('[reconfigureState] Failed to migrate doc to new schema; resetting to empty doc', e);
492
+ var empty = newSchema.topNodeType.createAndFill();
493
+ if (!empty) {
494
+ throw new Error('reconfigureState: doc migration failed and new schema cannot create an empty top node');
495
+ }
496
+ newDoc = empty;
497
+ }
498
+ var newSelection;
499
+ try {
500
+ newSelection = Selection.fromJSON(newDoc, state.selection.toJSON());
501
+ } catch (_unused) {
502
+ // Old selection's positions / node types may not map onto the new schema.
503
+ newSelection = Selection.atStart(newDoc);
504
+ }
505
+ var plugins = createPMPlugins({
506
+ schema: newSchema,
507
+ dispatch: dispatch,
508
+ errorReporter: errorReporter,
509
+ editorConfig: config.current,
510
+ eventDispatcher: eventDispatcher,
511
+ providerFactory: props.providerFactory,
512
+ portalProviderAPI: props.portalProviderAPI,
513
+ nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
514
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
515
+ featureFlags: featureFlags,
516
+ getIntl: function getIntl() {
517
+ return props.intl;
518
+ },
519
+ onEditorStateUpdated: pluginInjectionAPI.current.onEditorViewUpdated
520
+ });
521
+ newState = EditorState.create({
522
+ schema: newSchema,
523
+ doc: newDoc,
524
+ selection: newSelection,
525
+ plugins: plugins
526
+ });
527
+ } else {
528
+ var _plugins = createPMPlugins({
529
+ schema: state.schema,
530
+ dispatch: dispatch,
531
+ errorReporter: errorReporter,
532
+ editorConfig: config.current,
533
+ eventDispatcher: eventDispatcher,
534
+ providerFactory: props.providerFactory,
535
+ portalProviderAPI: props.portalProviderAPI,
536
+ nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
537
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
538
+ featureFlags: featureFlags,
539
+ getIntl: function getIntl() {
540
+ return props.intl;
541
+ },
542
+ onEditorStateUpdated: pluginInjectionAPI.current.onEditorViewUpdated
543
+ });
544
+ newState = state.reconfigure({
545
+ plugins: _plugins
546
+ });
547
+ }
548
+ if (presetChanged) {
549
+ lastProcessedPresetRef.current = props.preset;
550
+ }
436
551
 
437
552
  // need to update the state first so when the view builds the nodeviews it is
438
553
  // using the latest plugins
@@ -441,9 +556,32 @@ export function ReactEditorView(props) {
441
556
  state: newState
442
557
  }));
443
558
 
559
+ // The new collab-edit plugin instance starts with `isReady=false`.
560
+ // The rebind path in editor-plugin-collab-edit's initialize.ts is
561
+ // gated on `provider.getInitPayload`, which the Confluence NCS
562
+ // provider does not implement, so the placeholder spinner would
563
+ // never clear. Re-seeding here is safe: the prior state must have
564
+ // had `isReady=true` for the user to have triggered the toggle.
565
+ //
566
+ // Must run AFTER `view.update({ state: newState })`: that call resets
567
+ // the view's state to the captured `newState` reference, so a
568
+ // dispatch placed before it would advance `view.state` to a value
569
+ // that `update` then silently overwrites — discarding the meta and
570
+ // leaving `isReady=false`.
571
+ if (shouldRebuildSchema) {
572
+ // `state.collabEditPlugin$` is the property PM derives from the
573
+ // collab plugin's PluginKey; cast through `unknown` to read it.
574
+ var collabState = viewRef.current.state.collabEditPlugin$;
575
+ if (collabState && collabState.isReady !== true) {
576
+ viewRef.current.dispatch(viewRef.current.state.tr.setMeta('collabInitialised', true));
577
+ }
578
+ }
579
+
444
580
  // EDITOR-6702: gated until we have a broader gate; reconfigure is a
445
581
  // low-level path so use NoExposure.
446
582
  if (expValEqualsNoExposure('cc-markdown-mode', 'isEnabled', true)) {
583
+ // Force a render so PluginSlot picks up the new preset's content
584
+ // components against the new state.
447
585
  bumpConfigVersion(function (v) {
448
586
  return v + 1;
449
587
  });
@@ -686,19 +824,19 @@ export function ReactEditorView(props) {
686
824
  return function () {
687
825
  if (scrollElement.current) {
688
826
  // eslint-disable-next-line react-hooks/exhaustive-deps
689
- var _iterator = _createForOfIteratorHelper(possibleListeners.current),
690
- _step;
827
+ var _iterator2 = _createForOfIteratorHelper(possibleListeners.current),
828
+ _step2;
691
829
  try {
692
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
830
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
693
831
  var _scrollElement$curren;
694
- var possibleListener = _step.value;
832
+ var possibleListener = _step2.value;
695
833
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
696
834
  (_scrollElement$curren = scrollElement.current) === null || _scrollElement$curren === void 0 || _scrollElement$curren.removeEventListener.apply(_scrollElement$curren, _toConsumableArray(possibleListener));
697
835
  }
698
836
  } catch (err) {
699
- _iterator.e(err);
837
+ _iterator2.e(err);
700
838
  } finally {
701
- _iterator.f();
839
+ _iterator2.f();
702
840
  }
703
841
  }
704
842
  scrollElement.current = null;
@@ -710,19 +848,19 @@ export function ReactEditorView(props) {
710
848
  scrollElement.current = document.querySelector('[data-editor-scroll-container]');
711
849
  var cleanupListeners = function cleanupListeners() {
712
850
  // eslint-disable-next-line react-hooks/exhaustive-deps
713
- var _iterator2 = _createForOfIteratorHelper(possibleListeners.current),
714
- _step2;
851
+ var _iterator3 = _createForOfIteratorHelper(possibleListeners.current),
852
+ _step3;
715
853
  try {
716
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
854
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
717
855
  var _scrollElement$curren2;
718
- var possibleListener = _step2.value;
856
+ var possibleListener = _step3.value;
719
857
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
720
858
  (_scrollElement$curren2 = scrollElement.current) === null || _scrollElement$curren2 === void 0 || _scrollElement$curren2.removeEventListener.apply(_scrollElement$curren2, _toConsumableArray(possibleListener));
721
859
  }
722
860
  } catch (err) {
723
- _iterator2.e(err);
861
+ _iterator3.e(err);
724
862
  } finally {
725
- _iterator2.f();
863
+ _iterator3.f();
726
864
  }
727
865
  };
728
866
  if (scrollElement.current) {