@atlaskit/editor-common 116.50.0 → 116.51.0

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 +25 -0
  2. package/collab-agent-remote-edit-review/package.json +10 -0
  3. package/dist/cjs/collab/agent-remote-edit-review.js +22 -0
  4. package/dist/cjs/monitoring/error.js +1 -1
  5. package/dist/cjs/nesting/isPanelC1SchemaEnabled.js +25 -0
  6. package/dist/cjs/nesting/isPanelNestingExpandSupported.js +28 -0
  7. package/dist/cjs/nesting/utilities.js +15 -1
  8. package/dist/cjs/ui/DropList/index.js +1 -1
  9. package/dist/cjs/utils/processRawValue.js +43 -5
  10. package/dist/cjs/utils/validate-using-spec.js +13 -1
  11. package/dist/es2019/collab/agent-remote-edit-review.js +16 -0
  12. package/dist/es2019/monitoring/error.js +1 -1
  13. package/dist/es2019/nesting/isPanelC1SchemaEnabled.js +18 -0
  14. package/dist/es2019/nesting/isPanelNestingExpandSupported.js +24 -0
  15. package/dist/es2019/nesting/utilities.js +5 -1
  16. package/dist/es2019/ui/DropList/index.js +1 -1
  17. package/dist/es2019/utils/processRawValue.js +43 -6
  18. package/dist/es2019/utils/validate-using-spec.js +13 -1
  19. package/dist/esm/collab/agent-remote-edit-review.js +16 -0
  20. package/dist/esm/monitoring/error.js +1 -1
  21. package/dist/esm/nesting/isPanelC1SchemaEnabled.js +20 -0
  22. package/dist/esm/nesting/isPanelNestingExpandSupported.js +23 -0
  23. package/dist/esm/nesting/utilities.js +5 -1
  24. package/dist/esm/ui/DropList/index.js +1 -1
  25. package/dist/esm/utils/processRawValue.js +45 -6
  26. package/dist/esm/utils/validate-using-spec.js +13 -1
  27. package/dist/types/analytics/types/ai-suggestions-events.d.ts +2 -0
  28. package/dist/types/collab/agent-remote-edit-review.d.ts +58 -0
  29. package/dist/types/nesting/isPanelC1SchemaEnabled.d.ts +1 -0
  30. package/dist/types/nesting/isPanelNestingExpandSupported.d.ts +2 -0
  31. package/dist/types/nesting/utilities.d.ts +2 -0
  32. package/dist/types/utils/processRawValue.d.ts +25 -0
  33. package/dist/types/utils/validate-using-spec.d.ts +1 -0
  34. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 116.51.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`3e24bdff68508`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3e24bdff68508) -
8
+ Add expand-in-panel nesting helpers (isPanelC1SchemaEnabled, isPanelNestingExpandSupported),
9
+ validation and fallback-transform support for expand children inside panel_c1.
10
+ - [`95e5e100318c4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/95e5e100318c4) -
11
+ Review moment (Post Stream Review) for BE streaming — record remote agent edits into
12
+ aiContentPositions and open/append the Review moment (hybrid completion signal + idle debounce).
13
+ - New `@atlaskit/editor-common/collab/agent-remote-edit-review` subpath export for the neutral
14
+ agent-edit review contract (AGENT_REMOTE_EDIT_REVIEW_DATA, AgentRemoteEditReviewSegment,
15
+ AgentRemoteEditReviewData).
16
+ - Fix chimera delete diffs in agent-review-segments: per-step backward StepMap mapping replaces
17
+ the previous group-then-invert approach that produced blended original text when multiple
18
+ discrete operations (delete + insert) interacted in the same region.
19
+
20
+ - [`2f382e0df09a8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2f382e0df09a8) -
21
+ added actionKind attribute for viewed and discard analytics and fired discard analytics for
22
+ insights dismiss button
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies
27
+
3
28
  ## 116.50.0
4
29
 
5
30
  ### Minor Changes
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@atlaskit/editor-common/collab-agent-remote-edit-review",
3
+ "main": "../dist/cjs/collab/agent-remote-edit-review.js",
4
+ "module": "../dist/esm/collab/agent-remote-edit-review.js",
5
+ "module:es2019": "../dist/es2019/collab/agent-remote-edit-review.js",
6
+ "sideEffects": [
7
+ "**/*.compiled.css"
8
+ ],
9
+ "types": "../dist/types/collab/agent-remote-edit-review.d.ts"
10
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.AGENT_REMOTE_EDIT_REVIEW_DATA = void 0;
7
+ /**
8
+ * [CCI-17994] Meta carried on the transaction that applies a batch of REMOTE
9
+ * agent-authored steps (BE streaming) in `editor-plugin-collab-edit`'s
10
+ * `applyRemoteSteps`. It lets `editor-plugin-ai` record the agent's changes for a
11
+ * Post Stream Review ("Review moment") WITHOUT collab-edit depending on the AI
12
+ * plugin: the contract is neutral and lives here in `editor-common`, which both
13
+ * plugins already depend on.
14
+ *
15
+ * Stamped whenever a received remote-step batch contains agent-authored steps.
16
+ * Consumed by `aiSessionContextPlugin.apply()`,
17
+ * which appends coarse `aiContentPositions` entries — exactly like the in-editor
18
+ * (FE) streaming path's `AI_FINAL_STREAMING_TRANSFORMATION_DATA`, so the whole
19
+ * downstream Review moment pipeline (merge → segment → diff → undo/redo → accept)
20
+ * is reused unchanged.
21
+ */
22
+ var AGENT_REMOTE_EDIT_REVIEW_DATA = exports.AGENT_REMOTE_EDIT_REVIEW_DATA = 'agentRemoteEditReviewData';
@@ -28,7 +28,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
28
28
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
29
29
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
30
30
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
31
- var packageVersion = "116.49.0";
31
+ var packageVersion = "116.50.0";
32
32
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
33
33
  // Remove URL as it has UGC
34
34
  // Ignored via go/ees007
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isPanelC1SchemaEnabled = void 0;
7
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
8
+ /*
9
+ * Returns true when any panel container-variant nesting experiment is enabled, i.e. when the
10
+ * `panel_c1` node should exist in the schema and be handled by the panel plugin/renderer.
11
+ *
12
+ * `panel_c1` is a single shared node that accumulates extra block children over successive
13
+ * scenarios (table, expand, ...), each gated by its own experiment. Registration, node views,
14
+ * click handlers and insertion logic are all common to the node, so they should be active when
15
+ * ANY of those experiments is on.
16
+ *
17
+ * ```typescript
18
+ * if (isPanelC1SchemaEnabled()) {
19
+ * // register / handle panel_c1
20
+ * }
21
+ * ```
22
+ */
23
+ var isPanelC1SchemaEnabled = exports.isPanelC1SchemaEnabled = function isPanelC1SchemaEnabled() {
24
+ return (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) || (0, _expValEquals.expValEquals)('platform_editor_nest_expand_in_panel', 'isEnabled', true);
25
+ };
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isPanelNestingExpandSupported = void 0;
7
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
8
+ /*
9
+ * Returns true if the schema supports nesting an expand inside a panel (panel_c1 variant),
10
+ * AND the `platform_editor_nest_expand_in_panel` experiment is enabled.
11
+ *
12
+ * ```typescript
13
+ * const supportsExpandInPanel = isPanelNestingExpandSupported(state.schema);
14
+ * ```
15
+ */
16
+ var isPanelNestingExpandSupported = exports.isPanelNestingExpandSupported = function isPanelNestingExpandSupported(schema) {
17
+ var _panel_c1$contentMatc;
18
+ var _schema$nodes = schema.nodes,
19
+ expand = _schema$nodes.expand,
20
+ panel_c1 = _schema$nodes.panel_c1;
21
+ if (!expand || !panel_c1) {
22
+ return false;
23
+ }
24
+
25
+ // Confirm the PM schema actually allows expand inside panel_c1
26
+ var panelC1CanContainExpand = ((_panel_c1$contentMatc = panel_c1.contentMatch.matchType(expand)) === null || _panel_c1$contentMatc === void 0 ? void 0 : _panel_c1$contentMatc.validEnd) === true;
27
+ return panelC1CanContainExpand && (0, _expValEquals.expValEquals)('platform_editor_nest_expand_in_panel', 'isEnabled', true);
28
+ };
@@ -21,6 +21,18 @@ Object.defineProperty(exports, "isNestedTablesSupported", {
21
21
  return _isNestedTablesSupported.isNestedTablesSupported;
22
22
  }
23
23
  });
24
+ Object.defineProperty(exports, "isPanelC1SchemaEnabled", {
25
+ enumerable: true,
26
+ get: function get() {
27
+ return _isPanelC1SchemaEnabled.isPanelC1SchemaEnabled;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "isPanelNestingExpandSupported", {
31
+ enumerable: true,
32
+ get: function get() {
33
+ return _isPanelNestingExpandSupported.isPanelNestingExpandSupported;
34
+ }
35
+ });
24
36
  Object.defineProperty(exports, "isPanelNestingTableSupported", {
25
37
  enumerable: true,
26
38
  get: function get() {
@@ -37,4 +49,6 @@ var _getParentOfTypeCount = require("./getParentOfTypeCount");
37
49
  var _getPositionAfterTopParentNodeOfType = require("./getPositionAfterTopParentNodeOfType");
38
50
  var _isSelectionTableNestedInTable = require("./isSelectionTableNestedInTable");
39
51
  var _isNestedTablesSupported = require("./isNestedTablesSupported");
40
- var _isPanelNestingTableSupported = require("./isPanelNestingTableSupported");
52
+ var _isPanelNestingTableSupported = require("./isPanelNestingTableSupported");
53
+ var _isPanelNestingExpandSupported = require("./isPanelNestingExpandSupported");
54
+ var _isPanelC1SchemaEnabled = require("./isPanelC1SchemaEnabled");
@@ -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 = "116.49.0";
27
+ var packageVersion = "116.50.0";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -17,11 +17,18 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
17
17
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
18
18
  var _analytics = require("../analytics");
19
19
  var _isNestedTablesSupported = require("../nesting/isNestedTablesSupported");
20
+ var _isPanelNestingExpandSupported = require("../nesting/isPanelNestingExpandSupported");
20
21
  var _isPanelNestingTableSupported = require("../nesting/isPanelNestingTableSupported");
21
22
  var _privacyFilter = require("./filter/privacy-filter");
22
23
  var _trackUnsupportedContent = require("./track-unsupported-content");
23
24
  var _validateUsingSpec = require("./validate-using-spec");
24
25
  var _processRawFragmentValue = require("./processRawFragmentValue");
26
+ // Gate the generalised (table + expand) panel_c1 fallback behind the expand-in-panel
27
+ // experiment. The in-production table-in-panel path keeps using the deprecated table-only
28
+ // transform until platform_editor_nest_expand_in_panel is rolled out.
29
+ var runPanelC1FallbackTransform = function runPanelC1FallbackTransform(schema, adf) {
30
+ return (0, _expValEquals.expValEquals)('platform_editor_nest_expand_in_panel', 'isEnabled', true) ? (0, _transforms.panelC1FallbackTransformV2)(schema, adf) : (0, _transforms.panelC1FallbackTransform)(schema, adf);
31
+ };
25
32
  var transformNestedTablesWithAnalytics = function transformNestedTablesWithAnalytics(node, dispatchAnalyticsEvent) {
26
33
  try {
27
34
  var _transformNestedTable = (0, _transforms.transformNestedTablesIncomingDocument)(node),
@@ -100,6 +107,18 @@ var transformContainerNodesWithAnalytics = function transformContainerNodesWithA
100
107
  isTransformed: false
101
108
  };
102
109
  };
110
+
111
+ /**
112
+ * Converts a raw ADF value into a ProseMirror `Node` without running full ADF validation.
113
+ *
114
+ * Applies the relevant document transforms (nested tables, sync block and panel_c1 fallbacks,
115
+ * container node nesting) before building the node directly from the resulting JSON.
116
+ *
117
+ * @param schema - The ProseMirror schema to build the node against.
118
+ * @param value - The raw ADF value (string or object) to process.
119
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform analytics.
120
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or parsing fails.
121
+ */
103
122
  function processRawValueWithoutValidation(schema, value, dispatchAnalyticsEvent) {
104
123
  if (!value) {
105
124
  return;
@@ -125,7 +144,7 @@ function processRawValueWithoutValidation(schema, value, dispatchAnalyticsEvent)
125
144
  transformedAdf = result.transformedAdf;
126
145
  }
127
146
  if ((0, _platformFeatureFlags.fg)('platform_editor_panel_c1_fallback_transform')) {
128
- var panelC1Result = (0, _transforms.panelC1FallbackTransform)(schema, transformedAdf);
147
+ var panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
129
148
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
130
149
  transformedAdf = panelC1Result.transformedAdf;
131
150
  }
@@ -137,6 +156,20 @@ function processRawValueWithoutValidation(schema, value, dispatchAnalyticsEvent)
137
156
  return _model.Node.fromJSON(schema, transformedAdf);
138
157
  }
139
158
 
159
+ /**
160
+ * Converts a raw ADF value into a validated ProseMirror `Node`.
161
+ *
162
+ * Applies document transforms and validates the resulting ADF against the schema, tracking any
163
+ * unsupported content and optionally sanitizing private content before building the node.
164
+ *
165
+ * @param schema - The ProseMirror schema to build and validate the node against.
166
+ * @param value - The raw ADF value (string or object) to process.
167
+ * @param providerFactory - Optional provider factory used during validation/sanitization.
168
+ * @param sanitizePrivateContent - When `true`, private content is stripped from the document.
169
+ * @param contentTransformer - Optional transformer used to parse string content into ADF.
170
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform/validation analytics.
171
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or processing fails.
172
+ */
140
173
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
141
174
  function processRawValue(schema, value, providerFactory, sanitizePrivateContent, contentTransformer, dispatchAnalyticsEvent) {
142
175
  if (!value) {
@@ -291,7 +324,7 @@ function processRawValue(schema, value, providerFactory, sanitizePrivateContent,
291
324
  }
292
325
  }
293
326
  if ((0, _platformFeatureFlags.fg)('platform_editor_panel_c1_fallback_transform')) {
294
- var panelC1Result = (0, _transforms.panelC1FallbackTransform)(schema, transformedAdf);
327
+ var panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
295
328
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
296
329
  transformedAdf = panelC1Result.transformedAdf;
297
330
  }
@@ -301,9 +334,11 @@ function processRawValue(schema, value, providerFactory, sanitizePrivateContent,
301
334
  // This matches the renderer's behavior in render-document.ts
302
335
  var allowNestedTables = (0, _isNestedTablesSupported.isNestedTablesSupported)(schema);
303
336
  var allowTableInPanel = (0, _isPanelNestingTableSupported.isPanelNestingTableSupported)(schema);
304
- var validateADFEntityOptions = allowNestedTables || allowTableInPanel ? {
337
+ var allowExpandInPanel = (0, _isPanelNestingExpandSupported.isPanelNestingExpandSupported)(schema);
338
+ var validateADFEntityOptions = allowNestedTables || allowTableInPanel || allowExpandInPanel ? {
305
339
  allowNestedTables: allowNestedTables || undefined,
306
- allowTableInPanel: allowTableInPanel || undefined
340
+ allowTableInPanel: allowTableInPanel || undefined,
341
+ allowExpandInPanel: allowExpandInPanel || undefined
307
342
  } : undefined;
308
343
  var entity = (0, _validateUsingSpec.validateADFEntity)(schema, transformedAdf || node, dispatchAnalyticsEvent, validateADFEntityOptions);
309
344
 
@@ -311,7 +346,10 @@ function processRawValue(schema, value, providerFactory, sanitizePrivateContent,
311
346
  var _transformNestedTable3 = transformNestedTablesWithAnalytics(entity, dispatchAnalyticsEvent);
312
347
  transformedAdf = _transformNestedTable3.transformedAdf;
313
348
  entity = transformedAdf;
314
- if ((0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
349
+
350
+ // The container-node promotion (panel -> panel_c1) is schema-driven and shared across
351
+ // nesting scenarios, so it runs when any panel container-variant experiment is on.
352
+ if ((0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) || (0, _expValEquals.expValEquals)('platform_editor_nest_expand_in_panel', 'isEnabled', true)) {
315
353
  var _transformContainerNo3 = transformContainerNodesWithAnalytics(entity, schema, dispatchAnalyticsEvent);
316
354
  transformedAdf = _transformContainerNo3.transformedAdf;
317
355
  entity = transformedAdf;
@@ -23,7 +23,8 @@ var errorCallbackFor = function errorCallbackFor(marks, validate, dispatchAnalyt
23
23
  return function (entity, error, options) {
24
24
  return validationErrorHandler(entity, error, _objectSpread(_objectSpread({}, options), {}, {
25
25
  allowNestedTables: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowNestedTables,
26
- allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel
26
+ allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel,
27
+ allowExpandInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowExpandInPanel
27
28
  }), marks, validate, dispatchAnalyticsEvent);
28
29
  };
29
30
  };
@@ -101,6 +102,17 @@ var validationErrorHandler = exports.validationErrorHandler = function validatio
101
102
  return entity;
102
103
  }
103
104
  }
105
+
106
+ // panel_c1 is a ProseMirror-only variant: on save, expand-in-panel documents are stored as
107
+ // plain ADF `panel` nodes containing an `expand`. The base validator-spec does not permit
108
+ // `expand` inside `panel` (it's gated behind the experiment), so we suppress the
109
+ // INVALID_CONTENT error when the experiment is active.
110
+ if (options.allowExpandInPanel) {
111
+ var _meta2 = error.meta;
112
+ if ((_meta2 === null || _meta2 === void 0 ? void 0 : _meta2.parentType) === 'panel' && error.code === 'INVALID_CONTENT' && entity.type === 'expand') {
113
+ return entity;
114
+ }
115
+ }
104
116
  if (options.allowUnsupportedBlock) {
105
117
  return (0, _wrapWithUnsupported.wrapWithUnsupported)(entity);
106
118
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * [CCI-17994] Meta carried on the transaction that applies a batch of REMOTE
3
+ * agent-authored steps (BE streaming) in `editor-plugin-collab-edit`'s
4
+ * `applyRemoteSteps`. It lets `editor-plugin-ai` record the agent's changes for a
5
+ * Post Stream Review ("Review moment") WITHOUT collab-edit depending on the AI
6
+ * plugin: the contract is neutral and lives here in `editor-common`, which both
7
+ * plugins already depend on.
8
+ *
9
+ * Stamped whenever a received remote-step batch contains agent-authored steps.
10
+ * Consumed by `aiSessionContextPlugin.apply()`,
11
+ * which appends coarse `aiContentPositions` entries — exactly like the in-editor
12
+ * (FE) streaming path's `AI_FINAL_STREAMING_TRANSFORMATION_DATA`, so the whole
13
+ * downstream Review moment pipeline (merge → segment → diff → undo/redo → accept)
14
+ * is reused unchanged.
15
+ */
16
+ export const AGENT_REMOTE_EDIT_REVIEW_DATA = 'agentRemoteEditReviewData';
@@ -14,7 +14,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
14
14
  const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
15
15
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
16
16
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
17
- const packageVersion = "116.49.0";
17
+ const packageVersion = "116.50.0";
18
18
  const sanitiseSentryEvents = (data, _hint) => {
19
19
  // Remove URL as it has UGC
20
20
  // Ignored via go/ees007
@@ -0,0 +1,18 @@
1
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
+
3
+ /*
4
+ * Returns true when any panel container-variant nesting experiment is enabled, i.e. when the
5
+ * `panel_c1` node should exist in the schema and be handled by the panel plugin/renderer.
6
+ *
7
+ * `panel_c1` is a single shared node that accumulates extra block children over successive
8
+ * scenarios (table, expand, ...), each gated by its own experiment. Registration, node views,
9
+ * click handlers and insertion logic are all common to the node, so they should be active when
10
+ * ANY of those experiments is on.
11
+ *
12
+ * ```typescript
13
+ * if (isPanelC1SchemaEnabled()) {
14
+ * // register / handle panel_c1
15
+ * }
16
+ * ```
17
+ */
18
+ export const isPanelC1SchemaEnabled = () => expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) || expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true);
@@ -0,0 +1,24 @@
1
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
+
3
+ /*
4
+ * Returns true if the schema supports nesting an expand inside a panel (panel_c1 variant),
5
+ * AND the `platform_editor_nest_expand_in_panel` experiment is enabled.
6
+ *
7
+ * ```typescript
8
+ * const supportsExpandInPanel = isPanelNestingExpandSupported(state.schema);
9
+ * ```
10
+ */
11
+ export const isPanelNestingExpandSupported = schema => {
12
+ var _panel_c1$contentMatc;
13
+ const {
14
+ expand,
15
+ panel_c1
16
+ } = schema.nodes;
17
+ if (!expand || !panel_c1) {
18
+ return false;
19
+ }
20
+
21
+ // Confirm the PM schema actually allows expand inside panel_c1
22
+ const panelC1CanContainExpand = ((_panel_c1$contentMatc = panel_c1.contentMatch.matchType(expand)) === null || _panel_c1$contentMatc === void 0 ? void 0 : _panel_c1$contentMatc.validEnd) === true;
23
+ return panelC1CanContainExpand && expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true);
24
+ };
@@ -7,4 +7,8 @@ export { isSelectionTableNestedInTable } from './isSelectionTableNestedInTable';
7
7
  // eslint-disable-next-line @atlaskit/editor/no-re-export
8
8
  export { isNestedTablesSupported } from './isNestedTablesSupported';
9
9
  // eslint-disable-next-line @atlaskit/editor/no-re-export
10
- export { isPanelNestingTableSupported } from './isPanelNestingTableSupported';
10
+ export { isPanelNestingTableSupported } from './isPanelNestingTableSupported';
11
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
12
+ export { isPanelNestingExpandSupported } from './isPanelNestingExpandSupported';
13
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
14
+ export { isPanelC1SchemaEnabled } from './isPanelC1SchemaEnabled';
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "116.49.0";
17
+ const packageVersion = "116.50.0";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -1,13 +1,19 @@
1
- import { panelC1FallbackTransform, syncBlockFallbackTransform, transformDedupeMarks, transformIndentationMarks, transformInvalidMediaContent, transformMediaLinkMarks, transformNestedTablesIncomingDocument, transformNodesMissingContent, transformTextLinkCodeMarks, transformMediaSingleWidth, transformContainerNodes } from '@atlaskit/adf-utils/transforms';
1
+ import { panelC1FallbackTransform, panelC1FallbackTransformV2, syncBlockFallbackTransform, transformDedupeMarks, transformIndentationMarks, transformInvalidMediaContent, transformMediaLinkMarks, transformNestedTablesIncomingDocument, transformNodesMissingContent, transformTextLinkCodeMarks, transformMediaSingleWidth, transformContainerNodes } from '@atlaskit/adf-utils/transforms';
2
2
  import { Node } from '@atlaskit/editor-prosemirror/model';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
5
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../analytics';
6
6
  import { isNestedTablesSupported } from '../nesting/isNestedTablesSupported';
7
+ import { isPanelNestingExpandSupported } from '../nesting/isPanelNestingExpandSupported';
7
8
  import { isPanelNestingTableSupported } from '../nesting/isPanelNestingTableSupported';
8
9
  import { sanitizeNodeForPrivacy } from './filter/privacy-filter';
9
10
  import { findAndTrackUnsupportedContentNodes } from './track-unsupported-content';
10
11
  import { validateADFEntity } from './validate-using-spec';
12
+
13
+ // Gate the generalised (table + expand) panel_c1 fallback behind the expand-in-panel
14
+ // experiment. The in-production table-in-panel path keeps using the deprecated table-only
15
+ // transform until platform_editor_nest_expand_in_panel is rolled out.
16
+ const runPanelC1FallbackTransform = (schema, adf) => expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true) ? panelC1FallbackTransformV2(schema, adf) : panelC1FallbackTransform(schema, adf);
11
17
  const transformNestedTablesWithAnalytics = (node, dispatchAnalyticsEvent) => {
12
18
  try {
13
19
  const {
@@ -88,6 +94,18 @@ const transformContainerNodesWithAnalytics = (node, schema, dispatchAnalyticsEve
88
94
  isTransformed: false
89
95
  };
90
96
  };
97
+
98
+ /**
99
+ * Converts a raw ADF value into a ProseMirror `Node` without running full ADF validation.
100
+ *
101
+ * Applies the relevant document transforms (nested tables, sync block and panel_c1 fallbacks,
102
+ * container node nesting) before building the node directly from the resulting JSON.
103
+ *
104
+ * @param schema - The ProseMirror schema to build the node against.
105
+ * @param value - The raw ADF value (string or object) to process.
106
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform analytics.
107
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or parsing fails.
108
+ */
91
109
  export function processRawValueWithoutValidation(schema, value, dispatchAnalyticsEvent) {
92
110
  if (!value) {
93
111
  return;
@@ -114,7 +132,7 @@ export function processRawValueWithoutValidation(schema, value, dispatchAnalytic
114
132
  transformedAdf = result.transformedAdf;
115
133
  }
116
134
  if (fg('platform_editor_panel_c1_fallback_transform')) {
117
- const panelC1Result = panelC1FallbackTransform(schema, transformedAdf);
135
+ const panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
118
136
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
119
137
  transformedAdf = panelC1Result.transformedAdf;
120
138
  }
@@ -127,6 +145,20 @@ export function processRawValueWithoutValidation(schema, value, dispatchAnalytic
127
145
  return Node.fromJSON(schema, transformedAdf);
128
146
  }
129
147
 
148
+ /**
149
+ * Converts a raw ADF value into a validated ProseMirror `Node`.
150
+ *
151
+ * Applies document transforms and validates the resulting ADF against the schema, tracking any
152
+ * unsupported content and optionally sanitizing private content before building the node.
153
+ *
154
+ * @param schema - The ProseMirror schema to build and validate the node against.
155
+ * @param value - The raw ADF value (string or object) to process.
156
+ * @param providerFactory - Optional provider factory used during validation/sanitization.
157
+ * @param sanitizePrivateContent - When `true`, private content is stripped from the document.
158
+ * @param contentTransformer - Optional transformer used to parse string content into ADF.
159
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform/validation analytics.
160
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or processing fails.
161
+ */
130
162
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
131
163
  export function processRawValue(schema, value, providerFactory, sanitizePrivateContent, contentTransformer, dispatchAnalyticsEvent) {
132
164
  if (!value) {
@@ -286,7 +318,7 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
286
318
  }
287
319
  }
288
320
  if (fg('platform_editor_panel_c1_fallback_transform')) {
289
- const panelC1Result = panelC1FallbackTransform(schema, transformedAdf);
321
+ const panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
290
322
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
291
323
  transformedAdf = panelC1Result.transformedAdf;
292
324
  }
@@ -296,9 +328,11 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
296
328
  // This matches the renderer's behavior in render-document.ts
297
329
  const allowNestedTables = isNestedTablesSupported(schema);
298
330
  const allowTableInPanel = isPanelNestingTableSupported(schema);
299
- const validateADFEntityOptions = allowNestedTables || allowTableInPanel ? {
331
+ const allowExpandInPanel = isPanelNestingExpandSupported(schema);
332
+ const validateADFEntityOptions = allowNestedTables || allowTableInPanel || allowExpandInPanel ? {
300
333
  allowNestedTables: allowNestedTables || undefined,
301
- allowTableInPanel: allowTableInPanel || undefined
334
+ allowTableInPanel: allowTableInPanel || undefined,
335
+ allowExpandInPanel: allowExpandInPanel || undefined
302
336
  } : undefined;
303
337
  let entity = validateADFEntity(schema, transformedAdf || node, dispatchAnalyticsEvent, validateADFEntityOptions);
304
338
 
@@ -307,7 +341,10 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
307
341
  transformedAdf
308
342
  } = transformNestedTablesWithAnalytics(entity, dispatchAnalyticsEvent));
309
343
  entity = transformedAdf;
310
- if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
344
+
345
+ // The container-node promotion (panel -> panel_c1) is schema-driven and shared across
346
+ // nesting scenarios, so it runs when any panel container-variant experiment is on.
347
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) || expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true)) {
311
348
  ({
312
349
  transformedAdf
313
350
  } = transformContainerNodesWithAnalytics(entity, schema, dispatchAnalyticsEvent));
@@ -8,7 +8,8 @@ const errorCallbackFor = (marks, validate, dispatchAnalyticsEvent, validationOve
8
8
  return validationErrorHandler(entity, error, {
9
9
  ...options,
10
10
  allowNestedTables: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowNestedTables,
11
- allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel
11
+ allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel,
12
+ allowExpandInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowExpandInPanel
12
13
  }, marks, validate, dispatchAnalyticsEvent);
13
14
  };
14
15
  };
@@ -86,6 +87,17 @@ export const validationErrorHandler = (entity, error, options, marks, validate,
86
87
  return entity;
87
88
  }
88
89
  }
90
+
91
+ // panel_c1 is a ProseMirror-only variant: on save, expand-in-panel documents are stored as
92
+ // plain ADF `panel` nodes containing an `expand`. The base validator-spec does not permit
93
+ // `expand` inside `panel` (it's gated behind the experiment), so we suppress the
94
+ // INVALID_CONTENT error when the experiment is active.
95
+ if (options.allowExpandInPanel) {
96
+ const meta = error.meta;
97
+ if ((meta === null || meta === void 0 ? void 0 : meta.parentType) === 'panel' && error.code === 'INVALID_CONTENT' && entity.type === 'expand') {
98
+ return entity;
99
+ }
100
+ }
89
101
  if (options.allowUnsupportedBlock) {
90
102
  return wrapWithUnsupported(entity);
91
103
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * [CCI-17994] Meta carried on the transaction that applies a batch of REMOTE
3
+ * agent-authored steps (BE streaming) in `editor-plugin-collab-edit`'s
4
+ * `applyRemoteSteps`. It lets `editor-plugin-ai` record the agent's changes for a
5
+ * Post Stream Review ("Review moment") WITHOUT collab-edit depending on the AI
6
+ * plugin: the contract is neutral and lives here in `editor-common`, which both
7
+ * plugins already depend on.
8
+ *
9
+ * Stamped whenever a received remote-step batch contains agent-authored steps.
10
+ * Consumed by `aiSessionContextPlugin.apply()`,
11
+ * which appends coarse `aiContentPositions` entries — exactly like the in-editor
12
+ * (FE) streaming path's `AI_FINAL_STREAMING_TRANSFORMATION_DATA`, so the whole
13
+ * downstream Review moment pipeline (merge → segment → diff → undo/redo → accept)
14
+ * is reused unchanged.
15
+ */
16
+ export var AGENT_REMOTE_EDIT_REVIEW_DATA = 'agentRemoteEditReviewData';
@@ -20,7 +20,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
20
20
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
21
21
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
22
22
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
23
- var packageVersion = "116.49.0";
23
+ var packageVersion = "116.50.0";
24
24
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
25
25
  // Remove URL as it has UGC
26
26
  // Ignored via go/ees007
@@ -0,0 +1,20 @@
1
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
+
3
+ /*
4
+ * Returns true when any panel container-variant nesting experiment is enabled, i.e. when the
5
+ * `panel_c1` node should exist in the schema and be handled by the panel plugin/renderer.
6
+ *
7
+ * `panel_c1` is a single shared node that accumulates extra block children over successive
8
+ * scenarios (table, expand, ...), each gated by its own experiment. Registration, node views,
9
+ * click handlers and insertion logic are all common to the node, so they should be active when
10
+ * ANY of those experiments is on.
11
+ *
12
+ * ```typescript
13
+ * if (isPanelC1SchemaEnabled()) {
14
+ * // register / handle panel_c1
15
+ * }
16
+ * ```
17
+ */
18
+ export var isPanelC1SchemaEnabled = function isPanelC1SchemaEnabled() {
19
+ return expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) || expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true);
20
+ };
@@ -0,0 +1,23 @@
1
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
2
+
3
+ /*
4
+ * Returns true if the schema supports nesting an expand inside a panel (panel_c1 variant),
5
+ * AND the `platform_editor_nest_expand_in_panel` experiment is enabled.
6
+ *
7
+ * ```typescript
8
+ * const supportsExpandInPanel = isPanelNestingExpandSupported(state.schema);
9
+ * ```
10
+ */
11
+ export var isPanelNestingExpandSupported = function isPanelNestingExpandSupported(schema) {
12
+ var _panel_c1$contentMatc;
13
+ var _schema$nodes = schema.nodes,
14
+ expand = _schema$nodes.expand,
15
+ panel_c1 = _schema$nodes.panel_c1;
16
+ if (!expand || !panel_c1) {
17
+ return false;
18
+ }
19
+
20
+ // Confirm the PM schema actually allows expand inside panel_c1
21
+ var panelC1CanContainExpand = ((_panel_c1$contentMatc = panel_c1.contentMatch.matchType(expand)) === null || _panel_c1$contentMatc === void 0 ? void 0 : _panel_c1$contentMatc.validEnd) === true;
22
+ return panelC1CanContainExpand && expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true);
23
+ };
@@ -7,4 +7,8 @@ export { isSelectionTableNestedInTable } from './isSelectionTableNestedInTable';
7
7
  // eslint-disable-next-line @atlaskit/editor/no-re-export
8
8
  export { isNestedTablesSupported } from './isNestedTablesSupported';
9
9
  // eslint-disable-next-line @atlaskit/editor/no-re-export
10
- export { isPanelNestingTableSupported } from './isPanelNestingTableSupported';
10
+ export { isPanelNestingTableSupported } from './isPanelNestingTableSupported';
11
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
12
+ export { isPanelNestingExpandSupported } from './isPanelNestingExpandSupported';
13
+ // eslint-disable-next-line @atlaskit/editor/no-re-export
14
+ export { isPanelC1SchemaEnabled } from './isPanelC1SchemaEnabled';
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import { fg } from '@atlaskit/platform-feature-flags';
22
22
  import Layer from '../Layer';
23
23
  var packageName = "@atlaskit/editor-common";
24
- var packageVersion = "116.49.0";
24
+ var packageVersion = "116.50.0";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -1,13 +1,21 @@
1
- import { panelC1FallbackTransform, syncBlockFallbackTransform, transformDedupeMarks, transformIndentationMarks, transformInvalidMediaContent, transformMediaLinkMarks, transformNestedTablesIncomingDocument, transformNodesMissingContent, transformTextLinkCodeMarks, transformMediaSingleWidth, transformContainerNodes } from '@atlaskit/adf-utils/transforms';
1
+ import { panelC1FallbackTransform, panelC1FallbackTransformV2, syncBlockFallbackTransform, transformDedupeMarks, transformIndentationMarks, transformInvalidMediaContent, transformMediaLinkMarks, transformNestedTablesIncomingDocument, transformNodesMissingContent, transformTextLinkCodeMarks, transformMediaSingleWidth, transformContainerNodes } from '@atlaskit/adf-utils/transforms';
2
2
  import { Node } from '@atlaskit/editor-prosemirror/model';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
5
  import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '../analytics';
6
6
  import { isNestedTablesSupported } from '../nesting/isNestedTablesSupported';
7
+ import { isPanelNestingExpandSupported } from '../nesting/isPanelNestingExpandSupported';
7
8
  import { isPanelNestingTableSupported } from '../nesting/isPanelNestingTableSupported';
8
9
  import { sanitizeNodeForPrivacy } from './filter/privacy-filter';
9
10
  import { findAndTrackUnsupportedContentNodes } from './track-unsupported-content';
10
11
  import { validateADFEntity } from './validate-using-spec';
12
+
13
+ // Gate the generalised (table + expand) panel_c1 fallback behind the expand-in-panel
14
+ // experiment. The in-production table-in-panel path keeps using the deprecated table-only
15
+ // transform until platform_editor_nest_expand_in_panel is rolled out.
16
+ var runPanelC1FallbackTransform = function runPanelC1FallbackTransform(schema, adf) {
17
+ return expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true) ? panelC1FallbackTransformV2(schema, adf) : panelC1FallbackTransform(schema, adf);
18
+ };
11
19
  var transformNestedTablesWithAnalytics = function transformNestedTablesWithAnalytics(node, dispatchAnalyticsEvent) {
12
20
  try {
13
21
  var _transformNestedTable = transformNestedTablesIncomingDocument(node),
@@ -86,6 +94,18 @@ var transformContainerNodesWithAnalytics = function transformContainerNodesWithA
86
94
  isTransformed: false
87
95
  };
88
96
  };
97
+
98
+ /**
99
+ * Converts a raw ADF value into a ProseMirror `Node` without running full ADF validation.
100
+ *
101
+ * Applies the relevant document transforms (nested tables, sync block and panel_c1 fallbacks,
102
+ * container node nesting) before building the node directly from the resulting JSON.
103
+ *
104
+ * @param schema - The ProseMirror schema to build the node against.
105
+ * @param value - The raw ADF value (string or object) to process.
106
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform analytics.
107
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or parsing fails.
108
+ */
89
109
  export function processRawValueWithoutValidation(schema, value, dispatchAnalyticsEvent) {
90
110
  if (!value) {
91
111
  return;
@@ -111,7 +131,7 @@ export function processRawValueWithoutValidation(schema, value, dispatchAnalytic
111
131
  transformedAdf = result.transformedAdf;
112
132
  }
113
133
  if (fg('platform_editor_panel_c1_fallback_transform')) {
114
- var panelC1Result = panelC1FallbackTransform(schema, transformedAdf);
134
+ var panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
115
135
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
116
136
  transformedAdf = panelC1Result.transformedAdf;
117
137
  }
@@ -123,6 +143,20 @@ export function processRawValueWithoutValidation(schema, value, dispatchAnalytic
123
143
  return Node.fromJSON(schema, transformedAdf);
124
144
  }
125
145
 
146
+ /**
147
+ * Converts a raw ADF value into a validated ProseMirror `Node`.
148
+ *
149
+ * Applies document transforms and validates the resulting ADF against the schema, tracking any
150
+ * unsupported content and optionally sanitizing private content before building the node.
151
+ *
152
+ * @param schema - The ProseMirror schema to build and validate the node against.
153
+ * @param value - The raw ADF value (string or object) to process.
154
+ * @param providerFactory - Optional provider factory used during validation/sanitization.
155
+ * @param sanitizePrivateContent - When `true`, private content is stripped from the document.
156
+ * @param contentTransformer - Optional transformer used to parse string content into ADF.
157
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform/validation analytics.
158
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or processing fails.
159
+ */
126
160
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
127
161
  export function processRawValue(schema, value, providerFactory, sanitizePrivateContent, contentTransformer, dispatchAnalyticsEvent) {
128
162
  if (!value) {
@@ -277,7 +311,7 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
277
311
  }
278
312
  }
279
313
  if (fg('platform_editor_panel_c1_fallback_transform')) {
280
- var panelC1Result = panelC1FallbackTransform(schema, transformedAdf);
314
+ var panelC1Result = runPanelC1FallbackTransform(schema, transformedAdf);
281
315
  if (panelC1Result.isTransformed && panelC1Result.transformedAdf) {
282
316
  transformedAdf = panelC1Result.transformedAdf;
283
317
  }
@@ -287,9 +321,11 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
287
321
  // This matches the renderer's behavior in render-document.ts
288
322
  var allowNestedTables = isNestedTablesSupported(schema);
289
323
  var allowTableInPanel = isPanelNestingTableSupported(schema);
290
- var validateADFEntityOptions = allowNestedTables || allowTableInPanel ? {
324
+ var allowExpandInPanel = isPanelNestingExpandSupported(schema);
325
+ var validateADFEntityOptions = allowNestedTables || allowTableInPanel || allowExpandInPanel ? {
291
326
  allowNestedTables: allowNestedTables || undefined,
292
- allowTableInPanel: allowTableInPanel || undefined
327
+ allowTableInPanel: allowTableInPanel || undefined,
328
+ allowExpandInPanel: allowExpandInPanel || undefined
293
329
  } : undefined;
294
330
  var entity = validateADFEntity(schema, transformedAdf || node, dispatchAnalyticsEvent, validateADFEntityOptions);
295
331
 
@@ -297,7 +333,10 @@ export function processRawValue(schema, value, providerFactory, sanitizePrivateC
297
333
  var _transformNestedTable3 = transformNestedTablesWithAnalytics(entity, dispatchAnalyticsEvent);
298
334
  transformedAdf = _transformNestedTable3.transformedAdf;
299
335
  entity = transformedAdf;
300
- if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true)) {
336
+
337
+ // The container-node promotion (panel -> panel_c1) is schema-driven and shared across
338
+ // nesting scenarios, so it runs when any panel container-variant experiment is on.
339
+ if (expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) || expValEquals('platform_editor_nest_expand_in_panel', 'isEnabled', true)) {
301
340
  var _transformContainerNo3 = transformContainerNodesWithAnalytics(entity, schema, dispatchAnalyticsEvent);
302
341
  transformedAdf = _transformContainerNo3.transformedAdf;
303
342
  entity = transformedAdf;
@@ -10,7 +10,8 @@ var errorCallbackFor = function errorCallbackFor(marks, validate, dispatchAnalyt
10
10
  return function (entity, error, options) {
11
11
  return validationErrorHandler(entity, error, _objectSpread(_objectSpread({}, options), {}, {
12
12
  allowNestedTables: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowNestedTables,
13
- allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel
13
+ allowTableInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowTableInPanel,
14
+ allowExpandInPanel: validationOverrides === null || validationOverrides === void 0 ? void 0 : validationOverrides.allowExpandInPanel
14
15
  }), marks, validate, dispatchAnalyticsEvent);
15
16
  };
16
17
  };
@@ -88,6 +89,17 @@ export var validationErrorHandler = function validationErrorHandler(entity, erro
88
89
  return entity;
89
90
  }
90
91
  }
92
+
93
+ // panel_c1 is a ProseMirror-only variant: on save, expand-in-panel documents are stored as
94
+ // plain ADF `panel` nodes containing an `expand`. The base validator-spec does not permit
95
+ // `expand` inside `panel` (it's gated behind the experiment), so we suppress the
96
+ // INVALID_CONTENT error when the experiment is active.
97
+ if (options.allowExpandInPanel) {
98
+ var _meta2 = error.meta;
99
+ if ((_meta2 === null || _meta2 === void 0 ? void 0 : _meta2.parentType) === 'panel' && error.code === 'INVALID_CONTENT' && entity.type === 'expand') {
100
+ return entity;
101
+ }
102
+ }
91
103
  if (options.allowUnsupportedBlock) {
92
104
  return wrapWithUnsupported(entity);
93
105
  }
@@ -36,6 +36,7 @@ type AcceptSuggestionAEP = TrackAEP<ACTION.ACCEPTED, ACTION_SUBJECT.AI_SUGGESTIO
36
36
  suggestionType: string;
37
37
  }, undefined>;
38
38
  type DiscardSuggestionAEP = TrackAEP<ACTION.DISCARDED, ACTION_SUBJECT.AI_SUGGESTIONS, undefined, {
39
+ actionKind: string;
39
40
  affectedBlocks: number;
40
41
  interactionPoint: AiSuggestionInteractionPoint;
41
42
  suggestionType: string;
@@ -46,6 +47,7 @@ type DismissSuggestionAEP = TrackAEP<ACTION.DISMISSED, ACTION_SUBJECT.AI_SUGGEST
46
47
  suggestionType: string;
47
48
  }, undefined>;
48
49
  type ViewSuggestionAEP = TrackAEP<ACTION.VIEWED, ACTION_SUBJECT.AI_SUGGESTIONS, undefined, {
50
+ actionKind: string;
49
51
  affectedBlocks: number;
50
52
  blockTypes: string[];
51
53
  charactersToAdd: number;
@@ -0,0 +1,58 @@
1
+ import type { Slice } from '@atlaskit/editor-prosemirror/model';
2
+ /**
3
+ * [CCI-17994] Meta carried on the transaction that applies a batch of REMOTE
4
+ * agent-authored steps (BE streaming) in `editor-plugin-collab-edit`'s
5
+ * `applyRemoteSteps`. It lets `editor-plugin-ai` record the agent's changes for a
6
+ * Post Stream Review ("Review moment") WITHOUT collab-edit depending on the AI
7
+ * plugin: the contract is neutral and lives here in `editor-common`, which both
8
+ * plugins already depend on.
9
+ *
10
+ * Stamped whenever a received remote-step batch contains agent-authored steps.
11
+ * Consumed by `aiSessionContextPlugin.apply()`,
12
+ * which appends coarse `aiContentPositions` entries — exactly like the in-editor
13
+ * (FE) streaming path's `AI_FINAL_STREAMING_TRANSFORMATION_DATA`, so the whole
14
+ * downstream Review moment pipeline (merge → segment → diff → undo/redo → accept)
15
+ * is reused unchanged.
16
+ */
17
+ export declare const AGENT_REMOTE_EDIT_REVIEW_DATA = "agentRemoteEditReviewData";
18
+ export interface AgentRemoteEditReviewSegment {
19
+ /** Live-doc end of the change after the batch applied. A `remove` is zero-width (`endPos === startPos`). */
20
+ endPos: number;
21
+ /**
22
+ * Derived from the slice pair: empty original ⇒ `add`, empty new ⇒ `remove`,
23
+ * else `update`. Carried so the consumer does not re-derive it.
24
+ */
25
+ kind: 'add' | 'remove' | 'update';
26
+ /** Content now at [startPos, endPos] AFTER the batch (the agent's content; for redo). */
27
+ newSlice: Slice;
28
+ /** Content that was at the range BEFORE the batch (for undo / "compare with original"). */
29
+ originalSlice: Slice;
30
+ /** Live-doc start of the change after the batch applied. */
31
+ startPos: number;
32
+ }
33
+ export interface AgentRemoteEditReviewData {
34
+ /**
35
+ * AAID the agent acted on behalf of (the requester), read from the agent
36
+ * steps' `userId`. The AI plugin opens the Review moment only on the client
37
+ * whose local user matches this — so only the requester reviews. `undefined`
38
+ * when the batch carried no attributable user.
39
+ */
40
+ actorUserId?: string;
41
+ /**
42
+ * Identifier of the specific agent that authored the batch, from the agent
43
+ * steps' `agentId`. Additive on the steps contract, so it may be absent. Not
44
+ * consumed yet — carried so the contract is explicit, and so a future
45
+ * multi-agent Review moment can attribute each change to the agent that made
46
+ * it (`agentType` alone cannot distinguish two agents of the same kind).
47
+ */
48
+ agentId?: string;
49
+ /** The agent kind (e.g. `'mcp'` | `'twg'`), from the agent steps' `agentType`. */
50
+ agentType?: string;
51
+ /**
52
+ * Hybrid end-of-edit signal. When the BE/NCS marks a batch as the terminal one
53
+ * of an agent edit, the AI plugin opens the Review moment immediately instead of
54
+ * waiting for the idle debounce. `false`/absent ⇒ rely on the debounce.
55
+ */
56
+ complete?: boolean;
57
+ segments: AgentRemoteEditReviewSegment[];
58
+ }
@@ -0,0 +1 @@
1
+ export declare const isPanelC1SchemaEnabled: () => boolean;
@@ -0,0 +1,2 @@
1
+ import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
+ export declare const isPanelNestingExpandSupported: (schema: Schema) => boolean;
@@ -3,3 +3,5 @@ export { getPositionAfterTopParentNodeOfType } from './getPositionAfterTopParent
3
3
  export { isSelectionTableNestedInTable } from './isSelectionTableNestedInTable';
4
4
  export { isNestedTablesSupported } from './isNestedTablesSupported';
5
5
  export { isPanelNestingTableSupported } from './isPanelNestingTableSupported';
6
+ export { isPanelNestingExpandSupported } from './isPanelNestingExpandSupported';
7
+ export { isPanelC1SchemaEnabled } from './isPanelC1SchemaEnabled';
@@ -3,6 +3,31 @@ import type { Schema } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { DispatchAnalyticsEvent } from '../analytics';
4
4
  import type { ProviderFactory } from '../provider-factory';
5
5
  import type { ReplaceRawValue, Transformer } from '../types';
6
+ /**
7
+ * Converts a raw ADF value into a ProseMirror `Node` without running full ADF validation.
8
+ *
9
+ * Applies the relevant document transforms (nested tables, sync block and panel_c1 fallbacks,
10
+ * container node nesting) before building the node directly from the resulting JSON.
11
+ *
12
+ * @param schema - The ProseMirror schema to build the node against.
13
+ * @param value - The raw ADF value (string or object) to process.
14
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform analytics.
15
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or parsing fails.
16
+ */
6
17
  export declare function processRawValueWithoutValidation(schema: Schema, value?: ReplaceRawValue, dispatchAnalyticsEvent?: DispatchAnalyticsEvent): Node | undefined;
18
+ /**
19
+ * Converts a raw ADF value into a validated ProseMirror `Node`.
20
+ *
21
+ * Applies document transforms and validates the resulting ADF against the schema, tracking any
22
+ * unsupported content and optionally sanitizing private content before building the node.
23
+ *
24
+ * @param schema - The ProseMirror schema to build and validate the node against.
25
+ * @param value - The raw ADF value (string or object) to process.
26
+ * @param providerFactory - Optional provider factory used during validation/sanitization.
27
+ * @param sanitizePrivateContent - When `true`, private content is stripped from the document.
28
+ * @param contentTransformer - Optional transformer used to parse string content into ADF.
29
+ * @param dispatchAnalyticsEvent - Optional callback used to report transform/validation analytics.
30
+ * @returns The resulting ProseMirror `Node`, or `undefined` when no value is provided or processing fails.
31
+ */
7
32
  export declare function processRawValue(schema: Schema, value?: ReplaceRawValue, providerFactory?: ProviderFactory, sanitizePrivateContent?: boolean, contentTransformer?: Transformer<string>, dispatchAnalyticsEvent?: DispatchAnalyticsEvent): Node | undefined;
8
33
  export { processRawFragmentValue } from './processRawFragmentValue';
@@ -13,5 +13,6 @@ export declare const validationErrorHandler: (entity: ADFEntity, error: Validati
13
13
  export declare const validateADFEntity: (schema: Schema, node: ADFEntity, dispatchAnalyticsEvent?: DispatchAnalyticsEvent, validationOverrides?: {
14
14
  allowNestedTables?: boolean;
15
15
  allowTableInPanel?: boolean;
16
+ allowExpandInPanel?: boolean;
16
17
  }) => ADFEntity;
17
18
  export { wrapWithUnsupported } from './wrapWithUnsupported';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "116.50.0",
3
+ "version": "116.51.0",
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/"
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@atlaskit/activity-provider": "^3.0.0",
32
- "@atlaskit/adf-schema": "^56.4.0",
33
- "@atlaskit/adf-utils": "^20.4.0",
32
+ "@atlaskit/adf-schema": "^56.5.0",
33
+ "@atlaskit/adf-utils": "^20.5.0",
34
34
  "@atlaskit/afm-i18n-platform-editor-editor-common": "2.200.0",
35
35
  "@atlaskit/analytics-listeners": "^11.1.0",
36
36
  "@atlaskit/analytics-namespaced-context": "^8.1.0",
@@ -81,7 +81,7 @@
81
81
  "@atlaskit/task-decision": "^21.8.0",
82
82
  "@atlaskit/teams-app-config": "^2.1.0",
83
83
  "@atlaskit/textfield": "^9.1.0",
84
- "@atlaskit/tmp-editor-statsig": "^136.1.0",
84
+ "@atlaskit/tmp-editor-statsig": "^136.2.0",
85
85
  "@atlaskit/tokens": "^16.3.0",
86
86
  "@atlaskit/tooltip": "^24.0.0",
87
87
  "@atlaskit/width-detector": "^6.2.0",