@atlaskit/editor-core 190.1.25 → 190.1.27

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 (100) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/afm-cc/tsconfig.json +0 -12
  3. package/dist/cjs/plugins/index.js +0 -7
  4. package/dist/cjs/presets/default.js +2 -3
  5. package/dist/cjs/version-wrapper.js +1 -1
  6. package/dist/es2019/plugins/index.js +0 -1
  7. package/dist/es2019/presets/default.js +1 -1
  8. package/dist/es2019/version-wrapper.js +1 -1
  9. package/dist/esm/plugins/index.js +0 -1
  10. package/dist/esm/presets/default.js +1 -1
  11. package/dist/esm/version-wrapper.js +1 -1
  12. package/dist/types/plugins/index.d.ts +0 -1
  13. package/dist/types/presets/default.d.ts +1 -1
  14. package/dist/types/ui/Appearance/FullPage/StyledComponents.d.ts +2 -2
  15. package/dist/types/ui/ContentStyles/index.d.ts +2 -2
  16. package/dist/types-ts4.5/plugins/index.d.ts +0 -1
  17. package/dist/types-ts4.5/presets/default.d.ts +1 -1
  18. package/dist/types-ts4.5/ui/Appearance/FullPage/StyledComponents.d.ts +2 -2
  19. package/dist/types-ts4.5/ui/ContentStyles/index.d.ts +2 -2
  20. package/package.json +6 -12
  21. package/dist/cjs/plugins/paste/actions.js +0 -12
  22. package/dist/cjs/plugins/paste/commands.js +0 -255
  23. package/dist/cjs/plugins/paste/edge-cases/index.js +0 -88
  24. package/dist/cjs/plugins/paste/edge-cases/lists.js +0 -107
  25. package/dist/cjs/plugins/paste/handlers.js +0 -935
  26. package/dist/cjs/plugins/paste/index.js +0 -14
  27. package/dist/cjs/plugins/paste/plugin.js +0 -43
  28. package/dist/cjs/plugins/paste/plugins/media.js +0 -207
  29. package/dist/cjs/plugins/paste/pm-plugins/analytics.js +0 -376
  30. package/dist/cjs/plugins/paste/pm-plugins/clipboard-text-serializer.js +0 -43
  31. package/dist/cjs/plugins/paste/pm-plugins/main.js +0 -482
  32. package/dist/cjs/plugins/paste/pm-plugins/plugin-factory.js +0 -42
  33. package/dist/cjs/plugins/paste/reducer.js +0 -41
  34. package/dist/cjs/plugins/paste/types.js +0 -5
  35. package/dist/cjs/plugins/paste/util/index.js +0 -214
  36. package/dist/cjs/plugins/paste/util/tinyMCE.js +0 -183
  37. package/dist/es2019/plugins/paste/actions.js +0 -6
  38. package/dist/es2019/plugins/paste/commands.js +0 -235
  39. package/dist/es2019/plugins/paste/edge-cases/index.js +0 -87
  40. package/dist/es2019/plugins/paste/edge-cases/lists.js +0 -113
  41. package/dist/es2019/plugins/paste/handlers.js +0 -915
  42. package/dist/es2019/plugins/paste/index.js +0 -3
  43. package/dist/es2019/plugins/paste/plugin.js +0 -38
  44. package/dist/es2019/plugins/paste/plugins/media.js +0 -204
  45. package/dist/es2019/plugins/paste/pm-plugins/analytics.js +0 -332
  46. package/dist/es2019/plugins/paste/pm-plugins/clipboard-text-serializer.js +0 -37
  47. package/dist/es2019/plugins/paste/pm-plugins/main.js +0 -451
  48. package/dist/es2019/plugins/paste/pm-plugins/plugin-factory.js +0 -30
  49. package/dist/es2019/plugins/paste/reducer.js +0 -32
  50. package/dist/es2019/plugins/paste/types.js +0 -1
  51. package/dist/es2019/plugins/paste/util/index.js +0 -209
  52. package/dist/es2019/plugins/paste/util/tinyMCE.js +0 -168
  53. package/dist/esm/plugins/paste/actions.js +0 -6
  54. package/dist/esm/plugins/paste/commands.js +0 -248
  55. package/dist/esm/plugins/paste/edge-cases/index.js +0 -81
  56. package/dist/esm/plugins/paste/edge-cases/lists.js +0 -98
  57. package/dist/esm/plugins/paste/handlers.js +0 -914
  58. package/dist/esm/plugins/paste/index.js +0 -3
  59. package/dist/esm/plugins/paste/plugin.js +0 -37
  60. package/dist/esm/plugins/paste/plugins/media.js +0 -199
  61. package/dist/esm/plugins/paste/pm-plugins/analytics.js +0 -364
  62. package/dist/esm/plugins/paste/pm-plugins/clipboard-text-serializer.js +0 -37
  63. package/dist/esm/plugins/paste/pm-plugins/main.js +0 -469
  64. package/dist/esm/plugins/paste/pm-plugins/plugin-factory.js +0 -36
  65. package/dist/esm/plugins/paste/reducer.js +0 -34
  66. package/dist/esm/plugins/paste/types.js +0 -1
  67. package/dist/esm/plugins/paste/util/index.js +0 -194
  68. package/dist/esm/plugins/paste/util/tinyMCE.js +0 -176
  69. package/dist/types/plugins/paste/actions.d.ts +0 -21
  70. package/dist/types/plugins/paste/commands.d.ts +0 -30
  71. package/dist/types/plugins/paste/edge-cases/index.d.ts +0 -11
  72. package/dist/types/plugins/paste/edge-cases/lists.d.ts +0 -18
  73. package/dist/types/plugins/paste/handlers.d.ts +0 -55
  74. package/dist/types/plugins/paste/index.d.ts +0 -4
  75. package/dist/types/plugins/paste/plugin.d.ts +0 -2
  76. package/dist/types/plugins/paste/plugins/media.d.ts +0 -23
  77. package/dist/types/plugins/paste/pm-plugins/analytics.d.ts +0 -44
  78. package/dist/types/plugins/paste/pm-plugins/clipboard-text-serializer.d.ts +0 -13
  79. package/dist/types/plugins/paste/pm-plugins/main.d.ts +0 -12
  80. package/dist/types/plugins/paste/pm-plugins/plugin-factory.d.ts +0 -3
  81. package/dist/types/plugins/paste/reducer.d.ts +0 -3
  82. package/dist/types/plugins/paste/types.d.ts +0 -1
  83. package/dist/types/plugins/paste/util/index.d.ts +0 -21
  84. package/dist/types/plugins/paste/util/tinyMCE.d.ts +0 -32
  85. package/dist/types-ts4.5/plugins/paste/actions.d.ts +0 -21
  86. package/dist/types-ts4.5/plugins/paste/commands.d.ts +0 -30
  87. package/dist/types-ts4.5/plugins/paste/edge-cases/index.d.ts +0 -11
  88. package/dist/types-ts4.5/plugins/paste/edge-cases/lists.d.ts +0 -18
  89. package/dist/types-ts4.5/plugins/paste/handlers.d.ts +0 -55
  90. package/dist/types-ts4.5/plugins/paste/index.d.ts +0 -4
  91. package/dist/types-ts4.5/plugins/paste/plugin.d.ts +0 -2
  92. package/dist/types-ts4.5/plugins/paste/plugins/media.d.ts +0 -23
  93. package/dist/types-ts4.5/plugins/paste/pm-plugins/analytics.d.ts +0 -44
  94. package/dist/types-ts4.5/plugins/paste/pm-plugins/clipboard-text-serializer.d.ts +0 -13
  95. package/dist/types-ts4.5/plugins/paste/pm-plugins/main.d.ts +0 -12
  96. package/dist/types-ts4.5/plugins/paste/pm-plugins/plugin-factory.d.ts +0 -3
  97. package/dist/types-ts4.5/plugins/paste/reducer.d.ts +0 -3
  98. package/dist/types-ts4.5/plugins/paste/types.d.ts +0 -1
  99. package/dist/types-ts4.5/plugins/paste/util/index.d.ts +0 -21
  100. package/dist/types-ts4.5/plugins/paste/util/tinyMCE.d.ts +0 -32
@@ -1,914 +0,0 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import _regeneratorRuntime from "@babel/runtime/regenerator";
4
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, 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 normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
5
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
- import { closeHistory } from '@atlaskit/editor-prosemirror/history';
10
- import { Fragment, Node as PMNode, Slice } from '@atlaskit/editor-prosemirror/model';
11
- import { TextSelection, NodeSelection } from '@atlaskit/editor-prosemirror/state';
12
- import { canInsert, findParentNodeOfType, findParentNodeOfTypeClosestToPos, hasParentNodeOfType, safeInsert } from '@atlaskit/editor-prosemirror/utils';
13
- import uuid from 'uuid/v4';
14
- import { replaceSelectedTable } from '@atlaskit/editor-tables/utils';
15
- import { canLinkBeCreatedInRange, insideTableCell, isInListItem, isLinkMark, isListItemNode, isListNode, isParagraph, isText, linkifyContent, mapSlice } from '@atlaskit/editor-common/utils';
16
- import { insideTable } from '@atlaskit/editor-common/core-utils';
17
- import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
18
- import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
19
- // TODO: ED-20519 Needs Macro extraction
20
-
21
- import { addReplaceSelectedTableAnalytics, applyTextMarksToSlice, hasOnlyNodesOfType } from './util';
22
- import { insertSliceForLists, insertSliceForListsInsideBlockquote } from './edge-cases';
23
- import { startTrackingPastedMacroPositions, stopTrackingPastedMacroPositions } from './commands';
24
- import { getPluginState as getPastePluginState } from './pm-plugins/plugin-factory';
25
- import { anyMarkActive } from '@atlaskit/editor-common/mark';
26
-
27
- /** Helper type for single arg function */
28
-
29
- /**
30
- * Compose 1 to n functions.
31
- * @param func first function
32
- * @param funcs additional functions
33
- */
34
- function compose(func) {
35
- for (var _len = arguments.length, funcs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
36
- funcs[_key - 1] = arguments[_key];
37
- }
38
- var allFuncs = [func].concat(funcs);
39
- return function composed(raw) {
40
- return allFuncs.reduceRight(function (memo, func) {
41
- return func(memo);
42
- }, raw);
43
- };
44
- }
45
-
46
- // remove text attribute from mention for copy/paste (GDPR)
47
- export function handleMention(slice, schema) {
48
- return mapSlice(slice, function (node) {
49
- if (node.type.name === schema.nodes.mention.name) {
50
- var mention = node.attrs;
51
- var newMention = _objectSpread(_objectSpread({}, mention), {}, {
52
- text: ''
53
- });
54
- return schema.nodes.mention.create(newMention, node.content, node.marks);
55
- }
56
- return node;
57
- });
58
- }
59
- export function handlePasteIntoTaskOrDecisionOrPanel(slice, queueCardsFromChangedTr) {
60
- return function (state, dispatch) {
61
- var _slice$content$firstC, _transformedSlice$con;
62
- var schema = state.schema,
63
- selection = state.tr.selection;
64
- var codeMark = schema.marks.code,
65
- _schema$nodes = schema.nodes,
66
- decisionItem = _schema$nodes.decisionItem,
67
- emoji = _schema$nodes.emoji,
68
- hardBreak = _schema$nodes.hardBreak,
69
- mention = _schema$nodes.mention,
70
- paragraph = _schema$nodes.paragraph,
71
- taskItem = _schema$nodes.taskItem,
72
- text = _schema$nodes.text,
73
- panel = _schema$nodes.panel,
74
- bulletList = _schema$nodes.bulletList,
75
- orderedList = _schema$nodes.orderedList,
76
- taskList = _schema$nodes.taskList,
77
- listItem = _schema$nodes.listItem,
78
- expand = _schema$nodes.expand,
79
- heading = _schema$nodes.heading;
80
- var selectionIsValidNode = state.selection instanceof NodeSelection && ['decisionList', 'decisionItem', 'taskList', 'taskItem'].includes(state.selection.node.type.name);
81
- var selectionHasValidParentNode = hasParentNodeOfType([decisionItem, taskItem, panel])(state.selection);
82
- var selectionIsPanel = hasParentNodeOfType([panel])(state.selection);
83
-
84
- // Some types of content should be handled by the default handler, not this function.
85
- // Check through slice content to see if it contains an invalid node.
86
- var sliceIsInvalid = false;
87
- slice.content.nodesBetween(0, slice.content.size, function (node) {
88
- if (node.type === bulletList || node.type === orderedList || node.type === expand || node.type === heading || node.type === listItem) {
89
- sliceIsInvalid = true;
90
- }
91
- if (selectionIsPanel && node.type === taskList) {
92
- sliceIsInvalid = true;
93
- }
94
- });
95
-
96
- // If the selection is a panel,
97
- // and the slice's first node is a paragraph
98
- // and it is not from a depth that would indicate it being from inside from another node (e.g. text from a decision)
99
- // then we can rely on the default behaviour.
100
- var sliceIsAPanelReceivingLowDepthText = selectionIsPanel && ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type) === paragraph && slice.openEnd < 2;
101
- if (sliceIsInvalid || sliceIsAPanelReceivingLowDepthText || !selectionIsValidNode && !selectionHasValidParentNode) {
102
- return false;
103
- }
104
- var filters = [linkifyContent(schema)];
105
- var selectionMarks = selection.$head.marks();
106
- if (selection instanceof TextSelection && Array.isArray(selectionMarks) && selectionMarks.length > 0 && hasOnlyNodesOfType(paragraph, text, emoji, mention, hardBreak)(slice) && (!codeMark.isInSet(selectionMarks) || anyMarkActive(state, codeMark)) // check if there is a code mark anywhere in the selection
107
- ) {
108
- filters.push(applyTextMarksToSlice(schema, selection.$head.marks()));
109
- }
110
- var transformedSlice = compose.apply(null, filters)(slice);
111
- var tr = closeHistory(state.tr);
112
- var transformedSliceIsValidNode = transformedSlice.content.firstChild.type.inlineContent || ['decisionList', 'decisionItem', 'taskList', 'taskItem', 'panel'].includes(transformedSlice.content.firstChild.type.name) && !isInListItem(state);
113
- // If the slice or the selection are valid nodes to handle,
114
- // and the slice is not a whole node (i.e. openStart is 1 and openEnd is 0)
115
- // or the slice's first node is a paragraph,
116
- // then we can replace the selection with our slice.
117
- if ((transformedSliceIsValidNode || selectionIsValidNode) && !(transformedSlice.openStart === 1 && transformedSlice.openEnd === 0 ||
118
- // Whole codeblock node has reverse slice depths.
119
- transformedSlice.openStart === 0 && transformedSlice.openEnd === 1) || ((_transformedSlice$con = transformedSlice.content.firstChild) === null || _transformedSlice$con === void 0 ? void 0 : _transformedSlice$con.type) === paragraph) {
120
- tr.replaceSelection(transformedSlice).scrollIntoView();
121
- } else {
122
- // This maintains both the selection (destination) and the slice (paste content).
123
- safeInsert(transformedSlice.content)(tr).scrollIntoView();
124
- }
125
- queueCardsFromChangedTr === null || queueCardsFromChangedTr === void 0 || queueCardsFromChangedTr(state, tr, INPUT_METHOD.CLIPBOARD);
126
- if (dispatch) {
127
- dispatch(tr);
128
- }
129
- return true;
130
- };
131
- }
132
- export function handlePasteNonNestableBlockNodesIntoList(slice) {
133
- return function (state, dispatch) {
134
- var _tr$doc$nodeAt, _sliceContent$firstCh, _findParentNodeOfType;
135
- var tr = state.tr;
136
- var selection = tr.selection;
137
- var $from = selection.$from,
138
- $to = selection.$to,
139
- from = selection.from,
140
- to = selection.to;
141
- var _state$schema$nodes = state.schema.nodes,
142
- orderedList = _state$schema$nodes.orderedList,
143
- bulletList = _state$schema$nodes.bulletList,
144
- listItem = _state$schema$nodes.listItem;
145
-
146
- // Selected nodes
147
- var selectionParentListItemNode = findParentNodeOfType(listItem)(selection);
148
- var selectionParentListNodeWithPos = findParentNodeOfType([bulletList, orderedList])(selection);
149
- var selectionParentListNode = selectionParentListNodeWithPos === null || selectionParentListNodeWithPos === void 0 ? void 0 : selectionParentListNodeWithPos.node;
150
-
151
- // Slice info
152
- var sliceContent = slice.content;
153
- var sliceIsListItems = isListNode(sliceContent.firstChild) && isListNode(sliceContent.lastChild);
154
-
155
- // Find case of slices that can be inserted into a list item
156
- // (eg. paragraphs, list items, code blocks, media single)
157
- // These scenarios already get handled elsewhere and don't need to split the list
158
- var sliceContainsBlockNodesOtherThanThoseAllowedInListItem = false;
159
- slice.content.forEach(function (child) {
160
- var _listItem$spec$conten;
161
- if (!listItem || child.isBlock && !((_listItem$spec$conten = listItem.spec.content) !== null && _listItem$spec$conten !== void 0 && _listItem$spec$conten.includes(child.type.name))) {
162
- sliceContainsBlockNodesOtherThanThoseAllowedInListItem = true;
163
- }
164
- });
165
- if (!selectionParentListItemNode || !sliceContent || canInsert($from, sliceContent) ||
166
- // eg. inline nodes that can be inserted in a list item
167
- !sliceContainsBlockNodesOtherThanThoseAllowedInListItem || sliceIsListItems || !selectionParentListNodeWithPos) {
168
- return false;
169
- }
170
-
171
- // Offsets
172
- var listWrappingOffset = $to.depth - selectionParentListNodeWithPos.depth + 1; // difference in depth between to position and list node
173
- var listItemWrappingOffset = $to.depth - selectionParentListNodeWithPos.depth; // difference in depth between to position and list item node
174
-
175
- // Anything to do with nested lists should safeInsert and not be handled here
176
- var grandParentListNode = findParentNodeOfTypeClosestToPos(tr.doc.resolve(selectionParentListNodeWithPos.pos), [bulletList, orderedList]);
177
- var selectionIsInNestedList = !!grandParentListNode;
178
- var selectedListItemHasNestedList = false;
179
- selectionParentListItemNode.node.content.forEach(function (child) {
180
- if (isListNode(child)) {
181
- selectedListItemHasNestedList = true;
182
- }
183
- });
184
- if (selectedListItemHasNestedList || selectionIsInNestedList) {
185
- return false;
186
- }
187
-
188
- // Node after the insert position
189
- var nodeAfterInsertPositionIsListItem = ((_tr$doc$nodeAt = tr.doc.nodeAt(to + listItemWrappingOffset)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.type.name) === 'listItem';
190
-
191
- // Get the next list items position (used later to find the split out ordered list)
192
- var indexOfNextListItem = $to.indexAfter($to.depth - listItemWrappingOffset);
193
- var positionOfNextListItem = tr.doc.resolve(selectionParentListNodeWithPos.pos + 1).posAtIndex(indexOfNextListItem);
194
-
195
- // These nodes paste as plain text by default so need to be handled differently
196
- var sliceContainsNodeThatPastesAsPlainText = sliceContent.firstChild && ['taskItem', 'taskList', 'heading', 'blockquote'].includes(sliceContent.firstChild.type.name);
197
-
198
- // Work out position to replace up to
199
- var replaceTo;
200
- if (sliceContainsNodeThatPastesAsPlainText && nodeAfterInsertPositionIsListItem) {
201
- replaceTo = to + listItemWrappingOffset;
202
- } else if (sliceContainsNodeThatPastesAsPlainText || !nodeAfterInsertPositionIsListItem) {
203
- replaceTo = to;
204
- } else {
205
- replaceTo = to + listWrappingOffset;
206
- }
207
-
208
- // handle the insertion of the slice
209
- if (sliceContainsNodeThatPastesAsPlainText || nodeAfterInsertPositionIsListItem || sliceContent.childCount > 1 && ((_sliceContent$firstCh = sliceContent.firstChild) === null || _sliceContent$firstCh === void 0 ? void 0 : _sliceContent$firstCh.type.name) !== 'paragraph') {
210
- tr.replaceWith(from, replaceTo, sliceContent).scrollIntoView();
211
- } else {
212
- // When the selection is not at the end of a list item
213
- // eg. middle of list item, start of list item
214
- tr.replaceSelection(slice).scrollIntoView();
215
- }
216
-
217
- // Find the ordered list node after the pasted content so we can set it's order
218
- var mappedPositionOfNextListItem = tr.mapping.map(positionOfNextListItem);
219
- if (mappedPositionOfNextListItem > tr.doc.nodeSize) {
220
- return false;
221
- }
222
- var nodeAfterPastedContentResolvedPos = findParentNodeOfTypeClosestToPos(tr.doc.resolve(mappedPositionOfNextListItem), [orderedList]);
223
-
224
- // Work out the new split out lists 'order' (the number it starts from)
225
- var originalParentOrderedListNodeOrder = selectionParentListNode === null || selectionParentListNode === void 0 ? void 0 : selectionParentListNode.attrs.order;
226
- var numOfListItemsInOriginalList = (_findParentNodeOfType = findParentNodeOfTypeClosestToPos(tr.doc.resolve(from - 1), [orderedList])) === null || _findParentNodeOfType === void 0 ? void 0 : _findParentNodeOfType.node.childCount;
227
-
228
- // Set the new split out lists order attribute
229
- if (typeof originalParentOrderedListNodeOrder === 'number' && numOfListItemsInOriginalList && nodeAfterPastedContentResolvedPos) {
230
- tr.setNodeMarkup(nodeAfterPastedContentResolvedPos.pos, orderedList, _objectSpread(_objectSpread({}, nodeAfterPastedContentResolvedPos.node.attrs), {}, {
231
- order: originalParentOrderedListNodeOrder + numOfListItemsInOriginalList
232
- }));
233
- }
234
-
235
- // dispatch transaction
236
- if (tr.docChanged) {
237
- if (dispatch) {
238
- dispatch(tr);
239
- }
240
- return true;
241
- }
242
- return false;
243
- };
244
- }
245
- export var doesSelectionWhichStartsOrEndsInListContainEntireList = function doesSelectionWhichStartsOrEndsInListContainEntireList(selection, findRootParentListNode) {
246
- var $from = selection.$from,
247
- $to = selection.$to,
248
- from = selection.from,
249
- to = selection.to;
250
- var selectionParentListItemNodeResolvedPos = findRootParentListNode ? findRootParentListNode($from) || findRootParentListNode($to) : null;
251
- var selectionParentListNode = selectionParentListItemNodeResolvedPos === null || selectionParentListItemNodeResolvedPos === void 0 ? void 0 : selectionParentListItemNodeResolvedPos.parent;
252
- if (!selectionParentListItemNodeResolvedPos || !selectionParentListNode) {
253
- return false;
254
- }
255
- var startOfEntireList = $from.pos < $to.pos ? selectionParentListItemNodeResolvedPos.pos + $from.depth - 1 : selectionParentListItemNodeResolvedPos.pos + $to.depth - 1;
256
- var endOfEntireList = $from.pos < $to.pos ? selectionParentListItemNodeResolvedPos.pos + selectionParentListNode.nodeSize - $to.depth - 1 : selectionParentListItemNodeResolvedPos.pos + selectionParentListNode.nodeSize - $from.depth - 1;
257
- if (!startOfEntireList || !endOfEntireList) {
258
- return false;
259
- }
260
- if (from < to) {
261
- return startOfEntireList >= $from.pos && endOfEntireList <= $to.pos;
262
- } else if (from > to) {
263
- return startOfEntireList >= $to.pos && endOfEntireList <= $from.pos;
264
- } else {
265
- return false;
266
- }
267
- };
268
- export function handlePastePanelOrDecisionContentIntoList(slice, findRootParentListNode) {
269
- return function (state, dispatch) {
270
- var schema = state.schema,
271
- tr = state.tr;
272
- var selection = tr.selection;
273
- // Check this pasting action is related to copy content from panel node into a selected the list node
274
- var blockNode = slice.content.firstChild;
275
- var isSliceWholeNode = slice.openStart === 0 && slice.openEnd === 0;
276
- var selectionParentListItemNode = selection.$to.node(selection.$to.depth - 1);
277
- var sliceIsWholeNodeButShouldNotReplaceSelection = isSliceWholeNode && !doesSelectionWhichStartsOrEndsInListContainEntireList(selection, findRootParentListNode);
278
- if (!selectionParentListItemNode || (selectionParentListItemNode === null || selectionParentListItemNode === void 0 ? void 0 : selectionParentListItemNode.type) !== schema.nodes.listItem || !blockNode || !['panel', 'decisionList'].includes(blockNode === null || blockNode === void 0 ? void 0 : blockNode.type.name) || slice.content.childCount > 1 || (blockNode === null || blockNode === void 0 ? void 0 : blockNode.content.firstChild) === undefined || sliceIsWholeNodeButShouldNotReplaceSelection) {
279
- return false;
280
- }
281
-
282
- // Paste the panel node contents extracted instead of pasting the entire panel node
283
- tr.replaceSelection(slice).scrollIntoView();
284
- if (dispatch) {
285
- dispatch(tr);
286
- }
287
- return true;
288
- };
289
- }
290
-
291
- // If we paste a link onto some selected text, apply the link as a mark
292
- export function handlePasteLinkOnSelectedText(slice) {
293
- return function (state, dispatch) {
294
- var schema = state.schema,
295
- selection = state.selection,
296
- _state$selection = state.selection,
297
- from = _state$selection.from,
298
- to = _state$selection.to,
299
- tr = state.tr;
300
- var linkMark;
301
-
302
- // check if we have a link on the clipboard
303
- if (slice.content.childCount === 1 && isParagraph(slice.content.child(0), schema)) {
304
- var paragraph = slice.content.child(0);
305
- if (paragraph.content.childCount === 1 && isText(paragraph.content.child(0), schema)) {
306
- var text = paragraph.content.child(0);
307
-
308
- // If pasteType is plain text, then
309
- // @atlaskit/editor-markdown-transformer in getMarkdownSlice decode
310
- // url before setting text property of text node.
311
- // However href of marks will be without decoding.
312
- // So, if there is character (e.g space) in url eligible escaping then
313
- // mark.attrs.href will not be equal to text.text.
314
- // That's why decoding mark.attrs.href before comparing.
315
- // However, if pasteType is richText, that means url in text.text
316
- // and href in marks, both won't be decoded.
317
- linkMark = text.marks.find(function (mark) {
318
- return isLinkMark(mark, schema) && (mark.attrs.href === text.text || decodeURI(mark.attrs.href) === text.text);
319
- });
320
- }
321
- }
322
-
323
- // if we have a link, apply it to the selected text if we have any and it's allowed
324
- if (linkMark && selection instanceof TextSelection && !selection.empty && canLinkBeCreatedInRange(from, to)(state)) {
325
- tr.addMark(from, to, linkMark);
326
- if (dispatch) {
327
- dispatch(tr);
328
- }
329
- return true;
330
- }
331
- return false;
332
- };
333
- }
334
- export function handlePasteAsPlainText(slice, _event, editorAnalyticsAPI) {
335
- return function (state, dispatch, view) {
336
- var _input;
337
- if (!view) {
338
- return false;
339
- }
340
-
341
- // prosemirror-bump-fix
342
- // Yes, this is wrong by default. But, we need to keep the private PAI usage to unblock the prosemirror bump
343
- // So, this code will make sure we are checking for both version (current and the newest prosemirror-view version
344
- var isShiftKeyPressed = view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey);
345
- // In case of SHIFT+CMD+V ("Paste and Match Style") we don't want to run the usual
346
- // fuzzy matching of content. ProseMirror already handles this scenario and will
347
- // provide us with slice containing paragraphs with plain text, which we decorate
348
- // with "stored marks".
349
- // @see prosemirror-view/src/clipboard.js:parseFromClipboard()).
350
- // @see prosemirror-view/src/input.js:doPaste().
351
- if (isShiftKeyPressed) {
352
- var tr = closeHistory(state.tr);
353
- var _tr = tr,
354
- selection = _tr.selection;
355
-
356
- // <- using the same internal flag that prosemirror-view is using
357
-
358
- // if user has selected table we need custom logic to replace the table
359
- tr = replaceSelectedTable(state, slice);
360
-
361
- // add analytics after replacing selected table
362
- tr = addReplaceSelectedTableAnalytics(state, tr, editorAnalyticsAPI);
363
-
364
- // otherwise just replace the selection
365
- if (!tr.docChanged) {
366
- tr.replaceSelection(slice);
367
- }
368
- (state.storedMarks || []).forEach(function (mark) {
369
- tr.addMark(selection.from, selection.from + slice.size, mark);
370
- });
371
- tr.scrollIntoView();
372
- if (dispatch) {
373
- dispatch(tr);
374
- }
375
- return true;
376
- }
377
- return false;
378
- };
379
- }
380
- export function handlePastePreservingMarks(slice, queueCardsFromChangedTr) {
381
- return function (state, dispatch) {
382
- var schema = state.schema,
383
- selection = state.tr.selection;
384
- var _schema$marks = schema.marks,
385
- codeMark = _schema$marks.code,
386
- annotationMark = _schema$marks.annotation,
387
- _schema$nodes2 = schema.nodes,
388
- bulletList = _schema$nodes2.bulletList,
389
- emoji = _schema$nodes2.emoji,
390
- hardBreak = _schema$nodes2.hardBreak,
391
- heading = _schema$nodes2.heading,
392
- listItem = _schema$nodes2.listItem,
393
- mention = _schema$nodes2.mention,
394
- orderedList = _schema$nodes2.orderedList,
395
- text = _schema$nodes2.text;
396
- if (!(selection instanceof TextSelection)) {
397
- return false;
398
- }
399
- var selectionMarks = selection.$head.marks();
400
- if (selectionMarks.length === 0) {
401
- return false;
402
- }
403
-
404
- // special case for codeMark: will preserve mark only if codeMark is currently active
405
- // won't preserve mark if cursor is on the edge on the mark (namely inactive)
406
- var hasActiveCodeMark = codeMark && codeMark.isInSet(selectionMarks) && anyMarkActive(state, codeMark);
407
- var hasAnnotationMark = annotationMark && annotationMark.isInSet(selectionMarks);
408
- var selectionIsHeading = hasParentNodeOfType([heading])(state.selection);
409
-
410
- // if the pasted data is one of the node types below
411
- // we apply current selection marks to the pasted slice
412
- if (hasOnlyNodesOfType(bulletList, hardBreak, heading, listItem, text, emoji, mention, orderedList)(slice) || selectionIsHeading || hasActiveCodeMark || hasAnnotationMark) {
413
- var transformedSlice = applyTextMarksToSlice(schema, selectionMarks)(slice);
414
- var tr = closeHistory(state.tr).replaceSelection(transformedSlice).setStoredMarks(selectionMarks).scrollIntoView();
415
- queueCardsFromChangedTr === null || queueCardsFromChangedTr === void 0 || queueCardsFromChangedTr(state, tr, INPUT_METHOD.CLIPBOARD);
416
- if (dispatch) {
417
- dispatch(tr);
418
- }
419
- return true;
420
- }
421
- return false;
422
- };
423
- }
424
- function getSmartLinkAdf(_x, _x2, _x3) {
425
- return _getSmartLinkAdf.apply(this, arguments);
426
- }
427
- function _getSmartLinkAdf() {
428
- _getSmartLinkAdf = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(text, type, cardOptions) {
429
- var provider;
430
- return _regeneratorRuntime.wrap(function _callee$(_context) {
431
- while (1) switch (_context.prev = _context.next) {
432
- case 0:
433
- if (cardOptions.provider) {
434
- _context.next = 2;
435
- break;
436
- }
437
- throw Error('No card provider found');
438
- case 2:
439
- _context.next = 4;
440
- return cardOptions.provider;
441
- case 4:
442
- provider = _context.sent;
443
- _context.next = 7;
444
- return provider.resolve(text, type);
445
- case 7:
446
- return _context.abrupt("return", _context.sent);
447
- case 8:
448
- case "end":
449
- return _context.stop();
450
- }
451
- }, _callee);
452
- }));
453
- return _getSmartLinkAdf.apply(this, arguments);
454
- }
455
- function insertAutoMacro(slice, macro, view, from, to) {
456
- if (view) {
457
- // insert the text or linkified/md-converted clipboard data
458
- var selection = view.state.tr.selection;
459
- var tr;
460
- var before;
461
- if (typeof from === 'number' && typeof to === 'number') {
462
- tr = view.state.tr.replaceRange(from, to, slice);
463
- before = tr.mapping.map(from, -1);
464
- } else {
465
- tr = view.state.tr.replaceSelection(slice);
466
- before = tr.mapping.map(selection.from, -1);
467
- }
468
- view.dispatch(tr);
469
-
470
- // replace the text with the macro as a separate transaction
471
- // so the autoconversion generates 2 undo steps
472
- view.dispatch(closeHistory(view.state.tr).replaceRangeWith(before, before + slice.size, macro).scrollIntoView());
473
- return true;
474
- }
475
- return false;
476
- }
477
- export function handleMacroAutoConvert(text, slice, queueCardsFromChangedTr, runMacroAutoConvert, cardsOptions, extensionAutoConverter) {
478
- return function (state, dispatch, view) {
479
- var macro = null;
480
-
481
- // try to use auto convert from extension provider first
482
- if (extensionAutoConverter) {
483
- var extension = extensionAutoConverter(text);
484
- if (extension) {
485
- macro = PMNode.fromJSON(state.schema, extension);
486
- }
487
- }
488
-
489
- // then try from macro provider (which will be removed some time in the future)
490
- if (!macro) {
491
- var _runMacroAutoConvert;
492
- macro = (_runMacroAutoConvert = runMacroAutoConvert === null || runMacroAutoConvert === void 0 ? void 0 : runMacroAutoConvert(state, text)) !== null && _runMacroAutoConvert !== void 0 ? _runMacroAutoConvert : null;
493
- }
494
- if (macro) {
495
- /**
496
- * if FF enabled, run through smart links and check for result
497
- */
498
- if (cardsOptions && cardsOptions.resolveBeforeMacros && cardsOptions.resolveBeforeMacros.length) {
499
- var _startTrackingPastedM;
500
- if (cardsOptions.resolveBeforeMacros.indexOf(macro.attrs.extensionKey) < 0) {
501
- return insertAutoMacro(slice, macro, view);
502
- }
503
- if (!view) {
504
- throw new Error('View is missing');
505
- }
506
- var trackingId = uuid();
507
- var trackingFrom = "handleMacroAutoConvert-from-".concat(trackingId);
508
- var trackingTo = "handleMacroAutoConvert-to-".concat(trackingId);
509
- startTrackingPastedMacroPositions((_startTrackingPastedM = {}, _defineProperty(_startTrackingPastedM, trackingFrom, state.selection.from), _defineProperty(_startTrackingPastedM, trackingTo, state.selection.to), _startTrackingPastedM))(state, dispatch);
510
- getSmartLinkAdf(text, 'inline', cardsOptions).then(function () {
511
- // we use view.state rather than state because state becomes a stale
512
- // state reference after getSmartLinkAdf's async work
513
- var _getPastePluginState = getPastePluginState(view.state),
514
- pastedMacroPositions = _getPastePluginState.pastedMacroPositions;
515
- if (dispatch) {
516
- handleMarkdown(slice, queueCardsFromChangedTr, pastedMacroPositions[trackingFrom], pastedMacroPositions[trackingTo])(view.state, dispatch);
517
- }
518
- }).catch(function () {
519
- var _getPastePluginState2 = getPastePluginState(view.state),
520
- pastedMacroPositions = _getPastePluginState2.pastedMacroPositions;
521
- insertAutoMacro(slice, macro, view, pastedMacroPositions[trackingFrom], pastedMacroPositions[trackingTo]);
522
- }).finally(function () {
523
- stopTrackingPastedMacroPositions([trackingFrom, trackingTo])(view.state, dispatch);
524
- });
525
- return true;
526
- }
527
- return insertAutoMacro(slice, macro, view);
528
- }
529
- return !!macro;
530
- };
531
- }
532
- export function handleCodeBlock(text) {
533
- return function (state, dispatch) {
534
- var codeBlock = state.schema.nodes.codeBlock;
535
- if (text && hasParentNodeOfType(codeBlock)(state.selection)) {
536
- var tr = closeHistory(state.tr);
537
- tr.scrollIntoView();
538
- if (dispatch) {
539
- dispatch(tr.insertText(text));
540
- }
541
- return true;
542
- }
543
- return false;
544
- };
545
- }
546
- function isOnlyMedia(state, slice) {
547
- var media = state.schema.nodes.media;
548
- return slice.content.childCount === 1 && slice.content.firstChild.type === media;
549
- }
550
- function isOnlyMediaSingle(state, slice) {
551
- var mediaSingle = state.schema.nodes.mediaSingle;
552
- return mediaSingle && slice.content.childCount === 1 && slice.content.firstChild.type === mediaSingle;
553
- }
554
- export function handleMediaSingle(inputMethod, insertMediaAsMediaSingle) {
555
- return function (slice) {
556
- return function (state, dispatch, view) {
557
- if (view) {
558
- if (isOnlyMedia(state, slice)) {
559
- var _insertMediaAsMediaSi;
560
- return (_insertMediaAsMediaSi = insertMediaAsMediaSingle === null || insertMediaAsMediaSingle === void 0 ? void 0 : insertMediaAsMediaSingle(view, slice.content.firstChild, inputMethod)) !== null && _insertMediaAsMediaSi !== void 0 ? _insertMediaAsMediaSi : false;
561
- }
562
- if (insideTable(state) && isOnlyMediaSingle(state, slice)) {
563
- var tr = state.tr.replaceSelection(slice);
564
- var nextPos = tr.doc.resolve(tr.mapping.map(state.selection.$from.pos));
565
- if (dispatch) {
566
- dispatch(tr.setSelection(new GapCursorSelection(nextPos, Side.RIGHT)));
567
- }
568
- return true;
569
- }
570
- }
571
- return false;
572
- };
573
- };
574
- }
575
- var checkExpand = function checkExpand(slice) {
576
- var hasExpand = false;
577
- slice.content.forEach(function (node) {
578
- if (node.type.name === 'expand') {
579
- hasExpand = true;
580
- }
581
- });
582
- return hasExpand;
583
- };
584
- export function handleExpandPasteInTable(slice) {
585
- return function (state, dispatch) {
586
- // Do not handle expand if it's not being pasted into a table
587
- // OR if it's nested within another node when being pasted into a table
588
- if (!insideTable(state) || !checkExpand(slice)) {
589
- return false;
590
- }
591
- var _state$schema$nodes2 = state.schema.nodes,
592
- expand = _state$schema$nodes2.expand,
593
- nestedExpand = _state$schema$nodes2.nestedExpand;
594
- var tr = state.tr;
595
- var hasExpand = false;
596
- var newSlice = mapSlice(slice, function (maybeNode) {
597
- if (maybeNode.type === expand) {
598
- hasExpand = true;
599
- try {
600
- return nestedExpand.createChecked(maybeNode.attrs, maybeNode.content, maybeNode.marks);
601
- } catch (e) {
602
- tr = safeInsert(maybeNode, tr.selection.$to.pos)(tr);
603
- return Fragment.empty;
604
- }
605
- }
606
- return maybeNode;
607
- });
608
- if (hasExpand && dispatch) {
609
- // If the slice is a subset, we can let PM replace the selection
610
- // it will insert as text where it can't place the node.
611
- // Otherwise we use safeInsert to insert below instead of
612
- // replacing/splitting the current node.
613
- if (slice.openStart > 1 && slice.openEnd > 1) {
614
- dispatch(tr.replaceSelection(newSlice));
615
- } else {
616
- dispatch(safeInsert(newSlice.content)(tr));
617
- }
618
- return true;
619
- }
620
- return false;
621
- };
622
- }
623
- export function handleMarkdown(markdownSlice, queueCardsFromChangedTr, from, to) {
624
- return function (state, dispatch) {
625
- var tr = closeHistory(state.tr);
626
- var pastesFrom = typeof from === 'number' ? from : tr.selection.from;
627
- if (typeof from === 'number' && typeof to === 'number') {
628
- tr.replaceRange(from, to, markdownSlice);
629
- } else {
630
- tr.replaceSelection(markdownSlice);
631
- }
632
- var textPosition = tr.doc.resolve(Math.min(pastesFrom + markdownSlice.size, tr.doc.content.size));
633
- tr.setSelection(TextSelection.near(textPosition, -1));
634
- queueCardsFromChangedTr === null || queueCardsFromChangedTr === void 0 || queueCardsFromChangedTr(state, tr, INPUT_METHOD.CLIPBOARD);
635
- if (dispatch) {
636
- dispatch(tr.scrollIntoView());
637
- }
638
- return true;
639
- };
640
- }
641
- function removePrecedingBackTick(tr) {
642
- var _tr$selection = tr.selection,
643
- nodeBefore = _tr$selection.$from.nodeBefore,
644
- from = _tr$selection.from;
645
- if (nodeBefore && nodeBefore.isText && nodeBefore.text.endsWith('`')) {
646
- tr.delete(from - 1, from);
647
- }
648
- }
649
- function hasInlineCode(state, slice) {
650
- return slice.content.firstChild && slice.content.firstChild.marks.some(function (m) {
651
- return m.type === state.schema.marks.code;
652
- });
653
- }
654
- function rollupLeafListItems(list, leafListItems) {
655
- list.content.forEach(function (child) {
656
- if (isListNode(child) || isListItemNode(child) && isListNode(child.firstChild)) {
657
- rollupLeafListItems(child, leafListItems);
658
- } else {
659
- leafListItems.push(child);
660
- }
661
- });
662
- }
663
- function shouldFlattenList(state, slice) {
664
- var node = slice.content.firstChild;
665
- return node && insideTable(state) && isListNode(node) && slice.openStart > slice.openEnd;
666
- }
667
- function sliceHasTopLevelMarks(slice) {
668
- var hasTopLevelMarks = false;
669
- slice.content.descendants(function (node) {
670
- if (node.marks.length > 0) {
671
- hasTopLevelMarks = true;
672
- }
673
- return false;
674
- });
675
- return hasTopLevelMarks;
676
- }
677
- function getTopLevelMarkTypesInSlice(slice) {
678
- var markTypes = new Set();
679
- slice.content.descendants(function (node) {
680
- node.marks.map(function (mark) {
681
- return mark.type;
682
- }).forEach(function (markType) {
683
- return markTypes.add(markType);
684
- });
685
- return false;
686
- });
687
- return markTypes;
688
- }
689
- export function handleParagraphBlockMarks(state, slice) {
690
- if (slice.content.size === 0) {
691
- return slice;
692
- }
693
- var schema = state.schema,
694
- $from = state.selection.$from;
695
-
696
- // If no paragraph in the slice contains marks, there's no need for special handling
697
- // Note: this doesn't check for marks applied to lower level nodes such as text
698
- if (!sliceHasTopLevelMarks(slice)) {
699
- return slice;
700
- }
701
-
702
- // If pasting a single paragraph into pre-existing content, match destination formatting
703
- var destinationHasContent = $from.parent.textContent.length > 0;
704
- if (slice.content.childCount === 1 && destinationHasContent) {
705
- return slice;
706
- }
707
-
708
- // Check the parent of (paragraph -> text) because block marks are assigned to a wrapper
709
- // element around the paragraph node
710
- var grandparent = $from.node(Math.max(0, $from.depth - 1));
711
- var markTypesInSlice = getTopLevelMarkTypesInSlice(slice);
712
- var forbiddenMarkTypes = [];
713
- var _iterator = _createForOfIteratorHelper(markTypesInSlice),
714
- _step;
715
- try {
716
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
717
- var markType = _step.value;
718
- if (!grandparent.type.allowsMarkType(markType)) {
719
- forbiddenMarkTypes.push(markType);
720
- }
721
- }
722
- } catch (err) {
723
- _iterator.e(err);
724
- } finally {
725
- _iterator.f();
726
- }
727
- if (forbiddenMarkTypes.length === 0) {
728
- // In a slice containing one or more paragraphs at the document level (not wrapped in
729
- // another node), the first paragraph will only have its text content captured and pasted
730
- // since openStart is 1. We decrement the open depth of the slice so it retains any block
731
- // marks applied to it. We only care about the depth at the start of the selection so
732
- // there's no need to change openEnd - the rest of the slice gets pasted correctly.
733
- var openStart = Math.max(0, slice.openStart - 1);
734
- return new Slice(slice.content, openStart, slice.openEnd);
735
- }
736
-
737
- // If the paragraph contains marks forbidden by the parent node (e.g. alignment/indentation),
738
- // drop those marks from the slice
739
- return mapSlice(slice, function (node) {
740
- if (node.type === schema.nodes.paragraph) {
741
- return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(function (mark) {
742
- return !forbiddenMarkTypes.includes(mark.type);
743
- }));
744
- }
745
- return node;
746
- });
747
- }
748
-
749
- /**
750
- * ED-6300: When a nested list is pasted in a table cell and the slice has openStart > openEnd,
751
- * it splits the table. As a workaround, we flatten the list to even openStart and openEnd.
752
- *
753
- * Note: this only happens if the first child is a list
754
- *
755
- * Example: copying "one" and "two"
756
- * - zero
757
- * - one
758
- * - two
759
- *
760
- * Before:
761
- * ul
762
- * ┗━ li
763
- * ┗━ ul
764
- * ┗━ li
765
- * ┗━ p -> "one"
766
- * ┗━ li
767
- * ┗━ p -> "two"
768
- *
769
- * After:
770
- * ul
771
- * ┗━ li
772
- * ┗━ p -> "one"
773
- * ┗━ li
774
- * ┗━p -> "two"
775
- */
776
- export function flattenNestedListInSlice(slice) {
777
- if (!slice.content.firstChild) {
778
- return slice;
779
- }
780
- var listToFlatten = slice.content.firstChild;
781
- var leafListItems = [];
782
- rollupLeafListItems(listToFlatten, leafListItems);
783
- var contentWithFlattenedList = slice.content.replaceChild(0, listToFlatten.type.createChecked(listToFlatten.attrs, leafListItems));
784
- return new Slice(contentWithFlattenedList, slice.openEnd, slice.openEnd);
785
- }
786
- export function handleRichText(slice, queueCardsFromChangedTr) {
787
- return function (state, dispatch) {
788
- var _slice$content, _slice$content2, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
789
- var _state$schema$nodes3 = state.schema.nodes,
790
- codeBlock = _state$schema$nodes3.codeBlock,
791
- heading = _state$schema$nodes3.heading,
792
- paragraph = _state$schema$nodes3.paragraph,
793
- panel = _state$schema$nodes3.panel;
794
- var selection = state.selection,
795
- schema = state.schema;
796
- var firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
797
- var lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
798
-
799
- // In case user is pasting inline code,
800
- // any backtick ` immediately preceding it should be removed.
801
- var tr = state.tr;
802
- if (hasInlineCode(state, slice)) {
803
- removePrecedingBackTick(tr);
804
- }
805
- if (shouldFlattenList(state, slice)) {
806
- slice = flattenNestedListInSlice(slice);
807
- }
808
- closeHistory(tr);
809
- var isFirstChildListNode = isListNode(firstChildOfSlice);
810
- var isLastChildListNode = isListNode(lastChildOfSlice);
811
- var isSliceContentListNodes = isFirstChildListNode || isLastChildListNode;
812
- var isFirstChildTaskListNode = (firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$ty = firstChildOfSlice.type) === null || _firstChildOfSlice$ty === void 0 ? void 0 : _firstChildOfSlice$ty.name) === 'taskList';
813
- var isLastChildTaskListNode = (lastChildOfSlice === null || lastChildOfSlice === void 0 || (_lastChildOfSlice$typ = lastChildOfSlice.type) === null || _lastChildOfSlice$typ === void 0 ? void 0 : _lastChildOfSlice$typ.name) === 'taskList';
814
- var isSliceContentTaskListNodes = isFirstChildTaskListNode || isLastChildTaskListNode;
815
-
816
- // We want to use safeInsert to insert invalid content, as it inserts at the closest non schema violating position
817
- // rather than spliting the selection parent node in half (which is what replaceSelection does)
818
- // Exception is paragraph and heading nodes, these should be split, provided their parent supports the pasted content
819
- var textNodes = [heading, paragraph];
820
- var selectionParent = selection.$to.node(selection.$to.depth - 1);
821
- var noNeedForSafeInsert = selection.$to.node().type.validContent(slice.content) || textNodes.includes(selection.$to.node().type) && selectionParent.type.validContent(slice.content);
822
- var panelParentOverCurrentSelection = findParentNodeOfType(panel)(tr.selection);
823
- var isTargetPanelEmpty = panelParentOverCurrentSelection && ((_panelParentOverCurre = panelParentOverCurrentSelection.node) === null || _panelParentOverCurre === void 0 ? void 0 : _panelParentOverCurre.content.size) === 2;
824
- if (!isSliceContentTaskListNodes && (isSliceContentListNodes || isTargetPanelEmpty)) {
825
- insertSliceForLists({
826
- tr: tr,
827
- slice: slice,
828
- schema: schema
829
- });
830
- } else if (noNeedForSafeInsert) {
831
- var _firstChildOfSlice$ty2, _firstChildOfSlice$co, _firstChildOfSlice$co2;
832
- if ((firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$ty2 = firstChildOfSlice.type) === null || _firstChildOfSlice$ty2 === void 0 ? void 0 : _firstChildOfSlice$ty2.name) === 'blockquote' && firstChildOfSlice !== null && firstChildOfSlice !== void 0 && (_firstChildOfSlice$co = firstChildOfSlice.content.firstChild) !== null && _firstChildOfSlice$co !== void 0 && _firstChildOfSlice$co.type.name && ['bulletList', 'orderedList'].includes(firstChildOfSlice === null || firstChildOfSlice === void 0 || (_firstChildOfSlice$co2 = firstChildOfSlice.content.firstChild) === null || _firstChildOfSlice$co2 === void 0 ? void 0 : _firstChildOfSlice$co2.type.name)) {
833
- // checks if parent node is a blockquote and child node is either a bulletlist or orderedlist
834
- insertSliceForListsInsideBlockquote({
835
- tr: tr,
836
- slice: slice
837
- });
838
- } else {
839
- var _slice$content$lastCh;
840
- tr.replaceSelection(slice);
841
- // when cursor is inside a table cell, and slice.content.lastChild is a panel, expand, or decisionList
842
- // need to make sure the cursor position is is right after the panel, expand, or decisionList
843
- // still in the same table cell, see issue: https://product-fabric.atlassian.net/browse/ED-17862
844
- var shouldUpdateCursorPosAfterPaste = ['panel', 'nestedExpand', 'decisionList', 'codeBlock'].includes(((_slice$content$lastCh = slice.content.lastChild) === null || _slice$content$lastCh === void 0 || (_slice$content$lastCh = _slice$content$lastCh.type) === null || _slice$content$lastCh === void 0 ? void 0 : _slice$content$lastCh.name) || '');
845
- if (insideTableCell(state) && shouldUpdateCursorPosAfterPaste) {
846
- var nextPos = tr.doc.resolve(tr.mapping.map(selection.$from.pos));
847
- tr.setSelection(new GapCursorSelection(nextPos, Side.RIGHT));
848
- }
849
- }
850
- } else {
851
- // need to scan the slice if there's a block node or list items inside it
852
- var sliceHasList = false;
853
- slice.content.nodesBetween(0, slice.content.size, function (node, start) {
854
- if (node.type === state.schema.nodes.listItem) {
855
- sliceHasList = true;
856
- return false;
857
- }
858
- });
859
- if (insideTableCell(state) && isInListItem(state) && canInsert(selection.$from, slice.content) && canInsert(selection.$to, slice.content) || sliceHasList) {
860
- tr.replaceSelection(slice);
861
- } else {
862
- // need safeInsert rather than replaceSelection, so that nodes aren't split in half
863
- // e.g. when pasting a layout into a table, replaceSelection splits the table in half and adds the layout in the middle
864
- tr = safeInsert(slice.content, tr.selection.$to.pos)(tr);
865
- }
866
- }
867
- tr.setStoredMarks([]);
868
- if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
869
- tr.setSelection(TextSelection.near(tr.selection.$from, 1));
870
- }
871
- tr.scrollIntoView();
872
-
873
- // queue link cards, ignoring any errors
874
- queueCardsFromChangedTr === null || queueCardsFromChangedTr === void 0 || queueCardsFromChangedTr(state, tr, INPUT_METHOD.CLIPBOARD);
875
- if (dispatch) {
876
- dispatch(tr);
877
- }
878
- return true;
879
- };
880
- }
881
- export function handlePasteIntoCaption(slice) {
882
- return function (state, dispatch) {
883
- var caption = state.schema.nodes.caption;
884
- var tr = state.tr;
885
- if (hasParentNodeOfType(caption)(state.selection)) {
886
- // We let PM replace the selection and it will insert as text where it can't place the node
887
- // This is totally fine as caption is just a simple block that only contains inline contents
888
- // And it is more in line with WYSIWYG expectations
889
- tr.replaceSelection(slice).scrollIntoView();
890
- if (dispatch) {
891
- dispatch(tr);
892
- }
893
- return true;
894
- }
895
- return false;
896
- };
897
- }
898
- export var handleSelectedTable = function handleSelectedTable(editorAnalyticsAPI) {
899
- return function (slice) {
900
- return function (state, dispatch) {
901
- var tr = replaceSelectedTable(state, slice);
902
-
903
- // add analytics after replacing selected table
904
- tr = addReplaceSelectedTableAnalytics(state, tr, editorAnalyticsAPI);
905
- if (tr.docChanged) {
906
- if (dispatch) {
907
- dispatch(tr);
908
- }
909
- return true;
910
- }
911
- return false;
912
- };
913
- };
914
- };