@atlaskit/editor-plugin-paste 19.0.11 → 20.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 +20 -0
- package/dist/cjs/pm-plugins/main.js +8 -16
- package/dist/cjs/pm-plugins/util/edge-cases/index.js +0 -15
- package/dist/cjs/pm-plugins/util/handlers.js +3 -12
- package/dist/es2019/pm-plugins/main.js +7 -15
- package/dist/es2019/pm-plugins/util/edge-cases/index.js +0 -15
- package/dist/es2019/pm-plugins/util/handlers.js +3 -12
- package/dist/esm/pm-plugins/main.js +9 -17
- package/dist/esm/pm-plugins/util/edge-cases/index.js +0 -15
- package/dist/esm/pm-plugins/util/handlers.js +3 -12
- package/package.json +14 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste
|
|
2
2
|
|
|
3
|
+
## 20.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`3b3e57040d2d0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3b3e57040d2d0) -
|
|
8
|
+
Remove retired flexible-list feature controls and schema styles while preserving shipped list
|
|
9
|
+
normalization, hidden-marker rendering for wrapper list items, task paste and task-list tab
|
|
10
|
+
behavior, and toolbar indentation behavior.
|
|
11
|
+
|
|
12
|
+
Remove unused legacy list utilities after the flexible-list rollout: `flattenList`,
|
|
13
|
+
`normalizeListItemsSelection`, `hasValidListIndentationLevel`,
|
|
14
|
+
`processNestedTaskListsInSameLevel`, and `wrapTaskListIntoListAbove`. The
|
|
15
|
+
`@atlaskit/editor-common/lists/indentation` entrypoint is also removed.
|
|
16
|
+
|
|
17
|
+
Consumers of the removed runtime helpers should use the editor list plugin's indent/outdent
|
|
18
|
+
commands. The shared `FlattenedItem`, `FlattenListOptions`, and `FlattenListResult` types remain
|
|
19
|
+
available for the active list implementations.
|
|
20
|
+
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
|
|
3
23
|
## 19.0.11
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -309,16 +309,14 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
|
|
|
309
309
|
var isPastingIntoList = false;
|
|
310
310
|
// Pasting list content from an external source — slice top-level contains a list node.
|
|
311
311
|
var isPastingListContent = false;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
312
|
+
var listNodeTypes = [state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.taskList].filter(function (n) {
|
|
313
|
+
return Boolean(n);
|
|
314
|
+
});
|
|
315
|
+
isPastingIntoList = (0, _utils2.hasParentNodeOfType)(listNodeTypes)(state.selection);
|
|
316
|
+
for (var i = 0; i < slice.content.childCount; i++) {
|
|
317
|
+
if (listNodeTypes.includes(slice.content.child(i).type)) {
|
|
318
|
+
isPastingListContent = true;
|
|
319
|
+
break;
|
|
322
320
|
}
|
|
323
321
|
}
|
|
324
322
|
if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !isPastingIntoList && !isPastingListContent && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
|
|
@@ -619,12 +617,6 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
|
|
|
619
617
|
slice = (0, _transforms.transformSingleColumnLayout)(slice, schema);
|
|
620
618
|
}
|
|
621
619
|
slice = (0, _transforms.transformSliceToRemoveMacroId)(slice, schema);
|
|
622
|
-
if ((0, _expValEquals.expValEquals)('platform_editor_flexible_list_schema', 'isEnabled', true) && !(0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
623
|
-
// Prevent pasted externally-authored flexible list HTML from producing flexible list structures
|
|
624
|
-
// Only when schema support is enabled but indentation behaviour is not, meaning editor gracefully
|
|
625
|
-
// handles the structure, but ideally does not produce it
|
|
626
|
-
slice = (0, _transforms.transformSliceEnsureListItemParagraphFirst)(slice, schema);
|
|
627
|
-
}
|
|
628
620
|
return slice;
|
|
629
621
|
},
|
|
630
622
|
transformPastedHTML: function transformPastedHTML(html) {
|
|
@@ -13,8 +13,6 @@ var _model = require("@atlaskit/editor-prosemirror/model");
|
|
|
13
13
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
14
14
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
15
15
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
16
|
-
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
17
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
18
16
|
var _index = require("../index");
|
|
19
17
|
var _lists = require("./lists");
|
|
20
18
|
function insertSliceForLists(_ref) {
|
|
@@ -139,19 +137,6 @@ function insertSliceForTaskInsideList(_ref5) {
|
|
|
139
137
|
slice = _ref5.slice;
|
|
140
138
|
var schema = tr.doc.type.schema;
|
|
141
139
|
|
|
142
|
-
// The corrected insertion path only applies for the flexible list indentation dogfooding audience
|
|
143
|
-
// (`platform_editor_flexible_list_indentation`), and the kill switch protects that audience from
|
|
144
|
-
// regressions. Fall back to the legacy path when the experiment is OFF or the kill switch is ON.
|
|
145
|
-
if (!(0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true) || (0, _fg.fg)('platform_editor_flexible_list_kill_switch_1')) {
|
|
146
|
-
//To avoid the list being replaced with the tasklist, enclose the slice within a taskItem.
|
|
147
|
-
var selectionBeforeReplace = tr.selection.from;
|
|
148
|
-
tr.replaceSelection(new _model.Slice(_model.Fragment.from(schema.nodes.taskItem.createAndFill()), 0, 0));
|
|
149
|
-
var nextSelection = _state.Selection.near(tr.doc.resolve(selectionBeforeReplace + 1));
|
|
150
|
-
tr.setSelection(nextSelection);
|
|
151
|
-
tr.replaceSelection(slice);
|
|
152
|
-
return tr;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
140
|
// Collapse redundant nested taskList wrappers from the slice context, always keeping a single
|
|
156
141
|
// outermost taskList so the content can be safely inserted as a sibling of the list item's
|
|
157
142
|
// paragraph (a listItem cannot directly contain bare taskItems).
|
|
@@ -202,13 +202,13 @@ function handlePasteIntoTaskOrDecisionOrPanel(slice, queueCardsFromChangedTr) {
|
|
|
202
202
|
|
|
203
203
|
// A task slice carrying its own open taskList wrapper would, on a plain replaceSelection,
|
|
204
204
|
// nest that wrapper inside the current item and add an extra taskList level. Unwrapping one
|
|
205
|
-
// level keeps the pasted task(s) at the same level.
|
|
205
|
+
// level keeps the pasted task(s) at the same level.
|
|
206
206
|
var isOpenTaskListSlice = ((_transformedSlice$con = transformedSlice.content.firstChild) === null || _transformedSlice$con === void 0 ? void 0 : _transformedSlice$con.type) === taskList && transformedSlice.openStart >= 2 && transformedSlice.openEnd >= 1;
|
|
207
207
|
// Restrict the unwrap to a taskItem destination: its task content is schema-invalid inside a
|
|
208
208
|
// decisionItem (decisionList only accepts decisionItem), so decisionItem must fall through to
|
|
209
209
|
// the normal replaceSelection path.
|
|
210
210
|
var pastingIntoTaskItem = (0, _utils2.hasParentNodeOfType)([taskItem])(selection);
|
|
211
|
-
if (
|
|
211
|
+
if (isOpenTaskListSlice && pastingIntoTaskItem && !selectionIsPanel) {
|
|
212
212
|
var unwrappedSlice = new _model.Slice(transformedSlice.content.firstChild.content, transformedSlice.openStart - 1, transformedSlice.openEnd - 1);
|
|
213
213
|
tr.replaceSelection(unwrappedSlice).scrollIntoView();
|
|
214
214
|
} else if ((transformedSliceIsValidNode || selectionIsValidNode) && !pastingIntoExtendedPanel && !(transformedSlice.openStart === 1 && transformedSlice.openEnd === 0 ||
|
|
@@ -1443,7 +1443,7 @@ function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1443
1443
|
slice: slice,
|
|
1444
1444
|
schema: schema
|
|
1445
1445
|
});
|
|
1446
|
-
} else if (noNeedForSafeInsert && !
|
|
1446
|
+
} else if (noNeedForSafeInsert && !checkTaskListInList(state, slice)) {
|
|
1447
1447
|
var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
|
|
1448
1448
|
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)) {
|
|
1449
1449
|
// checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
|
|
@@ -1479,16 +1479,7 @@ function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1479
1479
|
});
|
|
1480
1480
|
if ((0, _utils.insideTableCell)(state) && (0, _utils.isInListItem)(state) && (0, _utils2.canInsert)(selection.$from, slice.content) && (0, _utils2.canInsert)(selection.$to, slice.content) || sliceHasList) {
|
|
1481
1481
|
tr.replaceSelection(slice);
|
|
1482
|
-
} else if ((0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true) && !(0, _fg.fg)('platform_editor_flexible_list_kill_switch_1') && checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1483
|
-
// Corrected task-into-list insertion is gated behind the flexible list indentation
|
|
1484
|
-
// experiment and protected by the kill switch.
|
|
1485
|
-
tr = (0, _edgeCases.insertSliceForTaskInsideList)({
|
|
1486
|
-
tr: tr,
|
|
1487
|
-
slice: slice
|
|
1488
|
-
});
|
|
1489
1482
|
} else if (checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1490
|
-
// Legacy path (experiment OFF or kill switch ON): preserve the previous over-nesting
|
|
1491
|
-
// behaviour via the function's internal fallback.
|
|
1492
1483
|
tr = (0, _edgeCases.insertSliceForTaskInsideList)({
|
|
1493
1484
|
tr: tr,
|
|
1494
1485
|
slice: slice
|
|
@@ -9,7 +9,7 @@ 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 { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark,
|
|
12
|
+
import { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, 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';
|
|
@@ -270,14 +270,12 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
270
270
|
let isPastingIntoList = false;
|
|
271
271
|
// Pasting list content from an external source — slice top-level contains a list node.
|
|
272
272
|
let isPastingListContent = false;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
break;
|
|
280
|
-
}
|
|
273
|
+
const listNodeTypes = [state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.taskList].filter(n => Boolean(n));
|
|
274
|
+
isPastingIntoList = hasParentNodeOfType(listNodeTypes)(state.selection);
|
|
275
|
+
for (let i = 0; i < slice.content.childCount; i++) {
|
|
276
|
+
if (listNodeTypes.includes(slice.content.child(i).type)) {
|
|
277
|
+
isPastingListContent = true;
|
|
278
|
+
break;
|
|
281
279
|
}
|
|
282
280
|
}
|
|
283
281
|
if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !isPastingIntoList && !isPastingListContent && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
|
|
@@ -578,12 +576,6 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
578
576
|
slice = transformSingleColumnLayout(slice, schema);
|
|
579
577
|
}
|
|
580
578
|
slice = transformSliceToRemoveMacroId(slice, schema);
|
|
581
|
-
if (expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && !expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
582
|
-
// Prevent pasted externally-authored flexible list HTML from producing flexible list structures
|
|
583
|
-
// Only when schema support is enabled but indentation behaviour is not, meaning editor gracefully
|
|
584
|
-
// handles the structure, but ideally does not produce it
|
|
585
|
-
slice = transformSliceEnsureListItemParagraphFirst(slice, schema);
|
|
586
|
-
}
|
|
587
579
|
return slice;
|
|
588
580
|
},
|
|
589
581
|
transformPastedHTML(html) {
|
|
@@ -4,8 +4,6 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
|
4
4
|
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
6
6
|
import { findParentNodeOfType, safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
7
|
-
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
8
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
7
|
import { isCursorSelectionAtTextStartOrEnd, isEmptyNode, isSelectionInsidePanel } from '../index';
|
|
10
8
|
import { insertSliceAtNodeEdge, insertSliceInsideOfPanelNodeSelected, insertSliceIntoEmptyNode, insertSliceIntoRangeSelectionInsideList } from './lists';
|
|
11
9
|
export function insertSliceForLists({
|
|
@@ -140,19 +138,6 @@ export function insertSliceForTaskInsideList({
|
|
|
140
138
|
schema
|
|
141
139
|
} = tr.doc.type;
|
|
142
140
|
|
|
143
|
-
// The corrected insertion path only applies for the flexible list indentation dogfooding audience
|
|
144
|
-
// (`platform_editor_flexible_list_indentation`), and the kill switch protects that audience from
|
|
145
|
-
// regressions. Fall back to the legacy path when the experiment is OFF or the kill switch is ON.
|
|
146
|
-
if (!expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) || fg('platform_editor_flexible_list_kill_switch_1')) {
|
|
147
|
-
//To avoid the list being replaced with the tasklist, enclose the slice within a taskItem.
|
|
148
|
-
const selectionBeforeReplace = tr.selection.from;
|
|
149
|
-
tr.replaceSelection(new Slice(Fragment.from(schema.nodes.taskItem.createAndFill()), 0, 0));
|
|
150
|
-
const nextSelection = Selection.near(tr.doc.resolve(selectionBeforeReplace + 1));
|
|
151
|
-
tr.setSelection(nextSelection);
|
|
152
|
-
tr.replaceSelection(slice);
|
|
153
|
-
return tr;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
141
|
// Collapse redundant nested taskList wrappers from the slice context, always keeping a single
|
|
157
142
|
// outermost taskList so the content can be safely inserted as a sibling of the list item's
|
|
158
143
|
// paragraph (a listItem cannot directly contain bare taskItems).
|
|
@@ -168,13 +168,13 @@ export function handlePasteIntoTaskOrDecisionOrPanel(slice, queueCardsFromChange
|
|
|
168
168
|
|
|
169
169
|
// A task slice carrying its own open taskList wrapper would, on a plain replaceSelection,
|
|
170
170
|
// nest that wrapper inside the current item and add an extra taskList level. Unwrapping one
|
|
171
|
-
// level keeps the pasted task(s) at the same level.
|
|
171
|
+
// level keeps the pasted task(s) at the same level.
|
|
172
172
|
const isOpenTaskListSlice = ((_transformedSlice$con = transformedSlice.content.firstChild) === null || _transformedSlice$con === void 0 ? void 0 : _transformedSlice$con.type) === taskList && transformedSlice.openStart >= 2 && transformedSlice.openEnd >= 1;
|
|
173
173
|
// Restrict the unwrap to a taskItem destination: its task content is schema-invalid inside a
|
|
174
174
|
// decisionItem (decisionList only accepts decisionItem), so decisionItem must fall through to
|
|
175
175
|
// the normal replaceSelection path.
|
|
176
176
|
const pastingIntoTaskItem = hasParentNodeOfType([taskItem])(selection);
|
|
177
|
-
if (
|
|
177
|
+
if (isOpenTaskListSlice && pastingIntoTaskItem && !selectionIsPanel) {
|
|
178
178
|
const unwrappedSlice = new Slice(transformedSlice.content.firstChild.content, transformedSlice.openStart - 1, transformedSlice.openEnd - 1);
|
|
179
179
|
tr.replaceSelection(unwrappedSlice).scrollIntoView();
|
|
180
180
|
} else if ((transformedSliceIsValidNode || selectionIsValidNode) && !pastingIntoExtendedPanel && !(transformedSlice.openStart === 1 && transformedSlice.openEnd === 0 ||
|
|
@@ -1425,7 +1425,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1425
1425
|
slice,
|
|
1426
1426
|
schema
|
|
1427
1427
|
});
|
|
1428
|
-
} else if (noNeedForSafeInsert && !
|
|
1428
|
+
} else if (noNeedForSafeInsert && !checkTaskListInList(state, slice)) {
|
|
1429
1429
|
var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
|
|
1430
1430
|
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)) {
|
|
1431
1431
|
// checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
|
|
@@ -1461,16 +1461,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1461
1461
|
});
|
|
1462
1462
|
if (insideTableCell(state) && isInListItem(state) && canInsert(selection.$from, slice.content) && canInsert(selection.$to, slice.content) || sliceHasList) {
|
|
1463
1463
|
tr.replaceSelection(slice);
|
|
1464
|
-
} else if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) && !fg('platform_editor_flexible_list_kill_switch_1') && checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1465
|
-
// Corrected task-into-list insertion is gated behind the flexible list indentation
|
|
1466
|
-
// experiment and protected by the kill switch.
|
|
1467
|
-
tr = insertSliceForTaskInsideList({
|
|
1468
|
-
tr,
|
|
1469
|
-
slice
|
|
1470
|
-
});
|
|
1471
1464
|
} else if (checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1472
|
-
// Legacy path (experiment OFF or kill switch ON): preserve the previous over-nesting
|
|
1473
|
-
// behaviour via the function's internal fallback.
|
|
1474
1465
|
tr = insertSliceForTaskInsideList({
|
|
1475
1466
|
tr,
|
|
1476
1467
|
slice
|
|
@@ -14,7 +14,7 @@ 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 { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark,
|
|
17
|
+
import { removeBreakoutFromRendererSyncBlockHTML, transformSingleColumnLayout, transformSingleLineCodeBlockToCodeMark, 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';
|
|
@@ -301,16 +301,14 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
301
301
|
var isPastingIntoList = false;
|
|
302
302
|
// Pasting list content from an external source — slice top-level contains a list node.
|
|
303
303
|
var isPastingListContent = false;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
304
|
+
var listNodeTypes = [state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.taskList].filter(function (n) {
|
|
305
|
+
return Boolean(n);
|
|
306
|
+
});
|
|
307
|
+
isPastingIntoList = hasParentNodeOfType(listNodeTypes)(state.selection);
|
|
308
|
+
for (var i = 0; i < slice.content.childCount; i++) {
|
|
309
|
+
if (listNodeTypes.includes(slice.content.child(i).type)) {
|
|
310
|
+
isPastingListContent = true;
|
|
311
|
+
break;
|
|
314
312
|
}
|
|
315
313
|
}
|
|
316
314
|
if (!isPastingTextInsidePlaceholderText && !isPastingTable && !isPastingOverLayoutColumns && !isPastingIntoList && !isPastingListContent && pluginInjectionApi !== null && pluginInjectionApi !== void 0 && pluginInjectionApi.betterTypeHistory) {
|
|
@@ -611,12 +609,6 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
611
609
|
slice = transformSingleColumnLayout(slice, schema);
|
|
612
610
|
}
|
|
613
611
|
slice = transformSliceToRemoveMacroId(slice, schema);
|
|
614
|
-
if (expValEquals('platform_editor_flexible_list_schema', 'isEnabled', true) && !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 = transformSliceEnsureListItemParagraphFirst(slice, schema);
|
|
619
|
-
}
|
|
620
612
|
return slice;
|
|
621
613
|
},
|
|
622
614
|
transformPastedHTML: function transformPastedHTML(html) {
|
|
@@ -4,8 +4,6 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
|
4
4
|
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
6
6
|
import { findParentNodeOfType, safeInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
7
|
-
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
8
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
7
|
import { isCursorSelectionAtTextStartOrEnd, isEmptyNode, isSelectionInsidePanel } from '../index';
|
|
10
8
|
import { insertSliceAtNodeEdge, insertSliceInsideOfPanelNodeSelected, insertSliceIntoEmptyNode, insertSliceIntoRangeSelectionInsideList } from './lists';
|
|
11
9
|
export function insertSliceForLists(_ref) {
|
|
@@ -130,19 +128,6 @@ export function insertSliceForTaskInsideList(_ref5) {
|
|
|
130
128
|
slice = _ref5.slice;
|
|
131
129
|
var schema = tr.doc.type.schema;
|
|
132
130
|
|
|
133
|
-
// The corrected insertion path only applies for the flexible list indentation dogfooding audience
|
|
134
|
-
// (`platform_editor_flexible_list_indentation`), and the kill switch protects that audience from
|
|
135
|
-
// regressions. Fall back to the legacy path when the experiment is OFF or the kill switch is ON.
|
|
136
|
-
if (!expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) || fg('platform_editor_flexible_list_kill_switch_1')) {
|
|
137
|
-
//To avoid the list being replaced with the tasklist, enclose the slice within a taskItem.
|
|
138
|
-
var selectionBeforeReplace = tr.selection.from;
|
|
139
|
-
tr.replaceSelection(new Slice(Fragment.from(schema.nodes.taskItem.createAndFill()), 0, 0));
|
|
140
|
-
var nextSelection = Selection.near(tr.doc.resolve(selectionBeforeReplace + 1));
|
|
141
|
-
tr.setSelection(nextSelection);
|
|
142
|
-
tr.replaceSelection(slice);
|
|
143
|
-
return tr;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
131
|
// Collapse redundant nested taskList wrappers from the slice context, always keeping a single
|
|
147
132
|
// outermost taskList so the content can be safely inserted as a sibling of the list item's
|
|
148
133
|
// paragraph (a listItem cannot directly contain bare taskItems).
|
|
@@ -173,13 +173,13 @@ export function handlePasteIntoTaskOrDecisionOrPanel(slice, queueCardsFromChange
|
|
|
173
173
|
|
|
174
174
|
// A task slice carrying its own open taskList wrapper would, on a plain replaceSelection,
|
|
175
175
|
// nest that wrapper inside the current item and add an extra taskList level. Unwrapping one
|
|
176
|
-
// level keeps the pasted task(s) at the same level.
|
|
176
|
+
// level keeps the pasted task(s) at the same level.
|
|
177
177
|
var isOpenTaskListSlice = ((_transformedSlice$con = transformedSlice.content.firstChild) === null || _transformedSlice$con === void 0 ? void 0 : _transformedSlice$con.type) === taskList && transformedSlice.openStart >= 2 && transformedSlice.openEnd >= 1;
|
|
178
178
|
// Restrict the unwrap to a taskItem destination: its task content is schema-invalid inside a
|
|
179
179
|
// decisionItem (decisionList only accepts decisionItem), so decisionItem must fall through to
|
|
180
180
|
// the normal replaceSelection path.
|
|
181
181
|
var pastingIntoTaskItem = hasParentNodeOfType([taskItem])(selection);
|
|
182
|
-
if (
|
|
182
|
+
if (isOpenTaskListSlice && pastingIntoTaskItem && !selectionIsPanel) {
|
|
183
183
|
var unwrappedSlice = new Slice(transformedSlice.content.firstChild.content, transformedSlice.openStart - 1, transformedSlice.openEnd - 1);
|
|
184
184
|
tr.replaceSelection(unwrappedSlice).scrollIntoView();
|
|
185
185
|
} else if ((transformedSliceIsValidNode || selectionIsValidNode) && !pastingIntoExtendedPanel && !(transformedSlice.openStart === 1 && transformedSlice.openEnd === 0 ||
|
|
@@ -1414,7 +1414,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1414
1414
|
slice: slice,
|
|
1415
1415
|
schema: schema
|
|
1416
1416
|
});
|
|
1417
|
-
} else if (noNeedForSafeInsert && !
|
|
1417
|
+
} else if (noNeedForSafeInsert && !checkTaskListInList(state, slice)) {
|
|
1418
1418
|
var _firstChildOfSlice$ty3, _firstChildOfSlice$co2, _firstChildOfSlice$co3;
|
|
1419
1419
|
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)) {
|
|
1420
1420
|
// checks if parent node is a blockquote and child node is either a bulletlist or orderedlist or mediaSingle
|
|
@@ -1450,16 +1450,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1450
1450
|
});
|
|
1451
1451
|
if (insideTableCell(state) && isInListItem(state) && canInsert(selection.$from, slice.content) && canInsert(selection.$to, slice.content) || sliceHasList) {
|
|
1452
1452
|
tr.replaceSelection(slice);
|
|
1453
|
-
} else if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true) && !fg('platform_editor_flexible_list_kill_switch_1') && checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1454
|
-
// Corrected task-into-list insertion is gated behind the flexible list indentation
|
|
1455
|
-
// experiment and protected by the kill switch.
|
|
1456
|
-
tr = insertSliceForTaskInsideList({
|
|
1457
|
-
tr: tr,
|
|
1458
|
-
slice: slice
|
|
1459
|
-
});
|
|
1460
1453
|
} else if (checkTaskListInList(state, slice) && !checkIfSelectionInNestedList(state)) {
|
|
1461
|
-
// Legacy path (experiment OFF or kill switch ON): preserve the previous over-nesting
|
|
1462
|
-
// behaviour via the function's internal fallback.
|
|
1463
1454
|
tr = insertSliceForTaskInsideList({
|
|
1464
1455
|
tr: tr,
|
|
1465
1456
|
slice: slice
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-paste",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.0.0",
|
|
4
4
|
"description": "Paste plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,17 +23,17 @@
|
|
|
23
23
|
"@atlaskit/adf-utils": "^20.9.0",
|
|
24
24
|
"@atlaskit/code": "^19.2.0",
|
|
25
25
|
"@atlaskit/editor-markdown-transformer": "^6.3.0",
|
|
26
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
27
|
-
"@atlaskit/editor-plugin-annotation": "^
|
|
28
|
-
"@atlaskit/editor-plugin-better-type-history": "^
|
|
29
|
-
"@atlaskit/editor-plugin-card": "^
|
|
30
|
-
"@atlaskit/editor-plugin-expand": "^
|
|
31
|
-
"@atlaskit/editor-plugin-extension": "^
|
|
32
|
-
"@atlaskit/editor-plugin-feature-flags": "^
|
|
33
|
-
"@atlaskit/editor-plugin-list": "^
|
|
34
|
-
"@atlaskit/editor-plugin-media": "^
|
|
35
|
-
"@atlaskit/editor-plugin-mentions": "^
|
|
36
|
-
"@atlaskit/editor-prosemirror": "^
|
|
26
|
+
"@atlaskit/editor-plugin-analytics": "^19.0.0",
|
|
27
|
+
"@atlaskit/editor-plugin-annotation": "^19.0.0",
|
|
28
|
+
"@atlaskit/editor-plugin-better-type-history": "^19.0.0",
|
|
29
|
+
"@atlaskit/editor-plugin-card": "^25.0.0",
|
|
30
|
+
"@atlaskit/editor-plugin-expand": "^20.0.0",
|
|
31
|
+
"@atlaskit/editor-plugin-extension": "^22.0.0",
|
|
32
|
+
"@atlaskit/editor-plugin-feature-flags": "^18.0.0",
|
|
33
|
+
"@atlaskit/editor-plugin-list": "^21.0.0",
|
|
34
|
+
"@atlaskit/editor-plugin-media": "^21.0.0",
|
|
35
|
+
"@atlaskit/editor-plugin-mentions": "^21.0.0",
|
|
36
|
+
"@atlaskit/editor-prosemirror": "^9.0.0",
|
|
37
37
|
"@atlaskit/editor-tables": "^3.2.0",
|
|
38
38
|
"@atlaskit/flag": "^18.5.0",
|
|
39
39
|
"@atlaskit/icon": "^37.7.0",
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
46
46
|
"@atlaskit/prosemirror-history": "^1.2.0",
|
|
47
47
|
"@atlaskit/tmp-editor-statsig": "^199.0.0",
|
|
48
|
-
"@atlaskit/tokens": "^18.
|
|
48
|
+
"@atlaskit/tokens": "^18.2.0",
|
|
49
49
|
"@babel/runtime": "^7.0.0",
|
|
50
50
|
"lodash": "^4.17.21",
|
|
51
51
|
"uuid": "^11.1.1"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@atlaskit/editor-common": "^
|
|
54
|
+
"@atlaskit/editor-common": "^123.0.0",
|
|
55
55
|
"react": "^18.2.0 || ^19.2.0",
|
|
56
56
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
57
57
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -78,9 +78,6 @@
|
|
|
78
78
|
},
|
|
79
79
|
"platform_media_cross_client_copy_with_auth": {
|
|
80
80
|
"type": "boolean"
|
|
81
|
-
},
|
|
82
|
-
"platform_editor_flexible_list_kill_switch_1": {
|
|
83
|
-
"type": "boolean"
|
|
84
81
|
}
|
|
85
82
|
},
|
|
86
83
|
"platform-experiments": {
|