@atlaskit/editor-plugin-paste 9.0.16 → 9.1.1

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,22 @@
1
1
  # @atlaskit/editor-plugin-paste
2
2
 
3
+ ## 9.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 9.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`b749ce678d575`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b749ce678d575) -
14
+ Preserve small text formatting across list and task list edits
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+
3
20
  ## 9.0.16
4
21
 
5
22
  ### Patch Changes
@@ -34,6 +34,7 @@ var _v = _interopRequireDefault(require("uuid/v4"));
34
34
  var _analytics = require("@atlaskit/editor-common/analytics");
35
35
  var _card = require("@atlaskit/editor-common/card");
36
36
  var _coreUtils = require("@atlaskit/editor-common/core-utils");
37
+ var _lists = require("@atlaskit/editor-common/lists");
37
38
  var _mark = require("@atlaskit/editor-common/mark");
38
39
  var _nesting = require("@atlaskit/editor-common/nesting");
39
40
  var _selection = require("@atlaskit/editor-common/selection");
@@ -49,7 +50,7 @@ var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equa
49
50
  var _commands = require("../../editor-commands/commands");
50
51
  var _pluginFactory = require("../plugin-factory");
51
52
  var _edgeCases = require("./edge-cases");
52
- var _lists = require("./edge-cases/lists");
53
+ var _lists2 = require("./edge-cases/lists");
53
54
  var _index = require("./index");
54
55
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
55
56
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
@@ -173,7 +174,7 @@ function handlePasteIntoTaskOrDecisionOrPanel(slice, queueCardsFromChangedTr) {
173
174
  var isFirstChildTaskNode = transformedSlice.content.firstChild.type === taskList || transformedSlice.content.firstChild.type === taskItem;
174
175
  var tr = (0, _prosemirrorHistory.closeHistory)(state.tr);
175
176
  if (panelNode && sliceHasTask && ((_slice$content$firstC3 = slice.content.firstChild) === null || _slice$content$firstC3 === void 0 ? void 0 : _slice$content$firstC3.type) === panel && (0, _index.isEmptyNode)(panelNode) && selection.$from.node() === selection.$to.node()) {
176
- return Boolean((0, _lists.insertSliceInsideOfPanelNodeSelected)(panelNode)({
177
+ return Boolean((0, _lists2.insertSliceInsideOfPanelNodeSelected)(panelNode)({
177
178
  tr: tr,
178
179
  slice: slice
179
180
  }));
@@ -912,21 +913,32 @@ function getTopLevelMarkTypesInSlice(slice) {
912
913
  return markTypes;
913
914
  }
914
915
  function handleParagraphBlockMarks(state, slice) {
916
+ var _findParentNodeOfType2;
915
917
  if (slice.content.size === 0) {
916
918
  return slice;
917
919
  }
918
920
  var schema = state.schema,
921
+ selection = state.selection,
919
922
  $from = state.selection.$from;
923
+ var destinationListNode = (_findParentNodeOfType2 = (0, _utils2.findParentNodeOfType)([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType2 === void 0 ? void 0 : _findParentNodeOfType2.node;
924
+ var currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
925
+ var isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.taskItem || $from.parent.type === schema.nodes.taskItem;
926
+ var isInSmallTaskContext = schema.nodes.blockTaskItem && (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === schema.nodes.blockTaskItem;
927
+ var destinationBlockMarkAttrs = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) && schema.marks.fontSize ? destinationListNode ? (0, _lists.getFirstParagraphBlockMarkAttrs)(destinationListNode, schema.marks.fontSize) : isInSmallTaskContext ? (0, _lists.getBlockMarkAttrs)($from.parent, schema.marks.fontSize) || (0, _lists.getFirstParagraphBlockMarkAttrs)(currentNode, schema.marks.fontSize) : false : false;
920
928
 
921
929
  // If no paragraph in the slice contains marks, there's no need for special handling
930
+ // unless we're pasting into a small-text list and need to add the destination block mark.
922
931
  // Note: this doesn't check for marks applied to lower level nodes such as text
923
- if (!sliceHasTopLevelMarks(slice)) {
932
+ if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
924
933
  return slice;
925
934
  }
935
+ var shouldNormalizeFontSizeForTarget = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) && !!schema.marks.fontSize && (!!destinationListNode || isInNormalTaskContext || !!isInSmallTaskContext);
926
936
 
927
- // If pasting a single paragraph into pre-existing content, match destination formatting
937
+ // If pasting a single paragraph into pre-existing content, match destination formatting.
938
+ // For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
939
+ // so pasted content adopts the destination list state.
928
940
  var destinationHasContent = $from.parent.textContent.length > 0;
929
- if (slice.content.childCount === 1 && destinationHasContent) {
941
+ if (slice.content.childCount === 1 && destinationHasContent && !shouldNormalizeFontSizeForTarget) {
930
942
  return slice;
931
943
  }
932
944
 
@@ -949,23 +961,16 @@ function handleParagraphBlockMarks(state, slice) {
949
961
  } finally {
950
962
  _iterator.f();
951
963
  }
952
- if (forbiddenMarkTypes.length === 0) {
953
- // In a slice containing one or more paragraphs at the document level (not wrapped in
954
- // another node), the first paragraph will only have its text content captured and pasted
955
- // since openStart is 1. We decrement the open depth of the slice so it retains any block
956
- // marks applied to it. We only care about the depth at the start of the selection so
957
- // there's no need to change openEnd - the rest of the slice gets pasted correctly.
958
- var openStart = Math.max(0, slice.openStart - 1);
959
- return new _model.Slice(slice.content, openStart, slice.openEnd);
960
- }
961
-
962
- // If the paragraph or heading contains marks forbidden by the parent node
963
- // (e.g. alignment/indentation), drop those marks from the slice
964
- return (0, _utils.mapSlice)(slice, function (node) {
964
+ var fontSizeMarkType = shouldNormalizeFontSizeForTarget ? schema.marks.fontSize : undefined;
965
+ var normalizedContent = (0, _utils.mapSlice)(slice, function (node) {
965
966
  if (node.type === schema.nodes.paragraph) {
966
- return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(function (mark) {
967
+ var paragraphMarks = node.marks.filter(function (mark) {
967
968
  return !forbiddenMarkTypes.includes(mark.type);
968
- }));
969
+ });
970
+ var normalizedMarks = fontSizeMarkType ? paragraphMarks.filter(function (mark) {
971
+ return mark.type !== fontSizeMarkType;
972
+ }) : paragraphMarks;
973
+ return schema.nodes.paragraph.createChecked(undefined, node.content, destinationBlockMarkAttrs && fontSizeMarkType ? normalizedMarks.concat(fontSizeMarkType.create(destinationBlockMarkAttrs)) : normalizedMarks);
969
974
  } else if (node.type === schema.nodes.heading) {
970
975
  // Preserve heading attributes to keep formatting
971
976
  return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(function (mark) {
@@ -974,6 +979,24 @@ function handleParagraphBlockMarks(state, slice) {
974
979
  }
975
980
  return node;
976
981
  });
982
+ if (forbiddenMarkTypes.length === 0 && !shouldNormalizeFontSizeForTarget) {
983
+ // In a slice containing one or more paragraphs at the document level (not wrapped in
984
+ // another node), the first paragraph will only have its text content captured and pasted
985
+ // since openStart is 1. We decrement the open depth of the slice so it retains any block
986
+ // marks applied to it. We only care about the depth at the start of the selection so
987
+ // there's no need to change openEnd - the rest of the slice gets pasted correctly.
988
+ var openStart = Math.max(0, slice.openStart - 1);
989
+ return new _model.Slice(slice.content, openStart, slice.openEnd);
990
+ }
991
+ if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
992
+ var _openStart = Math.max(0, slice.openStart - 1);
993
+ return new _model.Slice(normalizedContent.content, _openStart, slice.openEnd);
994
+ }
995
+
996
+ // If the paragraph or heading contains marks forbidden by the parent node
997
+ // (e.g. alignment/indentation), drop those marks from the slice. For lists under the small
998
+ // text experiment, also normalize fontSize to the destination list state.
999
+ return new _model.Slice(normalizedContent.content, slice.openStart, slice.openEnd);
977
1000
  }
978
1001
 
979
1002
  /**
@@ -1015,7 +1038,7 @@ function flattenNestedListInSlice(slice) {
1015
1038
  }
1016
1039
  function handleRichText(slice, queueCardsFromChangedTr) {
1017
1040
  return function (state, dispatch) {
1018
- var _slice$content, _slice$content2, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
1041
+ var _slice$content, _slice$content2, _findParentNodeOfType3, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
1019
1042
  var _state$schema$nodes4 = state.schema.nodes,
1020
1043
  codeBlock = _state$schema$nodes4.codeBlock,
1021
1044
  heading = _state$schema$nodes4.heading,
@@ -1025,6 +1048,7 @@ function handleRichText(slice, queueCardsFromChangedTr) {
1025
1048
  schema = state.schema;
1026
1049
  var firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
1027
1050
  var lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
1051
+ var destinationListFontSizeAttrs = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _lists.getFirstParagraphBlockMarkAttrs)((_findParentNodeOfType3 = (0, _utils2.findParentNodeOfType)([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, schema.marks.fontSize) : false;
1028
1052
 
1029
1053
  // In case user is pasting inline code,
1030
1054
  // any backtick ` immediately preceding it should be removed.
@@ -1109,6 +1133,12 @@ function handleRichText(slice, queueCardsFromChangedTr) {
1109
1133
  }
1110
1134
  }
1111
1135
  }
1136
+ if ((0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) && isSliceContentListNodes) {
1137
+ var containingList = (0, _utils2.findParentNodeOfTypeClosestToPos)(tr.doc.resolve(tr.mapping.map(selection.from)), [schema.nodes.bulletList, schema.nodes.orderedList]);
1138
+ if (containingList) {
1139
+ (0, _lists.reconcileBlockMarkForContainerAtPos)(tr, containingList.pos, schema.marks.fontSize, destinationListFontSizeAttrs);
1140
+ }
1141
+ }
1112
1142
  tr.setStoredMarks([]);
1113
1143
  if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
1114
1144
  tr.setSelection(_state.TextSelection.near(tr.selection.$from, 1));
@@ -3,6 +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
7
  import { anyMarkActive } from '@atlaskit/editor-common/mark';
7
8
  import { getParentOfTypeCount, getPositionAfterTopParentNodeOfType } from '@atlaskit/editor-common/nesting';
8
9
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
@@ -898,25 +899,36 @@ function getTopLevelMarkTypesInSlice(slice) {
898
899
  return markTypes;
899
900
  }
900
901
  export function handleParagraphBlockMarks(state, slice) {
902
+ var _findParentNodeOfType2;
901
903
  if (slice.content.size === 0) {
902
904
  return slice;
903
905
  }
904
906
  const {
905
907
  schema,
908
+ selection,
906
909
  selection: {
907
910
  $from
908
911
  }
909
912
  } = state;
913
+ const destinationListNode = (_findParentNodeOfType2 = findParentNodeOfType([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType2 === void 0 ? void 0 : _findParentNodeOfType2.node;
914
+ const currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
915
+ const isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.taskItem || $from.parent.type === schema.nodes.taskItem;
916
+ const isInSmallTaskContext = schema.nodes.blockTaskItem && (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === schema.nodes.blockTaskItem;
917
+ const destinationBlockMarkAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) && schema.marks.fontSize ? destinationListNode ? getFirstParagraphBlockMarkAttrs(destinationListNode, schema.marks.fontSize) : isInSmallTaskContext ? getBlockMarkAttrs($from.parent, schema.marks.fontSize) || getFirstParagraphBlockMarkAttrs(currentNode, schema.marks.fontSize) : false : false;
910
918
 
911
919
  // If no paragraph in the slice contains marks, there's no need for special handling
920
+ // unless we're pasting into a small-text list and need to add the destination block mark.
912
921
  // Note: this doesn't check for marks applied to lower level nodes such as text
913
- if (!sliceHasTopLevelMarks(slice)) {
922
+ if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
914
923
  return slice;
915
924
  }
925
+ const shouldNormalizeFontSizeForTarget = expValEquals('platform_editor_small_font_size', 'isEnabled', true) && !!schema.marks.fontSize && (!!destinationListNode || isInNormalTaskContext || !!isInSmallTaskContext);
916
926
 
917
- // If pasting a single paragraph into pre-existing content, match destination formatting
927
+ // If pasting a single paragraph into pre-existing content, match destination formatting.
928
+ // For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
929
+ // so pasted content adopts the destination list state.
918
930
  const destinationHasContent = $from.parent.textContent.length > 0;
919
- if (slice.content.childCount === 1 && destinationHasContent) {
931
+ if (slice.content.childCount === 1 && destinationHasContent && !shouldNormalizeFontSizeForTarget) {
920
932
  return slice;
921
933
  }
922
934
 
@@ -930,7 +942,19 @@ export function handleParagraphBlockMarks(state, slice) {
930
942
  forbiddenMarkTypes.push(markType);
931
943
  }
932
944
  }
933
- if (forbiddenMarkTypes.length === 0) {
945
+ const fontSizeMarkType = shouldNormalizeFontSizeForTarget ? schema.marks.fontSize : undefined;
946
+ const normalizedContent = mapSlice(slice, node => {
947
+ if (node.type === schema.nodes.paragraph) {
948
+ const paragraphMarks = node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type));
949
+ const normalizedMarks = fontSizeMarkType ? paragraphMarks.filter(mark => mark.type !== fontSizeMarkType) : paragraphMarks;
950
+ return schema.nodes.paragraph.createChecked(undefined, node.content, destinationBlockMarkAttrs && fontSizeMarkType ? normalizedMarks.concat(fontSizeMarkType.create(destinationBlockMarkAttrs)) : normalizedMarks);
951
+ } else if (node.type === schema.nodes.heading) {
952
+ // Preserve heading attributes to keep formatting
953
+ return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type)));
954
+ }
955
+ return node;
956
+ });
957
+ if (forbiddenMarkTypes.length === 0 && !shouldNormalizeFontSizeForTarget) {
934
958
  // In a slice containing one or more paragraphs at the document level (not wrapped in
935
959
  // another node), the first paragraph will only have its text content captured and pasted
936
960
  // since openStart is 1. We decrement the open depth of the slice so it retains any block
@@ -939,18 +963,15 @@ export function handleParagraphBlockMarks(state, slice) {
939
963
  const openStart = Math.max(0, slice.openStart - 1);
940
964
  return new Slice(slice.content, openStart, slice.openEnd);
941
965
  }
966
+ if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
967
+ const openStart = Math.max(0, slice.openStart - 1);
968
+ return new Slice(normalizedContent.content, openStart, slice.openEnd);
969
+ }
942
970
 
943
971
  // If the paragraph or heading contains marks forbidden by the parent node
944
- // (e.g. alignment/indentation), drop those marks from the slice
945
- return mapSlice(slice, node => {
946
- if (node.type === schema.nodes.paragraph) {
947
- return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type)));
948
- } else if (node.type === schema.nodes.heading) {
949
- // Preserve heading attributes to keep formatting
950
- return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type)));
951
- }
952
- return node;
953
- });
972
+ // (e.g. alignment/indentation), drop those marks from the slice. For lists under the small
973
+ // text experiment, also normalize fontSize to the destination list state.
974
+ return new Slice(normalizedContent.content, slice.openStart, slice.openEnd);
954
975
  }
955
976
 
956
977
  /**
@@ -992,7 +1013,7 @@ export function flattenNestedListInSlice(slice) {
992
1013
  }
993
1014
  export function handleRichText(slice, queueCardsFromChangedTr) {
994
1015
  return (state, dispatch) => {
995
- var _slice$content, _slice$content2, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
1016
+ var _slice$content, _slice$content2, _findParentNodeOfType3, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
996
1017
  const {
997
1018
  codeBlock,
998
1019
  heading,
@@ -1005,6 +1026,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
1005
1026
  } = state;
1006
1027
  const firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
1007
1028
  const lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
1029
+ const destinationListFontSizeAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getFirstParagraphBlockMarkAttrs((_findParentNodeOfType3 = findParentNodeOfType([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, schema.marks.fontSize) : false;
1008
1030
 
1009
1031
  // In case user is pasting inline code,
1010
1032
  // any backtick ` immediately preceding it should be removed.
@@ -1089,6 +1111,12 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
1089
1111
  }
1090
1112
  }
1091
1113
  }
1114
+ if (expValEquals('platform_editor_small_font_size', 'isEnabled', true) && isSliceContentListNodes) {
1115
+ const containingList = findParentNodeOfTypeClosestToPos(tr.doc.resolve(tr.mapping.map(selection.from)), [schema.nodes.bulletList, schema.nodes.orderedList]);
1116
+ if (containingList) {
1117
+ reconcileBlockMarkForContainerAtPos(tr, containingList.pos, schema.marks.fontSize, destinationListFontSizeAttrs);
1118
+ }
1119
+ }
1092
1120
  tr.setStoredMarks([]);
1093
1121
  if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
1094
1122
  tr.setSelection(TextSelection.near(tr.selection.$from, 1));
@@ -11,6 +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
15
  import { anyMarkActive } from '@atlaskit/editor-common/mark';
15
16
  import { getParentOfTypeCount, getPositionAfterTopParentNodeOfType } from '@atlaskit/editor-common/nesting';
16
17
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
@@ -885,21 +886,32 @@ function getTopLevelMarkTypesInSlice(slice) {
885
886
  return markTypes;
886
887
  }
887
888
  export function handleParagraphBlockMarks(state, slice) {
889
+ var _findParentNodeOfType2;
888
890
  if (slice.content.size === 0) {
889
891
  return slice;
890
892
  }
891
893
  var schema = state.schema,
894
+ selection = state.selection,
892
895
  $from = state.selection.$from;
896
+ var destinationListNode = (_findParentNodeOfType2 = findParentNodeOfType([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType2 === void 0 ? void 0 : _findParentNodeOfType2.node;
897
+ var currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
898
+ var isInNormalTaskContext = (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.taskItem || $from.parent.type === schema.nodes.taskItem;
899
+ var isInSmallTaskContext = schema.nodes.blockTaskItem && (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.blockTaskItem || schema.nodes.blockTaskItem && $from.parent.type === schema.nodes.paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === schema.nodes.blockTaskItem;
900
+ var destinationBlockMarkAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) && schema.marks.fontSize ? destinationListNode ? getFirstParagraphBlockMarkAttrs(destinationListNode, schema.marks.fontSize) : isInSmallTaskContext ? getBlockMarkAttrs($from.parent, schema.marks.fontSize) || getFirstParagraphBlockMarkAttrs(currentNode, schema.marks.fontSize) : false : false;
893
901
 
894
902
  // If no paragraph in the slice contains marks, there's no need for special handling
903
+ // unless we're pasting into a small-text list and need to add the destination block mark.
895
904
  // Note: this doesn't check for marks applied to lower level nodes such as text
896
- if (!sliceHasTopLevelMarks(slice)) {
905
+ if (!sliceHasTopLevelMarks(slice) && !destinationBlockMarkAttrs) {
897
906
  return slice;
898
907
  }
908
+ var shouldNormalizeFontSizeForTarget = expValEquals('platform_editor_small_font_size', 'isEnabled', true) && !!schema.marks.fontSize && (!!destinationListNode || isInNormalTaskContext || !!isInSmallTaskContext);
899
909
 
900
- // If pasting a single paragraph into pre-existing content, match destination formatting
910
+ // If pasting a single paragraph into pre-existing content, match destination formatting.
911
+ // For bullet/ordered lists under small-text, we still need to normalize the paragraph block mark
912
+ // so pasted content adopts the destination list state.
901
913
  var destinationHasContent = $from.parent.textContent.length > 0;
902
- if (slice.content.childCount === 1 && destinationHasContent) {
914
+ if (slice.content.childCount === 1 && destinationHasContent && !shouldNormalizeFontSizeForTarget) {
903
915
  return slice;
904
916
  }
905
917
 
@@ -922,23 +934,16 @@ export function handleParagraphBlockMarks(state, slice) {
922
934
  } finally {
923
935
  _iterator.f();
924
936
  }
925
- if (forbiddenMarkTypes.length === 0) {
926
- // In a slice containing one or more paragraphs at the document level (not wrapped in
927
- // another node), the first paragraph will only have its text content captured and pasted
928
- // since openStart is 1. We decrement the open depth of the slice so it retains any block
929
- // marks applied to it. We only care about the depth at the start of the selection so
930
- // there's no need to change openEnd - the rest of the slice gets pasted correctly.
931
- var openStart = Math.max(0, slice.openStart - 1);
932
- return new Slice(slice.content, openStart, slice.openEnd);
933
- }
934
-
935
- // If the paragraph or heading contains marks forbidden by the parent node
936
- // (e.g. alignment/indentation), drop those marks from the slice
937
- return mapSlice(slice, function (node) {
937
+ var fontSizeMarkType = shouldNormalizeFontSizeForTarget ? schema.marks.fontSize : undefined;
938
+ var normalizedContent = mapSlice(slice, function (node) {
938
939
  if (node.type === schema.nodes.paragraph) {
939
- return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(function (mark) {
940
+ var paragraphMarks = node.marks.filter(function (mark) {
940
941
  return !forbiddenMarkTypes.includes(mark.type);
941
- }));
942
+ });
943
+ var normalizedMarks = fontSizeMarkType ? paragraphMarks.filter(function (mark) {
944
+ return mark.type !== fontSizeMarkType;
945
+ }) : paragraphMarks;
946
+ return schema.nodes.paragraph.createChecked(undefined, node.content, destinationBlockMarkAttrs && fontSizeMarkType ? normalizedMarks.concat(fontSizeMarkType.create(destinationBlockMarkAttrs)) : normalizedMarks);
942
947
  } else if (node.type === schema.nodes.heading) {
943
948
  // Preserve heading attributes to keep formatting
944
949
  return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(function (mark) {
@@ -947,6 +952,24 @@ export function handleParagraphBlockMarks(state, slice) {
947
952
  }
948
953
  return node;
949
954
  });
955
+ if (forbiddenMarkTypes.length === 0 && !shouldNormalizeFontSizeForTarget) {
956
+ // In a slice containing one or more paragraphs at the document level (not wrapped in
957
+ // another node), the first paragraph will only have its text content captured and pasted
958
+ // since openStart is 1. We decrement the open depth of the slice so it retains any block
959
+ // marks applied to it. We only care about the depth at the start of the selection so
960
+ // there's no need to change openEnd - the rest of the slice gets pasted correctly.
961
+ var openStart = Math.max(0, slice.openStart - 1);
962
+ return new Slice(slice.content, openStart, slice.openEnd);
963
+ }
964
+ if (forbiddenMarkTypes.length === 0 && shouldNormalizeFontSizeForTarget) {
965
+ var _openStart = Math.max(0, slice.openStart - 1);
966
+ return new Slice(normalizedContent.content, _openStart, slice.openEnd);
967
+ }
968
+
969
+ // If the paragraph or heading contains marks forbidden by the parent node
970
+ // (e.g. alignment/indentation), drop those marks from the slice. For lists under the small
971
+ // text experiment, also normalize fontSize to the destination list state.
972
+ return new Slice(normalizedContent.content, slice.openStart, slice.openEnd);
950
973
  }
951
974
 
952
975
  /**
@@ -988,7 +1011,7 @@ export function flattenNestedListInSlice(slice) {
988
1011
  }
989
1012
  export function handleRichText(slice, queueCardsFromChangedTr) {
990
1013
  return function (state, dispatch) {
991
- var _slice$content, _slice$content2, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
1014
+ var _slice$content, _slice$content2, _findParentNodeOfType3, _firstChildOfSlice$ty, _lastChildOfSlice$typ, _panelParentOverCurre;
992
1015
  var _state$schema$nodes4 = state.schema.nodes,
993
1016
  codeBlock = _state$schema$nodes4.codeBlock,
994
1017
  heading = _state$schema$nodes4.heading,
@@ -998,6 +1021,7 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
998
1021
  schema = state.schema;
999
1022
  var firstChildOfSlice = (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.firstChild;
1000
1023
  var lastChildOfSlice = (_slice$content2 = slice.content) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.lastChild;
1024
+ var destinationListFontSizeAttrs = expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getFirstParagraphBlockMarkAttrs((_findParentNodeOfType3 = findParentNodeOfType([schema.nodes.bulletList, schema.nodes.orderedList])(selection)) === null || _findParentNodeOfType3 === void 0 ? void 0 : _findParentNodeOfType3.node, schema.marks.fontSize) : false;
1001
1025
 
1002
1026
  // In case user is pasting inline code,
1003
1027
  // any backtick ` immediately preceding it should be removed.
@@ -1082,6 +1106,12 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
1082
1106
  }
1083
1107
  }
1084
1108
  }
1109
+ if (expValEquals('platform_editor_small_font_size', 'isEnabled', true) && isSliceContentListNodes) {
1110
+ var containingList = findParentNodeOfTypeClosestToPos(tr.doc.resolve(tr.mapping.map(selection.from)), [schema.nodes.bulletList, schema.nodes.orderedList]);
1111
+ if (containingList) {
1112
+ reconcileBlockMarkForContainerAtPos(tr, containingList.pos, schema.marks.fontSize, destinationListFontSizeAttrs);
1113
+ }
1114
+ }
1085
1115
  tr.setStoredMarks([]);
1086
1116
  if (tr.selection.empty && tr.selection.$from.parent.type === codeBlock) {
1087
1117
  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": "9.0.16",
3
+ "version": "9.1.1",
4
4
  "description": "Paste plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,7 +36,7 @@
36
36
  "@atlaskit/editor-plugin-card": "^13.1.0",
37
37
  "@atlaskit/editor-plugin-expand": "^9.1.0",
38
38
  "@atlaskit/editor-plugin-feature-flags": "^7.0.0",
39
- "@atlaskit/editor-plugin-list": "^10.1.0",
39
+ "@atlaskit/editor-plugin-list": "^10.2.0",
40
40
  "@atlaskit/editor-plugin-media": "^10.1.0",
41
41
  "@atlaskit/editor-plugin-mentions": "^10.0.0",
42
42
  "@atlaskit/editor-prosemirror": "^7.3.0",
@@ -48,15 +48,15 @@
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": "^48.1.0",
52
- "@atlaskit/tokens": "^11.3.0",
51
+ "@atlaskit/tmp-editor-statsig": "^50.0.0",
52
+ "@atlaskit/tokens": "^11.4.0",
53
53
  "@babel/runtime": "^7.0.0",
54
54
  "lodash": "^4.17.21",
55
55
  "react-intl-next": "npm:react-intl@^5.18.1",
56
56
  "uuid": "^3.1.0"
57
57
  },
58
58
  "peerDependencies": {
59
- "@atlaskit/editor-common": "^112.11.0",
59
+ "@atlaskit/editor-common": "^112.13.0",
60
60
  "react": "^18.2.0",
61
61
  "react-dom": "^18.2.0"
62
62
  },