@atlaskit/editor-plugin-paste 10.0.0 → 11.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @atlaskit/editor-plugin-paste
2
2
 
3
+ ## 11.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [`901c87a57486e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/901c87a57486e) -
8
+ Removed `react-intl-next` alias and replaced all usages with `react-intl` directly.
9
+
10
+ What changed: The `react-intl-next` npm alias (which resolved to `react-intl@^5`) has been
11
+ removed. All imports now reference `react-intl` directly, and `peerDependencies` have been updated
12
+ to `"^5.25.1 || ^6.0.0 || ^7.0.0"`.
13
+
14
+ How consumer should update their code: Ensure `react-intl` is installed at a version satisfying
15
+ `^5.25.1 || ^6.0.0 || ^7.0.0`. If your application was using `react-intl-next` as an npm alias, it
16
+ can be safely removed. Replace any remaining `react-intl-next` imports with `react-intl`.
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
22
+ ## 10.0.1
23
+
24
+ ### Patch Changes
25
+
26
+ - [`bae5d569f660c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/bae5d569f660c) -
27
+ Prevent flexible list creation when platform_editor_flexible_list_schema is on but
28
+ platform_editor_flexible_list_indentation is off. Slice normalisation in paste pipeline.
29
+ appendTransaction normaliser in list plugin.
30
+
31
+ Paste plugin detects list-into-list paste and sets a transaction meta to skip closeHistory,
32
+ keeping the paste and normalisation appendTransaction as a single undo step.
33
+
34
+ - Updated dependencies
35
+
3
36
  ## 10.0.0
4
37
 
5
38
  ### Patch Changes
@@ -29,6 +29,7 @@ var _insm = require("@atlaskit/insm");
29
29
  var _mediaCommon = require("@atlaskit/media-common");
30
30
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
31
31
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
32
+ var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
32
33
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
33
34
  var _actions = require("../editor-actions/actions");
34
35
  var _commands = require("../editor-commands/commands");
@@ -44,6 +45,30 @@ var _tinyMCE = require("./util/tinyMCE");
44
45
  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; } } }; }
45
46
  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; } }
46
47
  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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
48
+ function isListIntoListPaste(tr, state) {
49
+ var _state$schema$nodes = state.schema.nodes,
50
+ listItem = _state$schema$nodes.listItem,
51
+ bulletList = _state$schema$nodes.bulletList,
52
+ orderedList = _state$schema$nodes.orderedList;
53
+ var _state$selection = state.selection,
54
+ $from = _state$selection.$from,
55
+ $to = _state$selection.$to;
56
+ var selectionInList = !!(0, _utils2.findParentNodeOfTypeClosestToPos)($from, [listItem]) || !!(0, _utils2.findParentNodeOfTypeClosestToPos)($to, [listItem]);
57
+ if (!selectionInList) {
58
+ return false;
59
+ }
60
+ return tr.steps.some(function (step) {
61
+ var _slice$content;
62
+ var slice = (0, _utils.extractSliceFromStep)(step);
63
+ var listExists = false;
64
+ slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 || _slice$content.forEach(function (node) {
65
+ if (node.type === bulletList || node.type === orderedList) {
66
+ listExists = true;
67
+ }
68
+ });
69
+ return listExists;
70
+ });
71
+ }
47
72
  var isInsideBlockQuote = exports.isInsideBlockQuote = function isInsideBlockQuote(state) {
48
73
  var blockquote = state.schema.nodes.blockquote;
49
74
  return (0, _utils2.hasParentNodeOfType)(blockquote)(state.selection);
@@ -282,17 +307,25 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
282
307
  // to split those repairing transactions in prosemirror-history when they're being added to the
283
308
  // "done" stack
284
309
  var isPastingTable = tr.steps.some(function (step) {
285
- var _slice$content;
310
+ var _slice$content2;
286
311
  var slice = (0, _utils.extractSliceFromStep)(step);
287
312
  var tableExists = false;
288
- slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 || _slice$content.forEach(function (node) {
313
+ slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || _slice$content2.forEach(function (node) {
289
314
  if (node.type === state.schema.nodes.table) {
290
315
  tableExists = true;
291
316
  }
292
317
  });
293
318
  return tableExists;
294
319
  });
295
- if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
320
+
321
+ // Don't add closeHistory if we're pasting a list into a list, as the list plugin will
322
+ // appendTransaction to normalise the list structure and we want to keep the paste and
323
+ // normalisation as one undo event. We also set a meta on the transaction so the list
324
+ // plugin's appendTransaction can cheaply detect this case without re-checking flags.
325
+ if ((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_flexible_list_schema', 'isEnabled', true) && isListIntoListPaste(tr, state)) {
326
+ tr = tr.setMeta('listPasteNormalisation', true);
327
+ }
328
+ if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !tr.getMeta('listPasteNormalisation') && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
296
329
  var _pluginInjectionApi$b;
297
330
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
298
331
  }
@@ -578,6 +611,12 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
578
611
  slice = (0, _transforms.transformSingleColumnLayout)(slice, schema);
579
612
  }
580
613
  slice = (0, _transforms.transformSliceToRemoveMacroId)(slice, schema);
614
+ if ((0, _expValEquals.expValEquals)('platform_editor_flexible_list_schema', 'isEnabled', true) && !(0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
615
+ // Prevent pasted externally-authored flexible list HTML from producing flexible list structures
616
+ // Only when schema support is enabled but indentation behaviour is not, meaning editor gracefully
617
+ // handles the structure, but ideally does not produce it
618
+ slice = (0, _transforms.transformSliceEnsureListItemParagraphFirst)(slice, schema);
619
+ }
581
620
  return slice;
582
621
  },
583
622
  transformPastedHTML: function transformPastedHTML(html) {
@@ -46,7 +46,6 @@ var _utils3 = require("@atlaskit/editor-tables/utils");
46
46
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
47
47
  var _prosemirrorHistory = require("@atlaskit/prosemirror-history");
48
48
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
49
- var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
50
49
  var _commands = require("../../editor-commands/commands");
51
50
  var _pluginFactory = require("../plugin-factory");
52
51
  var _edgeCases = require("./edge-cases");
@@ -1110,7 +1109,7 @@ function handleRichText(slice, queueCardsFromChangedTr) {
1110
1109
  slice: slice,
1111
1110
  schema: schema
1112
1111
  });
1113
- } else if (noNeedForSafeInsert && !((0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1112
+ } else if (noNeedForSafeInsert && !((0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1114
1113
  var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
1115
1114
  if ((firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$ty3 = firstChildOfSlice.type) === null || _firstChildOfSlice$ty3 === void 0 ? void 0 : _firstChildOfSlice$ty3.name) === 'blockquote' && firstChildOfSlice !== null && firstChildOfSlice !== void 0 && (_firstChildOfSlice$co2 = firstChildOfSlice.content.firstChild) !== null && _firstChildOfSlice$co2 !== void 0 && _firstChildOfSlice$co2.type.name && ['bulletList', 'orderedList', 'mediaSingle'].includes(firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$co3 = firstChildOfSlice.content.firstChild) === null || _firstChildOfSlice$co3 === void 0 ? void 0 : _firstChildOfSlice$co3.type.name)) {
1116
1115
  // checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.Flag = void 0;
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
10
  var _react = _interopRequireDefault(require("react"));
11
- var _reactIntlNext = require("react-intl-next");
11
+ var _reactIntl = require("react-intl");
12
12
  var _hooks = require("@atlaskit/editor-common/hooks");
13
13
  var _flag = _interopRequireWildcard(require("@atlaskit/flag"));
14
14
  var _statusError = _interopRequireDefault(require("@atlaskit/icon/core/status-error"));
@@ -29,7 +29,7 @@ var Flag = exports.Flag = function Flag(_ref) {
29
29
  };
30
30
  }),
31
31
  activeFlag = _useSharedPluginState.activeFlag;
32
- var _useIntl = (0, _reactIntlNext.useIntl)(),
32
+ var _useIntl = (0, _reactIntl.useIntl)(),
33
33
  formatMessage = _useIntl.formatMessage;
34
34
  if (!activeFlag) {
35
35
  return;
@@ -9,16 +9,17 @@ import { isPastedFile as isPastedFileFromEvent, md } from '@atlaskit/editor-comm
9
9
  import { measureRender } from '@atlaskit/editor-common/performance/measure-render';
10
10
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
11
11
  import { SyncBlockRendererDataAttributeName } from '@atlaskit/editor-common/sync-block';
12
- import { transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, transformSliceNestedExpandToExpand, transformSliceToDecisionList, transformSliceToJoinAdjacentCodeBlocks, transformSliceToRemoveLegacyContentMacro, transformSliceToRemoveMacroId, removeBreakoutFromRendererSyncBlockHTML } from '@atlaskit/editor-common/transforms';
12
+ import { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, transformSliceEnsureListItemParagraphFirst, transformSliceNestedExpandToExpand, transformSliceToDecisionList, transformSliceToJoinAdjacentCodeBlocks, transformSliceToRemoveLegacyContentMacro, transformSliceToRemoveMacroId } from '@atlaskit/editor-common/transforms';
13
13
  import { containsAnyAnnotations, extractSliceFromStep, linkifyContent, mapChildren } from '@atlaskit/editor-common/utils';
14
14
  import { MarkdownTransformer } from '@atlaskit/editor-markdown-transformer';
15
15
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
16
- import { contains, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
16
+ import { contains, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
17
17
  import { handlePaste as handlePasteTable } from '@atlaskit/editor-tables/utils';
18
18
  import { insm } from '@atlaskit/insm';
19
19
  import { extractClientIdsFromHtml } from '@atlaskit/media-common';
20
20
  import { fg } from '@atlaskit/platform-feature-flags';
21
21
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
22
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
22
23
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
23
24
  import { PastePluginActionTypes } from '../editor-actions/actions';
24
25
  import { splitParagraphs, upgradeTextToLists } from '../editor-commands/commands';
@@ -28,9 +29,35 @@ import { createClipboardTextSerializer } from './create-clipboard-text-serialize
28
29
  import { createPluginState, pluginKey as stateKey } from './plugin-factory';
29
30
  import { escapeBackslashAndLinksExceptCodeBlock, getPasteSource, htmlContainsSingleFile, htmlHasInvalidLinkTags, isPastedFromExcel, isPastedFromWord, removeDuplicateInvalidLinks, transformUnsupportedBlockCardToInline } from './util';
30
31
  import { handleVSCodeBlock } from './util/edge-cases/handleVSCodeBlock';
31
- import { handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handleTableContentPasteInBodiedExtension, handlePasteExpand } from './util/handlers';
32
+ import { handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handlePasteExpand, handleTableContentPasteInBodiedExtension } from './util/handlers';
32
33
  import { handleSyncBlocksPaste } from './util/sync-block';
33
34
  import { htmlHasIncompleteTable, isPastedFromTinyMCEConfluence, tryRebuildCompleteTableHtml } from './util/tinyMCE';
35
+ function isListIntoListPaste(tr, state) {
36
+ const {
37
+ listItem,
38
+ bulletList,
39
+ orderedList
40
+ } = state.schema.nodes;
41
+ const {
42
+ $from,
43
+ $to
44
+ } = state.selection;
45
+ const selectionInList = !!findParentNodeOfTypeClosestToPos($from, [listItem]) || !!findParentNodeOfTypeClosestToPos($to, [listItem]);
46
+ if (!selectionInList) {
47
+ return false;
48
+ }
49
+ return tr.steps.some(step => {
50
+ var _slice$content;
51
+ const slice = extractSliceFromStep(step);
52
+ let listExists = false;
53
+ slice === null || slice === void 0 ? void 0 : (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.forEach(node => {
54
+ if (node.type === bulletList || node.type === orderedList) {
55
+ listExists = true;
56
+ }
57
+ });
58
+ return listExists;
59
+ });
60
+ }
34
61
  export const isInsideBlockQuote = state => {
35
62
  const {
36
63
  blockquote
@@ -244,17 +271,25 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
244
271
  // to split those repairing transactions in prosemirror-history when they're being added to the
245
272
  // "done" stack
246
273
  const isPastingTable = tr.steps.some(step => {
247
- var _slice$content;
274
+ var _slice$content2;
248
275
  const slice = extractSliceFromStep(step);
249
276
  let tableExists = false;
250
- slice === null || slice === void 0 ? void 0 : (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.forEach(node => {
277
+ slice === null || slice === void 0 ? void 0 : (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.forEach(node => {
251
278
  if (node.type === state.schema.nodes.table) {
252
279
  tableExists = true;
253
280
  }
254
281
  });
255
282
  return tableExists;
256
283
  });
257
- if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
284
+
285
+ // Don't add closeHistory if we're pasting a list into a list, as the list plugin will
286
+ // appendTransaction to normalise the list structure and we want to keep the paste and
287
+ // normalisation as one undo event. We also set a meta on the transaction so the list
288
+ // plugin's appendTransaction can cheaply detect this case without re-checking flags.
289
+ if (expValEqualsNoExposure('platform_editor_flexible_list_schema', 'isEnabled', true) && isListIntoListPaste(tr, state)) {
290
+ tr = tr.setMeta('listPasteNormalisation', true);
291
+ }
292
+ if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !tr.getMeta('listPasteNormalisation') && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
258
293
  var _pluginInjectionApi$b;
259
294
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
260
295
  }
@@ -540,6 +575,12 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
540
575
  slice = transformSingleColumnLayout(slice, schema);
541
576
  }
542
577
  slice = transformSliceToRemoveMacroId(slice, schema);
578
+ if (expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && !expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
579
+ // Prevent pasted externally-authored flexible list HTML from producing flexible list structures
580
+ // Only when schema support is enabled but indentation behaviour is not, meaning editor gracefully
581
+ // handles the structure, but ideally does not produce it
582
+ slice = transformSliceEnsureListItemParagraphFirst(slice, schema);
583
+ }
543
584
  return slice;
544
585
  },
545
586
  transformPastedHTML(html) {
@@ -15,7 +15,6 @@ import { replaceSelectedTable } from '@atlaskit/editor-tables/utils';
15
15
  import { fg } from '@atlaskit/platform-feature-flags';
16
16
  import { closeHistory } from '@atlaskit/prosemirror-history';
17
17
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
18
- import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
19
18
  // TODO: ED-20519 - Needs Macro extraction
20
19
 
21
20
  import { startTrackingPastedMacroPositions, stopTrackingPastedMacroPositions } from '../../editor-commands/commands';
@@ -1091,7 +1090,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
1091
1090
  slice,
1092
1091
  schema
1093
1092
  });
1094
- } else if (noNeedForSafeInsert && !(expValEqualsNoExposure('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1093
+ } else if (noNeedForSafeInsert && !(expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1095
1094
  var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
1096
1095
  if ((firstChildOfSlice === null || firstChildOfSlice === void 0 ? void 0 : (_firstChildOfSlice$ty3 = firstChildOfSlice.type) === null || _firstChildOfSlice$ty3 === void 0 ? void 0 : _firstChildOfSlice$ty3.name) === 'blockquote' && firstChildOfSlice !== null && firstChildOfSlice !== void 0 && (_firstChildOfSlice$co2 = firstChildOfSlice.content.firstChild) !== null && _firstChildOfSlice$co2 !== void 0 && _firstChildOfSlice$co2.type.name && ['bulletList', 'orderedList', 'mediaSingle'].includes(firstChildOfSlice === null || firstChildOfSlice === void 0 ? void 0 : (_firstChildOfSlice$co3 = firstChildOfSlice.content.firstChild) === null || _firstChildOfSlice$co3 === void 0 ? void 0 : _firstChildOfSlice$co3.type.name)) {
1097
1096
  // checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { useIntl } from 'react-intl-next';
2
+ import { useIntl } from 'react-intl';
3
3
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
4
4
  import AkFlag, { AutoDismissFlag, FlagGroup } from '@atlaskit/flag';
5
5
  import StatusErrorIcon from '@atlaskit/icon/core/status-error';
@@ -14,16 +14,17 @@ import { isPastedFile as isPastedFileFromEvent, md } from '@atlaskit/editor-comm
14
14
  import { measureRender } from '@atlaskit/editor-common/performance/measure-render';
15
15
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
16
16
  import { SyncBlockRendererDataAttributeName } from '@atlaskit/editor-common/sync-block';
17
- import { transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, transformSliceNestedExpandToExpand, transformSliceToDecisionList, transformSliceToJoinAdjacentCodeBlocks, transformSliceToRemoveLegacyContentMacro, transformSliceToRemoveMacroId, removeBreakoutFromRendererSyncBlockHTML } from '@atlaskit/editor-common/transforms';
17
+ import { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, transformSliceEnsureListItemParagraphFirst, transformSliceNestedExpandToExpand, transformSliceToDecisionList, transformSliceToJoinAdjacentCodeBlocks, transformSliceToRemoveLegacyContentMacro, transformSliceToRemoveMacroId } from '@atlaskit/editor-common/transforms';
18
18
  import { containsAnyAnnotations, extractSliceFromStep, linkifyContent, mapChildren } from '@atlaskit/editor-common/utils';
19
19
  import { MarkdownTransformer } from '@atlaskit/editor-markdown-transformer';
20
20
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
21
- import { contains, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
21
+ import { contains, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
22
22
  import { handlePaste as handlePasteTable } from '@atlaskit/editor-tables/utils';
23
23
  import { insm } from '@atlaskit/insm';
24
24
  import { extractClientIdsFromHtml } from '@atlaskit/media-common';
25
25
  import { fg } from '@atlaskit/platform-feature-flags';
26
26
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
27
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
27
28
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
28
29
  import { PastePluginActionTypes } from '../editor-actions/actions';
29
30
  import { splitParagraphs, upgradeTextToLists } from '../editor-commands/commands';
@@ -33,9 +34,33 @@ import { createClipboardTextSerializer } from './create-clipboard-text-serialize
33
34
  import { createPluginState, pluginKey as stateKey } from './plugin-factory';
34
35
  import { escapeBackslashAndLinksExceptCodeBlock, getPasteSource, htmlContainsSingleFile, htmlHasInvalidLinkTags, isPastedFromExcel, isPastedFromWord, removeDuplicateInvalidLinks, transformUnsupportedBlockCardToInline } from './util';
35
36
  import { handleVSCodeBlock } from './util/edge-cases/handleVSCodeBlock';
36
- import { handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handleTableContentPasteInBodiedExtension, handlePasteExpand } from './util/handlers';
37
+ import { handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handlePasteExpand, handleTableContentPasteInBodiedExtension } from './util/handlers';
37
38
  import { handleSyncBlocksPaste } from './util/sync-block';
38
39
  import { htmlHasIncompleteTable, isPastedFromTinyMCEConfluence, tryRebuildCompleteTableHtml } from './util/tinyMCE';
40
+ function isListIntoListPaste(tr, state) {
41
+ var _state$schema$nodes = state.schema.nodes,
42
+ listItem = _state$schema$nodes.listItem,
43
+ bulletList = _state$schema$nodes.bulletList,
44
+ orderedList = _state$schema$nodes.orderedList;
45
+ var _state$selection = state.selection,
46
+ $from = _state$selection.$from,
47
+ $to = _state$selection.$to;
48
+ var selectionInList = !!findParentNodeOfTypeClosestToPos($from, [listItem]) || !!findParentNodeOfTypeClosestToPos($to, [listItem]);
49
+ if (!selectionInList) {
50
+ return false;
51
+ }
52
+ return tr.steps.some(function (step) {
53
+ var _slice$content;
54
+ var slice = extractSliceFromStep(step);
55
+ var listExists = false;
56
+ slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 || _slice$content.forEach(function (node) {
57
+ if (node.type === bulletList || node.type === orderedList) {
58
+ listExists = true;
59
+ }
60
+ });
61
+ return listExists;
62
+ });
63
+ }
39
64
  export var isInsideBlockQuote = function isInsideBlockQuote(state) {
40
65
  var blockquote = state.schema.nodes.blockquote;
41
66
  return hasParentNodeOfType(blockquote)(state.selection);
@@ -274,17 +299,25 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
274
299
  // to split those repairing transactions in prosemirror-history when they're being added to the
275
300
  // "done" stack
276
301
  var isPastingTable = tr.steps.some(function (step) {
277
- var _slice$content;
302
+ var _slice$content2;
278
303
  var slice = extractSliceFromStep(step);
279
304
  var tableExists = false;
280
- slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 || _slice$content.forEach(function (node) {
305
+ slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || _slice$content2.forEach(function (node) {
281
306
  if (node.type === state.schema.nodes.table) {
282
307
  tableExists = true;
283
308
  }
284
309
  });
285
310
  return tableExists;
286
311
  });
287
- if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
312
+
313
+ // Don't add closeHistory if we're pasting a list into a list, as the list plugin will
314
+ // appendTransaction to normalise the list structure and we want to keep the paste and
315
+ // normalisation as one undo event. We also set a meta on the transaction so the list
316
+ // plugin's appendTransaction can cheaply detect this case without re-checking flags.
317
+ if (expValEqualsNoExposure('platform_editor_flexible_list_schema', 'isEnabled', true) && isListIntoListPaste(tr, state)) {
318
+ tr = tr.setMeta('listPasteNormalisation', true);
319
+ }
320
+ if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !tr.getMeta('listPasteNormalisation') && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
288
321
  var _pluginInjectionApi$b;
289
322
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
290
323
  }
@@ -570,6 +603,12 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
570
603
  slice = transformSingleColumnLayout(slice, schema);
571
604
  }
572
605
  slice = transformSliceToRemoveMacroId(slice, schema);
606
+ if (expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && !expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
607
+ // Prevent pasted externally-authored flexible list HTML from producing flexible list structures
608
+ // Only when schema support is enabled but indentation behaviour is not, meaning editor gracefully
609
+ // handles the structure, but ideally does not produce it
610
+ slice = transformSliceEnsureListItemParagraphFirst(slice, schema);
611
+ }
573
612
  return slice;
574
613
  },
575
614
  transformPastedHTML: function transformPastedHTML(html) {
@@ -23,7 +23,6 @@ import { replaceSelectedTable } from '@atlaskit/editor-tables/utils';
23
23
  import { fg } from '@atlaskit/platform-feature-flags';
24
24
  import { closeHistory } from '@atlaskit/prosemirror-history';
25
25
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
26
- import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
27
26
  // TODO: ED-20519 - Needs Macro extraction
28
27
 
29
28
  import { startTrackingPastedMacroPositions, stopTrackingPastedMacroPositions } from '../../editor-commands/commands';
@@ -1083,7 +1082,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
1083
1082
  slice: slice,
1084
1083
  schema: schema
1085
1084
  });
1086
- } else if (noNeedForSafeInsert && !(expValEqualsNoExposure('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1085
+ } else if (noNeedForSafeInsert && !(expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) && checkTaskListInList(state, slice))) {
1087
1086
  var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
1088
1087
  if ((firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$ty3 = firstChildOfSlice.type) === null || _firstChildOfSlice$ty3 === void 0 ? void 0 : _firstChildOfSlice$ty3.name) === 'blockquote' && firstChildOfSlice !== null && firstChildOfSlice !== void 0 && (_firstChildOfSlice$co2 = firstChildOfSlice.content.firstChild) !== null && _firstChildOfSlice$co2 !== void 0 && _firstChildOfSlice$co2.type.name && ['bulletList', 'orderedList', 'mediaSingle'].includes(firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$co3 = firstChildOfSlice.content.firstChild) === null || _firstChildOfSlice$co3 === void 0 ? void 0 : _firstChildOfSlice$co3.type.name)) {
1089
1088
  // checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  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; }
3
3
  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
4
  import React from 'react';
5
- import { useIntl } from 'react-intl-next';
5
+ import { useIntl } from 'react-intl';
6
6
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
7
7
  import AkFlag, { AutoDismissFlag, FlagGroup } from '@atlaskit/flag';
8
8
  import StatusErrorIcon from '@atlaskit/icon/core/status-error';
@@ -1,4 +1,4 @@
1
- import type { MessageDescriptor } from 'react-intl-next';
1
+ import type { MessageDescriptor } from 'react-intl';
2
2
  import type { PasteSource } from '@atlaskit/editor-common/analytics';
3
3
  import type { CardOptions } from '@atlaskit/editor-common/card';
4
4
  import type { NextEditorPlugin, OptionalPlugin, PasteWarningOptions } from '@atlaskit/editor-common/types';
@@ -1,4 +1,4 @@
1
- import type { IntlShape } from 'react-intl-next';
1
+ import type { IntlShape } from 'react-intl';
2
2
  import type { Slice } from '@atlaskit/editor-prosemirror/model';
3
3
  /**
4
4
  * Returns a plain text serialization of a given slice. This is used for populating the plain text
@@ -1,4 +1,4 @@
1
- import type { IntlShape } from 'react-intl-next';
1
+ import type { IntlShape } from 'react-intl';
2
2
  import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
3
3
  import type { CardOptions } from '@atlaskit/editor-common/card';
4
4
  import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
@@ -1,4 +1,4 @@
1
- import type { MessageDescriptor } from 'react-intl-next';
1
+ import type { MessageDescriptor } from 'react-intl';
2
2
  import type { PasteSource } from '@atlaskit/editor-common/analytics';
3
3
  import type { CardOptions } from '@atlaskit/editor-common/card';
4
4
  import type { NextEditorPlugin, OptionalPlugin, PasteWarningOptions } from '@atlaskit/editor-common/types';
@@ -1,4 +1,4 @@
1
- import type { IntlShape } from 'react-intl-next';
1
+ import type { IntlShape } from 'react-intl';
2
2
  import type { Slice } from '@atlaskit/editor-prosemirror/model';
3
3
  /**
4
4
  * Returns a plain text serialization of a given slice. This is used for populating the plain text
@@ -1,4 +1,4 @@
1
- import type { IntlShape } from 'react-intl-next';
1
+ import type { IntlShape } from 'react-intl';
2
2
  import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
3
3
  import type { CardOptions } from '@atlaskit/editor-common/card';
4
4
  import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-paste",
3
- "version": "10.0.0",
3
+ "version": "11.0.0",
4
4
  "description": "Paste plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -30,15 +30,15 @@
30
30
  "@atlaskit/adf-schema": "^52.5.0",
31
31
  "@atlaskit/code": "^17.4.0",
32
32
  "@atlaskit/editor-markdown-transformer": "^5.20.0",
33
- "@atlaskit/editor-plugin-analytics": "^9.0.0",
34
- "@atlaskit/editor-plugin-annotation": "^9.0.0",
35
- "@atlaskit/editor-plugin-better-type-history": "^9.0.0",
36
- "@atlaskit/editor-plugin-card": "^15.0.0",
37
- "@atlaskit/editor-plugin-expand": "^10.0.0",
38
- "@atlaskit/editor-plugin-feature-flags": "^8.0.0",
39
- "@atlaskit/editor-plugin-list": "^11.0.0",
40
- "@atlaskit/editor-plugin-media": "^11.0.0",
41
- "@atlaskit/editor-plugin-mentions": "^11.0.0",
33
+ "@atlaskit/editor-plugin-analytics": "^10.0.0",
34
+ "@atlaskit/editor-plugin-annotation": "^10.0.0",
35
+ "@atlaskit/editor-plugin-better-type-history": "^10.0.0",
36
+ "@atlaskit/editor-plugin-card": "^16.0.0",
37
+ "@atlaskit/editor-plugin-expand": "^11.0.0",
38
+ "@atlaskit/editor-plugin-feature-flags": "^9.0.0",
39
+ "@atlaskit/editor-plugin-list": "^12.0.0",
40
+ "@atlaskit/editor-plugin-media": "^12.0.0",
41
+ "@atlaskit/editor-plugin-mentions": "^12.0.0",
42
42
  "@atlaskit/editor-prosemirror": "^7.3.0",
43
43
  "@atlaskit/editor-tables": "^2.9.0",
44
44
  "@atlaskit/flag": "^17.9.0",
@@ -52,16 +52,17 @@
52
52
  "@atlaskit/tokens": "^13.0.0",
53
53
  "@babel/runtime": "^7.0.0",
54
54
  "lodash": "^4.17.21",
55
- "react-intl-next": "npm:react-intl@^5.18.1",
56
55
  "uuid": "^3.1.0"
57
56
  },
58
57
  "peerDependencies": {
59
- "@atlaskit/editor-common": "^113.0.0",
58
+ "@atlaskit/editor-common": "^114.0.0",
60
59
  "react": "^18.2.0",
61
- "react-dom": "^18.2.0"
60
+ "react-dom": "^18.2.0",
61
+ "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@testing-library/react": "^16.3.0",
65
+ "react-intl": "^6.6.2",
65
66
  "wait-for-expect": "^1.2.0"
66
67
  },
67
68
  "techstack": {