@atlaskit/editor-plugin-paste 11.0.4 → 11.0.6

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,19 @@
1
1
  # @atlaskit/editor-plugin-paste
2
2
 
3
+ ## 11.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 11.0.5
10
+
11
+ ### Patch Changes
12
+
13
+ - [`583f16df338b0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/583f16df338b0) -
14
+ Normalise small text fontSize mark on paste: strip fontSize when pasting into headings, and
15
+ preserve source style when pasting normal text into small-text paragraphs
16
+
3
17
  ## 11.0.4
4
18
 
5
19
  ### 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) && !!fontSize;
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
- var _openStart = Math.max(0, slice.openStart - 1);
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 destinationListFontSizeAttrs = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _lists.getFirstParagraphBlockMarkAttrs)((_findParentNodeOfType3 = (0, _utils2.findParentNodeOfType)(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, fontSize) : false;
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
- if ((isSliceContentListNodes || sliceContentBlockquoteListNodes) && fontSize && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) {
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) && !!fontSize;
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
- const openStart = Math.max(0, slice.openStart - 1);
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 destinationListFontSizeAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getFirstParagraphBlockMarkAttrs((_findParentNodeOfType3 = findParentNodeOfType(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, fontSize) : false;
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
- if ((isSliceContentListNodes || sliceContentBlockquoteListNodes) && fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
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) && !!fontSize;
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
- var _openStart = Math.max(0, slice.openStart - 1);
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 destinationListFontSizeAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getFirstParagraphBlockMarkAttrs((_findParentNodeOfType3 = findParentNodeOfType(listContainerNodeTypes)(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, fontSize) : false;
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
- if ((isSliceContentListNodes || sliceContentBlockquoteListNodes) && fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
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.4",
3
+ "version": "11.0.6",
4
4
  "description": "Paste plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -31,14 +31,14 @@
31
31
  "@atlaskit/code": "^17.4.0",
32
32
  "@atlaskit/editor-markdown-transformer": "^5.20.0",
33
33
  "@atlaskit/editor-plugin-analytics": "^10.0.0",
34
- "@atlaskit/editor-plugin-annotation": "^10.0.0",
34
+ "@atlaskit/editor-plugin-annotation": "^10.1.0",
35
35
  "@atlaskit/editor-plugin-better-type-history": "^10.0.0",
36
- "@atlaskit/editor-plugin-card": "^16.0.0",
36
+ "@atlaskit/editor-plugin-card": "^16.2.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",
40
40
  "@atlaskit/editor-plugin-media": "^12.1.0",
41
- "@atlaskit/editor-plugin-mentions": "^12.0.0",
41
+ "@atlaskit/editor-plugin-mentions": "^12.1.0",
42
42
  "@atlaskit/editor-prosemirror": "^7.3.0",
43
43
  "@atlaskit/editor-tables": "^2.9.0",
44
44
  "@atlaskit/flag": "^17.9.0",
@@ -48,14 +48,14 @@
48
48
  "@atlaskit/media-common": "^13.0.0",
49
49
  "@atlaskit/platform-feature-flags": "^1.1.0",
50
50
  "@atlaskit/prosemirror-history": "^0.2.0",
51
- "@atlaskit/tmp-editor-statsig": "^64.0.0",
51
+ "@atlaskit/tmp-editor-statsig": "^65.0.0",
52
52
  "@atlaskit/tokens": "^13.0.0",
53
53
  "@babel/runtime": "^7.0.0",
54
54
  "lodash": "^4.17.21",
55
55
  "uuid": "^3.1.0"
56
56
  },
57
57
  "peerDependencies": {
58
- "@atlaskit/editor-common": "^114.5.0",
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"