@atlaskit/editor-plugin-paste 11.0.4 → 11.0.5
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,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste
|
|
2
2
|
|
|
3
|
+
## 11.0.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`583f16df338b0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/583f16df338b0) -
|
|
8
|
+
Normalise small text fontSize mark on paste: strip fontSize when pasting into headings, and
|
|
9
|
+
preserve source style when pasting normal text into small-text paragraphs
|
|
10
|
+
|
|
3
11
|
## 11.0.4
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -992,7 +992,7 @@ function handleParagraphBlockMarks(state, slice) {
|
|
|
992
992
|
paragraph = _schema$nodes3.paragraph,
|
|
993
993
|
heading = _schema$nodes3.heading;
|
|
994
994
|
var fontSize = schema.marks.fontSize;
|
|
995
|
-
var isSmallFontSizeEnabled = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)
|
|
995
|
+
var isSmallFontSizeEnabled = !!fontSize && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
996
996
|
|
|
997
997
|
// When copying from inside a container (e.g. panel, expand), ProseMirror wraps the
|
|
998
998
|
// content back in the container via addContext(), increasing openStart/openEnd. Unwrap
|
|
@@ -1005,6 +1005,7 @@ function handleParagraphBlockMarks(state, slice) {
|
|
|
1005
1005
|
var isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem || $from.parent.type === taskItem;
|
|
1006
1006
|
var isInSmallTaskContext = !!blockTaskItem && ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem || $from.parent.type === blockTaskItem || $from.parent.type === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem);
|
|
1007
1007
|
var destinationBlockMarkAttrs = isSmallFontSizeEnabled ? getDestinationFontSizeAttrs(destinationListNode, isInSmallTaskContext, $from, currentNode, fontSize) : false;
|
|
1008
|
+
var isInHeadingContext = $from.parent.type === heading;
|
|
1008
1009
|
|
|
1009
1010
|
// If no paragraph in the slice contains marks, there's no need for special handling
|
|
1010
1011
|
// unless we're pasting into a small-text list and need to add the destination block mark.
|
|
@@ -1012,7 +1013,7 @@ function handleParagraphBlockMarks(state, slice) {
|
|
|
1012
1013
|
if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
|
|
1013
1014
|
return slice;
|
|
1014
1015
|
}
|
|
1015
|
-
var shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext);
|
|
1016
|
+
var shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext || isInHeadingContext);
|
|
1016
1017
|
|
|
1017
1018
|
// If pasting a single paragraph into pre-existing content, match destination formatting.
|
|
1018
1019
|
// For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
|
|
@@ -1065,7 +1066,9 @@ function handleParagraphBlockMarks(state, slice) {
|
|
|
1065
1066
|
return new _model.Slice(slice.content, openStart, slice.openEnd);
|
|
1066
1067
|
}
|
|
1067
1068
|
if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
|
|
1068
|
-
|
|
1069
|
+
// When pasting into a heading, keep the original openStart so ProseMirror merges inline
|
|
1070
|
+
// content into the heading node rather than replacing it with a paragraph.
|
|
1071
|
+
var _openStart = isInHeadingContext ? slice.openStart : Math.max(0, slice.openStart - 1);
|
|
1069
1072
|
return new _model.Slice(normalizedContent.content, _openStart, slice.openEnd);
|
|
1070
1073
|
}
|
|
1071
1074
|
|
|
@@ -1142,7 +1145,9 @@ function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1142
1145
|
var firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
|
|
1143
1146
|
var lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
|
|
1144
1147
|
var listContainerNodeTypes = [bulletList, orderedList];
|
|
1145
|
-
var
|
|
1148
|
+
var isSmallFontSizeEnabled = !!fontSize && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
1149
|
+
var destinationListNode = isSmallFontSizeEnabled ? (_findParentNodeOfType3 = (0, _utils2.findParentNodeOfType)(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node : undefined;
|
|
1150
|
+
var destinationListFontSizeAttrs = isSmallFontSizeEnabled ? (0, _lists.getFirstParagraphBlockMarkAttrs)(destinationListNode, fontSize) : false;
|
|
1146
1151
|
|
|
1147
1152
|
// In case user is pasting inline code,
|
|
1148
1153
|
// any backtick ` immediately preceding it should be removed.
|
|
@@ -1162,6 +1167,17 @@ function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1162
1167
|
var isSliceContentTaskListNodes = isFirstChildTaskListNode || isLastChildTaskListNode;
|
|
1163
1168
|
var sliceContentBlockquoteListNodes = doesSliceContainBlockquoteListNodes(slice, listContainerNodeTypes);
|
|
1164
1169
|
|
|
1170
|
+
// Compute once and reuse below to avoid traversing the slice twice.
|
|
1171
|
+
var sliceMarkTypes = isSmallFontSizeEnabled ? getTopLevelMarkTypesInSlice(slice) : new Set();
|
|
1172
|
+
var destinationIsEmpty = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && selection.$from.parent.textContent.length === 0;
|
|
1173
|
+
|
|
1174
|
+
// Capture the destination paragraph's non-fontSize block marks (e.g. alignment, indentation)
|
|
1175
|
+
// before the paste so they can be restored if the paste replaces the paragraph entirely
|
|
1176
|
+
// (which happens when small text is pasted with openStart=0).
|
|
1177
|
+
var destinationNonFontSizeBlockMarks = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && sliceMarkTypes.has(fontSize) ? selection.$from.parent.marks.filter(function (m) {
|
|
1178
|
+
return m.type !== fontSize;
|
|
1179
|
+
}) : [];
|
|
1180
|
+
|
|
1165
1181
|
// We want to use safeInsert to insert invalid content, as it inserts at the closest non schema violating position
|
|
1166
1182
|
// rather than spliting the selection parent node in half (which is what replaceSelection does)
|
|
1167
1183
|
// Exception is paragraph and heading nodes, these should be split, provided their parent supports the pasted content
|
|
@@ -1228,12 +1244,38 @@ function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1228
1244
|
}
|
|
1229
1245
|
}
|
|
1230
1246
|
}
|
|
1231
|
-
|
|
1247
|
+
|
|
1248
|
+
// font size handling for pasting into lists or blockquotes
|
|
1249
|
+
if (isSmallFontSizeEnabled && (isSliceContentListNodes || sliceContentBlockquoteListNodes)) {
|
|
1232
1250
|
var containingList = (0, _utils2.findParentNodeOfTypeClosestToPos)(tr.selection.$from, listContainerNodeTypes);
|
|
1233
1251
|
if (containingList) {
|
|
1234
1252
|
(0, _lists.reconcileBlockMarkForContainerAtPos)(tr, containingList.pos, fontSize, isSliceContentListNodes ? destinationListFontSizeAttrs : false);
|
|
1235
1253
|
}
|
|
1236
1254
|
}
|
|
1255
|
+
|
|
1256
|
+
// font size handling for pasting into paragraphs (normal text) - preserve source style
|
|
1257
|
+
if (isSmallFontSizeEnabled && destinationIsEmpty && !sliceMarkTypes.has(fontSize) && !destinationListNode && selection.$from.parent.type === paragraph && (0, _lists.getBlockMarkAttrs)(selection.$from.parent, fontSize)) {
|
|
1258
|
+
(0, _lists.reconcileBlockMarkForParagraphAtPos)(tr, tr.mapping.map(selection.$from.pos), fontSize, false);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
// Restore destination block marks (e.g. alignment) that were lost when pasting small text
|
|
1262
|
+
// replaced the paragraph entirely (openStart=0 from container unwrap).
|
|
1263
|
+
if (isSmallFontSizeEnabled && destinationNonFontSizeBlockMarks.length > 0) {
|
|
1264
|
+
var pastedFrom = tr.mapping.map(selection.from, -1);
|
|
1265
|
+
var pastedTo = tr.mapping.map(selection.to, 1);
|
|
1266
|
+
var _iterator2 = _createForOfIteratorHelper(destinationNonFontSizeBlockMarks),
|
|
1267
|
+
_step2;
|
|
1268
|
+
try {
|
|
1269
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1270
|
+
var mark = _step2.value;
|
|
1271
|
+
(0, _lists.reconcileBlockMarkInRange)(tr, pastedFrom, pastedTo, mark.type, mark.attrs);
|
|
1272
|
+
}
|
|
1273
|
+
} catch (err) {
|
|
1274
|
+
_iterator2.e(err);
|
|
1275
|
+
} finally {
|
|
1276
|
+
_iterator2.f();
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1237
1279
|
tr.setStoredMarks([]);
|
|
1238
1280
|
if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
|
|
1239
1281
|
tr.setSelection(_state.TextSelection.near(tr.selection.$from, 1));
|
|
@@ -3,7 +3,7 @@ import uuid from 'uuid/v4';
|
|
|
3
3
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { addLinkMetadata } from '@atlaskit/editor-common/card';
|
|
5
5
|
import { insideTable } from '@atlaskit/editor-common/core-utils';
|
|
6
|
-
import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForContainerAtPos } from '@atlaskit/editor-common/lists';
|
|
6
|
+
import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForContainerAtPos, reconcileBlockMarkForParagraphAtPos, reconcileBlockMarkInRange } from '@atlaskit/editor-common/lists';
|
|
7
7
|
import { anyMarkActive } from '@atlaskit/editor-common/mark';
|
|
8
8
|
import { getParentOfTypeCount, getPositionAfterTopParentNodeOfType } from '@atlaskit/editor-common/nesting';
|
|
9
9
|
import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
@@ -979,7 +979,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
979
979
|
const {
|
|
980
980
|
fontSize
|
|
981
981
|
} = schema.marks;
|
|
982
|
-
const isSmallFontSizeEnabled = expValEquals('platform_editor_small_font_size', 'isEnabled', true)
|
|
982
|
+
const isSmallFontSizeEnabled = !!fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
983
983
|
|
|
984
984
|
// When copying from inside a container (e.g. panel, expand), ProseMirror wraps the
|
|
985
985
|
// content back in the container via addContext(), increasing openStart/openEnd. Unwrap
|
|
@@ -992,6 +992,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
992
992
|
const isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem || $from.parent.type === taskItem;
|
|
993
993
|
const isInSmallTaskContext = !!blockTaskItem && ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem || $from.parent.type === blockTaskItem || $from.parent.type === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem);
|
|
994
994
|
const destinationBlockMarkAttrs = isSmallFontSizeEnabled ? getDestinationFontSizeAttrs(destinationListNode, isInSmallTaskContext, $from, currentNode, fontSize) : false;
|
|
995
|
+
const isInHeadingContext = $from.parent.type === heading;
|
|
995
996
|
|
|
996
997
|
// If no paragraph in the slice contains marks, there's no need for special handling
|
|
997
998
|
// unless we're pasting into a small-text list and need to add the destination block mark.
|
|
@@ -999,7 +1000,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
999
1000
|
if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
|
|
1000
1001
|
return slice;
|
|
1001
1002
|
}
|
|
1002
|
-
const shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext);
|
|
1003
|
+
const shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext || isInHeadingContext);
|
|
1003
1004
|
|
|
1004
1005
|
// If pasting a single paragraph into pre-existing content, match destination formatting.
|
|
1005
1006
|
// For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
|
|
@@ -1039,7 +1040,9 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
1039
1040
|
return new Slice(slice.content, openStart, slice.openEnd);
|
|
1040
1041
|
}
|
|
1041
1042
|
if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
|
|
1042
|
-
|
|
1043
|
+
// When pasting into a heading, keep the original openStart so ProseMirror merges inline
|
|
1044
|
+
// content into the heading node rather than replacing it with a paragraph.
|
|
1045
|
+
const openStart = isInHeadingContext ? slice.openStart : Math.max(0, slice.openStart - 1);
|
|
1043
1046
|
return new Slice(normalizedContent.content, openStart, slice.openEnd);
|
|
1044
1047
|
}
|
|
1045
1048
|
|
|
@@ -1121,7 +1124,9 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1121
1124
|
const firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
|
|
1122
1125
|
const lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
|
|
1123
1126
|
const listContainerNodeTypes = [bulletList, orderedList];
|
|
1124
|
-
const
|
|
1127
|
+
const isSmallFontSizeEnabled = !!fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
1128
|
+
const destinationListNode = isSmallFontSizeEnabled ? (_findParentNodeOfType3 = findParentNodeOfType(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node : undefined;
|
|
1129
|
+
const destinationListFontSizeAttrs = isSmallFontSizeEnabled ? getFirstParagraphBlockMarkAttrs(destinationListNode, fontSize) : false;
|
|
1125
1130
|
|
|
1126
1131
|
// In case user is pasting inline code,
|
|
1127
1132
|
// any backtick ` immediately preceding it should be removed.
|
|
@@ -1141,6 +1146,15 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1141
1146
|
const isSliceContentTaskListNodes = isFirstChildTaskListNode || isLastChildTaskListNode;
|
|
1142
1147
|
const sliceContentBlockquoteListNodes = doesSliceContainBlockquoteListNodes(slice, listContainerNodeTypes);
|
|
1143
1148
|
|
|
1149
|
+
// Compute once and reuse below to avoid traversing the slice twice.
|
|
1150
|
+
const sliceMarkTypes = isSmallFontSizeEnabled ? getTopLevelMarkTypesInSlice(slice) : new Set();
|
|
1151
|
+
const destinationIsEmpty = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && selection.$from.parent.textContent.length === 0;
|
|
1152
|
+
|
|
1153
|
+
// Capture the destination paragraph's non-fontSize block marks (e.g. alignment, indentation)
|
|
1154
|
+
// before the paste so they can be restored if the paste replaces the paragraph entirely
|
|
1155
|
+
// (which happens when small text is pasted with openStart=0).
|
|
1156
|
+
const destinationNonFontSizeBlockMarks = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && sliceMarkTypes.has(fontSize) ? selection.$from.parent.marks.filter(m => m.type !== fontSize) : [];
|
|
1157
|
+
|
|
1144
1158
|
// We want to use safeInsert to insert invalid content, as it inserts at the closest non schema violating position
|
|
1145
1159
|
// rather than spliting the selection parent node in half (which is what replaceSelection does)
|
|
1146
1160
|
// Exception is paragraph and heading nodes, these should be split, provided their parent supports the pasted content
|
|
@@ -1207,12 +1221,29 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1207
1221
|
}
|
|
1208
1222
|
}
|
|
1209
1223
|
}
|
|
1210
|
-
|
|
1224
|
+
|
|
1225
|
+
// font size handling for pasting into lists or blockquotes
|
|
1226
|
+
if (isSmallFontSizeEnabled && (isSliceContentListNodes || sliceContentBlockquoteListNodes)) {
|
|
1211
1227
|
const containingList = findParentNodeOfTypeClosestToPos(tr.selection.$from, listContainerNodeTypes);
|
|
1212
1228
|
if (containingList) {
|
|
1213
1229
|
reconcileBlockMarkForContainerAtPos(tr, containingList.pos, fontSize, isSliceContentListNodes ? destinationListFontSizeAttrs : false);
|
|
1214
1230
|
}
|
|
1215
1231
|
}
|
|
1232
|
+
|
|
1233
|
+
// font size handling for pasting into paragraphs (normal text) - preserve source style
|
|
1234
|
+
if (isSmallFontSizeEnabled && destinationIsEmpty && !sliceMarkTypes.has(fontSize) && !destinationListNode && selection.$from.parent.type === paragraph && getBlockMarkAttrs(selection.$from.parent, fontSize)) {
|
|
1235
|
+
reconcileBlockMarkForParagraphAtPos(tr, tr.mapping.map(selection.$from.pos), fontSize, false);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// Restore destination block marks (e.g. alignment) that were lost when pasting small text
|
|
1239
|
+
// replaced the paragraph entirely (openStart=0 from container unwrap).
|
|
1240
|
+
if (isSmallFontSizeEnabled && destinationNonFontSizeBlockMarks.length > 0) {
|
|
1241
|
+
const pastedFrom = tr.mapping.map(selection.from, -1);
|
|
1242
|
+
const pastedTo = tr.mapping.map(selection.to, 1);
|
|
1243
|
+
for (const mark of destinationNonFontSizeBlockMarks) {
|
|
1244
|
+
reconcileBlockMarkInRange(tr, pastedFrom, pastedTo, mark.type, mark.attrs);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1216
1247
|
tr.setStoredMarks([]);
|
|
1217
1248
|
if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
|
|
1218
1249
|
tr.setSelection(TextSelection.near(tr.selection.$from, 1));
|
|
@@ -11,7 +11,7 @@ import uuid from 'uuid/v4';
|
|
|
11
11
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
12
12
|
import { addLinkMetadata } from '@atlaskit/editor-common/card';
|
|
13
13
|
import { insideTable } from '@atlaskit/editor-common/core-utils';
|
|
14
|
-
import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForContainerAtPos } from '@atlaskit/editor-common/lists';
|
|
14
|
+
import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForContainerAtPos, reconcileBlockMarkForParagraphAtPos, reconcileBlockMarkInRange } from '@atlaskit/editor-common/lists';
|
|
15
15
|
import { anyMarkActive } from '@atlaskit/editor-common/mark';
|
|
16
16
|
import { getParentOfTypeCount, getPositionAfterTopParentNodeOfType } from '@atlaskit/editor-common/nesting';
|
|
17
17
|
import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
@@ -965,7 +965,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
965
965
|
paragraph = _schema$nodes3.paragraph,
|
|
966
966
|
heading = _schema$nodes3.heading;
|
|
967
967
|
var fontSize = schema.marks.fontSize;
|
|
968
|
-
var isSmallFontSizeEnabled = expValEquals('platform_editor_small_font_size', 'isEnabled', true)
|
|
968
|
+
var isSmallFontSizeEnabled = !!fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
969
969
|
|
|
970
970
|
// When copying from inside a container (e.g. panel, expand), ProseMirror wraps the
|
|
971
971
|
// content back in the container via addContext(), increasing openStart/openEnd. Unwrap
|
|
@@ -978,6 +978,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
978
978
|
var isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem || $from.parent.type === taskItem;
|
|
979
979
|
var isInSmallTaskContext = !!blockTaskItem && ((currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem || $from.parent.type === blockTaskItem || $from.parent.type === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem);
|
|
980
980
|
var destinationBlockMarkAttrs = isSmallFontSizeEnabled ? getDestinationFontSizeAttrs(destinationListNode, isInSmallTaskContext, $from, currentNode, fontSize) : false;
|
|
981
|
+
var isInHeadingContext = $from.parent.type === heading;
|
|
981
982
|
|
|
982
983
|
// If no paragraph in the slice contains marks, there's no need for special handling
|
|
983
984
|
// unless we're pasting into a small-text list and need to add the destination block mark.
|
|
@@ -985,7 +986,7 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
985
986
|
if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
|
|
986
987
|
return slice;
|
|
987
988
|
}
|
|
988
|
-
var shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext);
|
|
989
|
+
var shouldNormalizeFontSizeForTarget = isSmallFontSizeEnabled && (!!destinationListNode || isInNormalTaskContext || isInSmallTaskContext || isInHeadingContext);
|
|
989
990
|
|
|
990
991
|
// If pasting a single paragraph into pre-existing content, match destination formatting.
|
|
991
992
|
// For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
|
|
@@ -1038,7 +1039,9 @@ export function handleParagraphBlockMarks(state, slice) {
|
|
|
1038
1039
|
return new Slice(slice.content, openStart, slice.openEnd);
|
|
1039
1040
|
}
|
|
1040
1041
|
if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
|
|
1041
|
-
|
|
1042
|
+
// When pasting into a heading, keep the original openStart so ProseMirror merges inline
|
|
1043
|
+
// content into the heading node rather than replacing it with a paragraph.
|
|
1044
|
+
var _openStart = isInHeadingContext ? slice.openStart : Math.max(0, slice.openStart - 1);
|
|
1042
1045
|
return new Slice(normalizedContent.content, _openStart, slice.openEnd);
|
|
1043
1046
|
}
|
|
1044
1047
|
|
|
@@ -1115,7 +1118,9 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1115
1118
|
var firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
|
|
1116
1119
|
var lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
|
|
1117
1120
|
var listContainerNodeTypes = [bulletList, orderedList];
|
|
1118
|
-
var
|
|
1121
|
+
var isSmallFontSizeEnabled = !!fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
1122
|
+
var destinationListNode = isSmallFontSizeEnabled ? (_findParentNodeOfType3 = findParentNodeOfType(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node : undefined;
|
|
1123
|
+
var destinationListFontSizeAttrs = isSmallFontSizeEnabled ? getFirstParagraphBlockMarkAttrs(destinationListNode, fontSize) : false;
|
|
1119
1124
|
|
|
1120
1125
|
// In case user is pasting inline code,
|
|
1121
1126
|
// any backtick ` immediately preceding it should be removed.
|
|
@@ -1135,6 +1140,17 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1135
1140
|
var isSliceContentTaskListNodes = isFirstChildTaskListNode || isLastChildTaskListNode;
|
|
1136
1141
|
var sliceContentBlockquoteListNodes = doesSliceContainBlockquoteListNodes(slice, listContainerNodeTypes);
|
|
1137
1142
|
|
|
1143
|
+
// Compute once and reuse below to avoid traversing the slice twice.
|
|
1144
|
+
var sliceMarkTypes = isSmallFontSizeEnabled ? getTopLevelMarkTypesInSlice(slice) : new Set();
|
|
1145
|
+
var destinationIsEmpty = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && selection.$from.parent.textContent.length === 0;
|
|
1146
|
+
|
|
1147
|
+
// Capture the destination paragraph's non-fontSize block marks (e.g. alignment, indentation)
|
|
1148
|
+
// before the paste so they can be restored if the paste replaces the paragraph entirely
|
|
1149
|
+
// (which happens when small text is pasted with openStart=0).
|
|
1150
|
+
var destinationNonFontSizeBlockMarks = isSmallFontSizeEnabled && selection.$from.parent.type === paragraph && sliceMarkTypes.has(fontSize) ? selection.$from.parent.marks.filter(function (m) {
|
|
1151
|
+
return m.type !== fontSize;
|
|
1152
|
+
}) : [];
|
|
1153
|
+
|
|
1138
1154
|
// We want to use safeInsert to insert invalid content, as it inserts at the closest non schema violating position
|
|
1139
1155
|
// rather than spliting the selection parent node in half (which is what replaceSelection does)
|
|
1140
1156
|
// Exception is paragraph and heading nodes, these should be split, provided their parent supports the pasted content
|
|
@@ -1201,12 +1217,38 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
|
|
|
1201
1217
|
}
|
|
1202
1218
|
}
|
|
1203
1219
|
}
|
|
1204
|
-
|
|
1220
|
+
|
|
1221
|
+
// font size handling for pasting into lists or blockquotes
|
|
1222
|
+
if (isSmallFontSizeEnabled && (isSliceContentListNodes || sliceContentBlockquoteListNodes)) {
|
|
1205
1223
|
var containingList = findParentNodeOfTypeClosestToPos(tr.selection.$from, listContainerNodeTypes);
|
|
1206
1224
|
if (containingList) {
|
|
1207
1225
|
reconcileBlockMarkForContainerAtPos(tr, containingList.pos, fontSize, isSliceContentListNodes ? destinationListFontSizeAttrs : false);
|
|
1208
1226
|
}
|
|
1209
1227
|
}
|
|
1228
|
+
|
|
1229
|
+
// font size handling for pasting into paragraphs (normal text) - preserve source style
|
|
1230
|
+
if (isSmallFontSizeEnabled && destinationIsEmpty && !sliceMarkTypes.has(fontSize) && !destinationListNode && selection.$from.parent.type === paragraph && getBlockMarkAttrs(selection.$from.parent, fontSize)) {
|
|
1231
|
+
reconcileBlockMarkForParagraphAtPos(tr, tr.mapping.map(selection.$from.pos), fontSize, false);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Restore destination block marks (e.g. alignment) that were lost when pasting small text
|
|
1235
|
+
// replaced the paragraph entirely (openStart=0 from container unwrap).
|
|
1236
|
+
if (isSmallFontSizeEnabled && destinationNonFontSizeBlockMarks.length > 0) {
|
|
1237
|
+
var pastedFrom = tr.mapping.map(selection.from, -1);
|
|
1238
|
+
var pastedTo = tr.mapping.map(selection.to, 1);
|
|
1239
|
+
var _iterator2 = _createForOfIteratorHelper(destinationNonFontSizeBlockMarks),
|
|
1240
|
+
_step2;
|
|
1241
|
+
try {
|
|
1242
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1243
|
+
var mark = _step2.value;
|
|
1244
|
+
reconcileBlockMarkInRange(tr, pastedFrom, pastedTo, mark.type, mark.attrs);
|
|
1245
|
+
}
|
|
1246
|
+
} catch (err) {
|
|
1247
|
+
_iterator2.e(err);
|
|
1248
|
+
} finally {
|
|
1249
|
+
_iterator2.f();
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1210
1252
|
tr.setStoredMarks([]);
|
|
1211
1253
|
if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
|
|
1212
1254
|
tr.setSelection(TextSelection.near(tr.selection.$from, 1));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-paste",
|
|
3
|
-
"version": "11.0.
|
|
3
|
+
"version": "11.0.5",
|
|
4
4
|
"description": "Paste plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@atlaskit/editor-plugin-analytics": "^10.0.0",
|
|
34
34
|
"@atlaskit/editor-plugin-annotation": "^10.0.0",
|
|
35
35
|
"@atlaskit/editor-plugin-better-type-history": "^10.0.0",
|
|
36
|
-
"@atlaskit/editor-plugin-card": "^16.
|
|
36
|
+
"@atlaskit/editor-plugin-card": "^16.1.0",
|
|
37
37
|
"@atlaskit/editor-plugin-expand": "^11.0.0",
|
|
38
38
|
"@atlaskit/editor-plugin-feature-flags": "^9.0.0",
|
|
39
39
|
"@atlaskit/editor-plugin-list": "^12.0.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"uuid": "^3.1.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@atlaskit/editor-common": "^114.
|
|
58
|
+
"@atlaskit/editor-common": "^114.6.0",
|
|
59
59
|
"react": "^18.2.0",
|
|
60
60
|
"react-dom": "^18.2.0",
|
|
61
61
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|