@atlaskit/editor-plugin-tasks-and-decisions 11.3.6 → 11.4.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @atlaskit/editor-plugin-tasks-and-decisions
2
2
 
3
+ ## 11.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`b749ce678d575`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b749ce678d575) -
8
+ Preserve small text formatting across list and task list edits
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies
13
+
3
14
  ## 11.3.6
4
15
 
5
16
  ### Patch Changes
@@ -5,9 +5,13 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.wrapSelectionInTaskList = exports.liftSelection = exports.joinAtCut = void 0;
7
7
  var _commands = require("@atlaskit/editor-common/commands");
8
+ var _lists = require("@atlaskit/editor-common/lists");
9
+ var _transforms = require("@atlaskit/editor-common/transforms");
8
10
  var _transform = require("@atlaskit/editor-prosemirror/transform");
11
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
9
12
  var _helpers = require("./helpers");
10
13
  var _utils = require("./utils");
14
+ var _paste = require("./utils/paste");
11
15
  var liftSelection = exports.liftSelection = function liftSelection(state, dispatch) {
12
16
  var normalizedSelection = (0, _utils.normalizeTaskItemsSelection)(state.selection);
13
17
  var $from = normalizedSelection.$from,
@@ -94,6 +98,7 @@ var joinAtCut = exports.joinAtCut = function joinAtCut($pos) {
94
98
  return function (state, dispatch) {
95
99
  var $cut = (0, _commands.findCutBefore)($pos);
96
100
  var blockTaskItem = state.schema.nodes.blockTaskItem;
101
+ var fontSize = state.schema.marks.fontSize;
97
102
  if (!$cut) {
98
103
  return false;
99
104
  }
@@ -143,6 +148,21 @@ var joinAtCut = exports.joinAtCut = function joinAtCut($pos) {
143
148
  // see https://prosemirror.net/docs/ref/#transform.ReplaceStep.constructor
144
149
  // see https://prosemirror.net/docs/ref/#transform.ReplaceAroundStep.constructor
145
150
  var tr = state.tr.step(new _transform.ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, true));
151
+ if (fontSize && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) {
152
+ var targetTaskListSmallTextAttrs = (0, _lists.getFirstParagraphBlockMarkAttrs)($cut.nodeBefore, fontSize);
153
+ var followingListPos = $cut.pos + $cut.nodeAfter.nodeSize;
154
+ var followingListNode = state.doc.resolve(followingListPos).nodeAfter;
155
+ if (followingListNode && (0, _transforms.isTaskList)(followingListNode.type)) {
156
+ var normalizedListNode = (0, _paste.normalizeNodeForTaskTextSize)(followingListNode, state.schema, targetTaskListSmallTextAttrs)[0];
157
+ if (normalizedListNode && normalizedListNode !== followingListNode) {
158
+ var mappedFollowingListPos = tr.mapping.map(followingListPos);
159
+ var currentFollowingListNode = tr.doc.nodeAt(mappedFollowingListPos);
160
+ if (currentFollowingListNode) {
161
+ tr = tr.replaceWith(mappedFollowingListPos, mappedFollowingListPos + currentFollowingListNode.nodeSize, normalizedListNode);
162
+ }
163
+ }
164
+ }
165
+ }
146
166
  if (dispatch) {
147
167
  dispatch(tr);
148
168
  }
@@ -12,6 +12,7 @@ var _steps = require("@atlaskit/adf-schema/steps");
12
12
  var _analytics = require("@atlaskit/editor-common/analytics");
13
13
  var _editorAnalytics = require("@atlaskit/editor-common/editor-analytics");
14
14
  var _keymaps = require("@atlaskit/editor-common/keymaps");
15
+ var _lists = require("@atlaskit/editor-common/lists");
15
16
  var _selection = require("@atlaskit/editor-common/selection");
16
17
  var _utils = require("@atlaskit/editor-common/utils");
17
18
  var _commands = require("@atlaskit/editor-prosemirror/commands");
@@ -497,14 +498,40 @@ var splitListItemWith = function splitListItemWith(tr, content, $from, setSelect
497
498
  var creatParentListItemFragement = function creatParentListItemFragement(state) {
498
499
  return state.schema.nodes.listItem.create({}, state.schema.nodes.paragraph.create());
499
500
  };
500
- var splitListItem = function splitListItem(state, dispatch) {
501
- var tr = state.tr,
502
- $from = state.selection.$from;
501
+ var getCurrentBlockTaskFontSizeAttrs = function getCurrentBlockTaskFontSizeAttrs(state, $from) {
502
+ if (!(0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) {
503
+ return false;
504
+ }
505
+ var fontSize = state.schema.marks.fontSize;
506
+ if (!fontSize) {
507
+ return false;
508
+ }
509
+ var result = (0, _utils3.findBlockTaskItem)($from);
510
+ if (!result) {
511
+ return false;
512
+ }
513
+ return result.hasParagraph ? (0, _lists.getBlockMarkAttrs)($from.parent, fontSize) : (0, _lists.getFirstParagraphBlockMarkAttrs)(result.blockTaskItemNode, fontSize);
514
+ };
515
+ var createTaskItemForCurrentTextSize = function createTaskItemForCurrentTextSize(state, attrs, fontSizeAttrs) {
503
516
  var _state$schema$nodes5 = state.schema.nodes,
504
- listItem = _state$schema$nodes5.listItem,
505
- blockTaskItem = _state$schema$nodes5.blockTaskItem,
506
517
  taskItem = _state$schema$nodes5.taskItem,
518
+ blockTaskItem = _state$schema$nodes5.blockTaskItem,
507
519
  paragraph = _state$schema$nodes5.paragraph;
520
+ var fontSize = state.schema.marks.fontSize;
521
+ if (fontSizeAttrs && blockTaskItem && paragraph && fontSize) {
522
+ return blockTaskItem.createChecked(attrs, paragraph.createChecked({}, undefined, [fontSize.create(fontSizeAttrs)]));
523
+ }
524
+ return taskItem.createAndFill(attrs);
525
+ };
526
+ var splitListItem = function splitListItem(state, dispatch) {
527
+ var tr = state.tr,
528
+ $from = state.selection.$from;
529
+ var _state$schema$nodes6 = state.schema.nodes,
530
+ listItem = _state$schema$nodes6.listItem,
531
+ blockTaskItem = _state$schema$nodes6.blockTaskItem,
532
+ taskItem = _state$schema$nodes6.taskItem,
533
+ paragraph = _state$schema$nodes6.paragraph;
534
+ var currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
508
535
  if (actionDecisionFollowsOrNothing($from)) {
509
536
  if (dispatch) {
510
537
  // If previous node is a blockTaskItem we just want to delete the existing node and replace it with a paragraph
@@ -523,7 +550,11 @@ var splitListItem = function splitListItem(state, dispatch) {
523
550
  dispatch(splitListItemWith(tr, creatParentListItemFragement(state), $from, true));
524
551
  return true;
525
552
  }
526
- dispatch(splitListItemWith(tr, paragraph.createChecked(), $from, true));
553
+ var splitTr = splitListItemWith(tr, paragraph.createChecked(), $from, true);
554
+ if (currentBlockTaskFontSizeAttrs) {
555
+ (0, _lists.reconcileBlockMarkForParagraphAtPos)(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
556
+ }
557
+ dispatch(splitTr);
527
558
  }
528
559
  return true;
529
560
  }
@@ -591,11 +622,12 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
591
622
  // If the selection is a gap cursor at the end of the blockTaskItem,
592
623
  // we should insert a new taskItem.
593
624
  if ((!$from.parent.isTextblock || (0, _helpers.isInLastTextblockOfBlockTaskItem)(state)) && $from.parentOffset === $from.parent.nodeSize - 2) {
594
- var _newTaskItem = taskItem.createAndFill({
625
+ var _currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
626
+ var newTaskNode = createTaskItemForCurrentTextSize(state, {
595
627
  localId: itemLocalId
596
- });
597
- if (_newTaskItem) {
598
- tr.insert(_blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize, _newTaskItem);
628
+ }, _currentBlockTaskFontSizeAttrs);
629
+ if (newTaskNode) {
630
+ tr.insert(_blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize, newTaskNode);
599
631
 
600
632
  // Move the cursor to the end of the newly inserted blockTaskItem
601
633
  tr.setSelection(_state2.TextSelection.create(tr.doc, _blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize + 1));
@@ -604,12 +636,17 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
604
636
  }
605
637
 
606
638
  // Split near the depth of the current selection
607
- return tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
639
+ var splitTr = tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
608
640
  type: blockTaskItem,
609
641
  attrs: {
610
642
  localId: itemLocalId
611
643
  }
612
644
  }]);
645
+ var currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
646
+ if (currentBlockTaskFontSizeAttrs) {
647
+ (0, _lists.reconcileBlockMarkForParagraphAtPos)(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
648
+ }
649
+ return splitTr;
613
650
  }
614
651
  return tr.split($from.pos, 1, [{
615
652
  type: nodeType,
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
- exports.tempTransformSliceToRemoveBlockTaskItem = void 0;
7
+ exports.tempTransformSliceToRemoveBlockTaskItem = exports.normalizeNodeForTaskTextSize = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
7
9
  var _adfSchema = require("@atlaskit/adf-schema");
10
+ var _lists = require("@atlaskit/editor-common/lists");
11
+ var _transforms = require("@atlaskit/editor-common/transforms");
8
12
  var _model = require("@atlaskit/editor-prosemirror/model");
13
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
9
14
  /**
10
15
  * Transforms a paste slice to handle blockTaskItem nodes when pasting into task items.
11
16
  *
@@ -25,54 +30,167 @@ var _model = require("@atlaskit/editor-prosemirror/model");
25
30
  *
26
31
  * @see {@link https://hello.atlassian.net/wiki/spaces/EDITOR/pages/5626622054/Block+elements+in+task+-+Decision+log#Can-users-create-block-task-items%3F} for reasoning
27
32
  */
28
- var tempTransformSliceToRemoveBlockTaskItem = exports.tempTransformSliceToRemoveBlockTaskItem = function tempTransformSliceToRemoveBlockTaskItem(slice, view) {
29
- var schema = view.state.schema;
33
+ var getTaskPasteContext = function getTaskPasteContext(view) {
34
+ var _schema$marks;
35
+ var _view$state = view.state,
36
+ schema = _view$state.schema,
37
+ selection = _view$state.selection;
30
38
  var _schema$nodes = schema.nodes,
31
39
  taskItem = _schema$nodes.taskItem,
32
40
  blockTaskItem = _schema$nodes.blockTaskItem,
33
41
  paragraph = _schema$nodes.paragraph;
34
-
35
- // Check if we're pasting into a taskItem
36
- var $from = view.state.selection.$from;
37
- var isInTaskItem = $from.node().type === taskItem;
38
- if (isInTaskItem && blockTaskItem) {
39
- // Transform the slice to replace blockTaskItems with taskItems
42
+ var fontSize = (_schema$marks = schema.marks) === null || _schema$marks === void 0 ? void 0 : _schema$marks.fontSize;
43
+ var $from = selection.$from;
44
+ var currentParent = $from.parent;
45
+ var currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
46
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === taskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem) {
47
+ return {
48
+ isInTaskContext: true,
49
+ smallTextAttrs: false
50
+ };
51
+ }
52
+ if (!blockTaskItem) {
53
+ return {
54
+ isInTaskContext: false,
55
+ smallTextAttrs: false
56
+ };
57
+ }
58
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === blockTaskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem) {
59
+ return {
60
+ isInTaskContext: true,
61
+ smallTextAttrs: fontSize ? (0, _lists.getFirstParagraphBlockMarkAttrs)(currentParent !== null && currentParent !== void 0 ? currentParent : currentNode, fontSize) : false
62
+ };
63
+ }
64
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem) {
65
+ return {
66
+ isInTaskContext: true,
67
+ smallTextAttrs: fontSize ? (0, _lists.getBlockMarkAttrs)(currentParent, fontSize) : false
68
+ };
69
+ }
70
+ return {
71
+ isInTaskContext: false,
72
+ smallTextAttrs: false
73
+ };
74
+ };
75
+ var convertTaskItemToBlockTaskItem = function convertTaskItemToBlockTaskItem(node, schema, smallTextAttrs) {
76
+ var _schema$nodes2 = schema.nodes,
77
+ blockTaskItem = _schema$nodes2.blockTaskItem,
78
+ paragraph = _schema$nodes2.paragraph;
79
+ var fontSize = schema.marks.fontSize;
80
+ return blockTaskItem.create(node.attrs, paragraph.createChecked({}, node.content, [fontSize.create(smallTextAttrs)]));
81
+ };
82
+ var addSmallTextToBlockTaskItem = function addSmallTextToBlockTaskItem(node, schema, smallTextAttrs) {
83
+ var paragraph = schema.nodes.paragraph;
84
+ var fontSize = schema.marks.fontSize;
85
+ var newContent = [];
86
+ node.content.forEach(function (child) {
87
+ if (child.type === paragraph) {
88
+ newContent.push(paragraph.createChecked(child.attrs, child.content, child.marks.filter(function (mark) {
89
+ return mark.type !== fontSize;
90
+ }).concat(fontSize.create(smallTextAttrs))));
91
+ } else {
92
+ newContent.push(child);
93
+ }
94
+ });
95
+ return node.type.create(node.attrs, newContent);
96
+ };
97
+ var normalizeBlockTaskItemToTaskItems = function normalizeBlockTaskItemToTaskItems(node, schema) {
98
+ var _schema$nodes3 = schema.nodes,
99
+ taskItem = _schema$nodes3.taskItem,
100
+ blockTaskItem = _schema$nodes3.blockTaskItem,
101
+ paragraph = _schema$nodes3.paragraph;
102
+ if (!blockTaskItem || node.type !== blockTaskItem) {
103
+ return [node];
104
+ }
105
+ var allChildrenAreParagraphs = true;
106
+ node.content.forEach(function (child) {
107
+ if (child.type !== paragraph) {
108
+ allChildrenAreParagraphs = false;
109
+ }
110
+ });
111
+ if (allChildrenAreParagraphs && node.childCount > 0) {
40
112
  var transformedContent = [];
41
- slice.content.forEach(function (node) {
42
- if (node.type === blockTaskItem) {
43
- // Check if blockTaskItem only contains paragraphs
44
- var allChildrenAreParagraphs = true;
45
- node.content.forEach(function (child) {
46
- if (child.type !== paragraph) {
47
- allChildrenAreParagraphs = false;
48
- }
49
- });
50
- if (allChildrenAreParagraphs && node.childCount > 0) {
51
- // Convert each paragraph to a taskItem
52
- node.content.forEach(function (paragraphNode) {
53
- var newTaskItem = taskItem.create({
54
- localId: _adfSchema.uuid.generate(),
55
- state: node.attrs.state || 'TODO'
56
- }, paragraphNode.content);
57
- transformedContent.push(newTaskItem);
58
- });
59
- } else {
60
- // Keep the blockTaskItem as is if it doesn't only contain paragraphs
61
- transformedContent.push(node);
62
- }
63
- } else {
64
- // Keep other nodes as is
65
- transformedContent.push(node);
66
- }
113
+ node.content.forEach(function (paragraphNode) {
114
+ transformedContent.push(taskItem.create({
115
+ localId: _adfSchema.uuid.generate(),
116
+ state: node.attrs.state || 'TODO'
117
+ }, paragraphNode.content));
67
118
  });
68
-
69
- // Create new slice with transformed content
70
- if (transformedContent.length !== slice.content.childCount || transformedContent.some(function (node, idx) {
71
- return node !== slice.content.child(idx);
72
- })) {
73
- var newFragment = _model.Fragment.from(transformedContent);
74
- return new _model.Slice(newFragment, slice.openStart, slice.openEnd);
75
- }
119
+ return transformedContent;
120
+ }
121
+ return [node];
122
+ };
123
+ var transformSliceContent = function transformSliceContent(slice, transformNode) {
124
+ var transformedContent = [];
125
+ slice.content.forEach(function (node) {
126
+ transformedContent.push.apply(transformedContent, (0, _toConsumableArray2.default)(transformNode(node)));
127
+ });
128
+ if (transformedContent.length !== slice.content.childCount || transformedContent.some(function (node, idx) {
129
+ return node !== slice.content.child(idx);
130
+ })) {
131
+ var newFragment = _model.Fragment.from(transformedContent);
132
+ return new _model.Slice(newFragment, slice.openStart, slice.openEnd);
76
133
  }
77
134
  return slice;
135
+ };
136
+ var transformSliceToRemoveBlockTaskItemLegacy = function transformSliceToRemoveBlockTaskItemLegacy(slice, view) {
137
+ var schema = view.state.schema;
138
+ var _schema$nodes4 = schema.nodes,
139
+ taskItem = _schema$nodes4.taskItem,
140
+ blockTaskItem = _schema$nodes4.blockTaskItem;
141
+ var isInTaskItem = view.state.selection.$from.node().type === taskItem;
142
+ if (!isInTaskItem || !blockTaskItem) {
143
+ return slice;
144
+ }
145
+ return transformSliceContent(slice, function (node) {
146
+ return normalizeBlockTaskItemToTaskItems(node, schema);
147
+ });
148
+ };
149
+ var _normalizeNodeForTaskTextSize = exports.normalizeNodeForTaskTextSize = function normalizeNodeForTaskTextSize(node, schema, smallTextAttrs) {
150
+ var _schema$nodes5 = schema.nodes,
151
+ taskList = _schema$nodes5.taskList,
152
+ taskItem = _schema$nodes5.taskItem,
153
+ blockTaskItem = _schema$nodes5.blockTaskItem;
154
+ var fontSize = schema.marks.fontSize;
155
+ if (!smallTextAttrs) {
156
+ return [node];
157
+ }
158
+ if ((0, _transforms.isTaskList)(node.type)) {
159
+ var transformedChildren = [];
160
+ node.content.forEach(function (child) {
161
+ transformedChildren.push.apply(transformedChildren, (0, _toConsumableArray2.default)(_normalizeNodeForTaskTextSize(child, schema, smallTextAttrs)));
162
+ });
163
+ return [taskList.create(node.attrs, transformedChildren)];
164
+ }
165
+ if (blockTaskItem && fontSize) {
166
+ if (node.type === taskItem) {
167
+ return [convertTaskItemToBlockTaskItem(node, schema, smallTextAttrs)];
168
+ }
169
+ if (node.type === blockTaskItem) {
170
+ return [addSmallTextToBlockTaskItem(node, schema, smallTextAttrs)];
171
+ }
172
+ }
173
+ return [node];
174
+ };
175
+ var normalizeNodeForTaskPaste = function normalizeNodeForTaskPaste(node, schema, smallTextAttrs) {
176
+ if (smallTextAttrs) {
177
+ return _normalizeNodeForTaskTextSize(node, schema, smallTextAttrs);
178
+ }
179
+ return normalizeBlockTaskItemToTaskItems(node, schema);
180
+ };
181
+ var tempTransformSliceToRemoveBlockTaskItem = exports.tempTransformSliceToRemoveBlockTaskItem = function tempTransformSliceToRemoveBlockTaskItem(slice, view) {
182
+ var fontSizeExperimentEnabled = (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
183
+ if (!fontSizeExperimentEnabled) {
184
+ return transformSliceToRemoveBlockTaskItemLegacy(slice, view);
185
+ }
186
+ var blockTaskItem = view.state.schema.nodes.blockTaskItem;
187
+ var _getTaskPasteContext = getTaskPasteContext(view),
188
+ isInTaskContext = _getTaskPasteContext.isInTaskContext,
189
+ smallTextAttrs = _getTaskPasteContext.smallTextAttrs;
190
+ if (!isInTaskContext || !blockTaskItem) {
191
+ return slice;
192
+ }
193
+ return transformSliceContent(slice, function (node) {
194
+ return normalizeNodeForTaskPaste(node, view.state.schema, smallTextAttrs);
195
+ });
78
196
  };
@@ -1,7 +1,11 @@
1
1
  import { findCutBefore } from '@atlaskit/editor-common/commands';
2
+ import { getFirstParagraphBlockMarkAttrs } from '@atlaskit/editor-common/lists';
3
+ import { isTaskList } from '@atlaskit/editor-common/transforms';
2
4
  import { findWrapping, ReplaceAroundStep } from '@atlaskit/editor-prosemirror/transform';
5
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
6
  import { getBlockRange, isActionOrDecisionItem, isActionOrDecisionList, liftBlock, subtreeHeight } from './helpers';
4
7
  import { findBlockTaskItem, normalizeTaskItemsSelection } from './utils';
8
+ import { normalizeNodeForTaskTextSize } from './utils/paste';
5
9
  export const liftSelection = (state, dispatch) => {
6
10
  const normalizedSelection = normalizeTaskItemsSelection(state.selection);
7
11
  const {
@@ -95,6 +99,9 @@ export const joinAtCut = $pos => (state, dispatch) => {
95
99
  const {
96
100
  blockTaskItem
97
101
  } = state.schema.nodes;
102
+ const {
103
+ fontSize
104
+ } = state.schema.marks;
98
105
  if (!$cut) {
99
106
  return false;
100
107
  }
@@ -145,7 +152,22 @@ export const joinAtCut = $pos => (state, dispatch) => {
145
152
  //
146
153
  // see https://prosemirror.net/docs/ref/#transform.ReplaceStep.constructor
147
154
  // see https://prosemirror.net/docs/ref/#transform.ReplaceAroundStep.constructor
148
- const tr = state.tr.step(new ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, true));
155
+ let tr = state.tr.step(new ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, true));
156
+ if (fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
157
+ const targetTaskListSmallTextAttrs = getFirstParagraphBlockMarkAttrs($cut.nodeBefore, fontSize);
158
+ const followingListPos = $cut.pos + $cut.nodeAfter.nodeSize;
159
+ const followingListNode = state.doc.resolve(followingListPos).nodeAfter;
160
+ if (followingListNode && isTaskList(followingListNode.type)) {
161
+ const normalizedListNode = normalizeNodeForTaskTextSize(followingListNode, state.schema, targetTaskListSmallTextAttrs)[0];
162
+ if (normalizedListNode && normalizedListNode !== followingListNode) {
163
+ const mappedFollowingListPos = tr.mapping.map(followingListPos);
164
+ const currentFollowingListNode = tr.doc.nodeAt(mappedFollowingListPos);
165
+ if (currentFollowingListNode) {
166
+ tr = tr.replaceWith(mappedFollowingListPos, mappedFollowingListPos + currentFollowingListNode.nodeSize, normalizedListNode);
167
+ }
168
+ }
169
+ }
170
+ }
149
171
  if (dispatch) {
150
172
  dispatch(tr);
151
173
  }
@@ -3,6 +3,7 @@ import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
3
3
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INDENT_DIRECTION, INDENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
4
  import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
5
5
  import { toggleTaskItemCheckbox, toggleTaskList as toggleTaskListKeymap } from '@atlaskit/editor-common/keymaps';
6
+ import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForParagraphAtPos } from '@atlaskit/editor-common/lists';
6
7
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
7
8
  import { deleteEmptyParagraphAndMoveBlockUp, filterCommand as filter, isEmptySelectionAtEnd, isEmptySelectionAtStart } from '@atlaskit/editor-common/utils';
8
9
  import { autoJoin, chainCommands } from '@atlaskit/editor-prosemirror/commands';
@@ -477,6 +478,36 @@ const splitListItemWith = (tr, content, $from, setSelection) => {
477
478
  const creatParentListItemFragement = state => {
478
479
  return state.schema.nodes.listItem.create({}, state.schema.nodes.paragraph.create());
479
480
  };
481
+ const getCurrentBlockTaskFontSizeAttrs = (state, $from) => {
482
+ if (!expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
483
+ return false;
484
+ }
485
+ const {
486
+ fontSize
487
+ } = state.schema.marks;
488
+ if (!fontSize) {
489
+ return false;
490
+ }
491
+ const result = findBlockTaskItem($from);
492
+ if (!result) {
493
+ return false;
494
+ }
495
+ return result.hasParagraph ? getBlockMarkAttrs($from.parent, fontSize) : getFirstParagraphBlockMarkAttrs(result.blockTaskItemNode, fontSize);
496
+ };
497
+ const createTaskItemForCurrentTextSize = (state, attrs, fontSizeAttrs) => {
498
+ const {
499
+ taskItem,
500
+ blockTaskItem,
501
+ paragraph
502
+ } = state.schema.nodes;
503
+ const {
504
+ fontSize
505
+ } = state.schema.marks;
506
+ if (fontSizeAttrs && blockTaskItem && paragraph && fontSize) {
507
+ return blockTaskItem.createChecked(attrs, paragraph.createChecked({}, undefined, [fontSize.create(fontSizeAttrs)]));
508
+ }
509
+ return taskItem.createAndFill(attrs);
510
+ };
480
511
  const splitListItem = (state, dispatch) => {
481
512
  const {
482
513
  tr,
@@ -490,6 +521,7 @@ const splitListItem = (state, dispatch) => {
490
521
  taskItem,
491
522
  paragraph
492
523
  } = state.schema.nodes;
524
+ const currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
493
525
  if (actionDecisionFollowsOrNothing($from)) {
494
526
  if (dispatch) {
495
527
  // If previous node is a blockTaskItem we just want to delete the existing node and replace it with a paragraph
@@ -508,7 +540,11 @@ const splitListItem = (state, dispatch) => {
508
540
  dispatch(splitListItemWith(tr, creatParentListItemFragement(state), $from, true));
509
541
  return true;
510
542
  }
511
- dispatch(splitListItemWith(tr, paragraph.createChecked(), $from, true));
543
+ const splitTr = splitListItemWith(tr, paragraph.createChecked(), $from, true);
544
+ if (currentBlockTaskFontSizeAttrs) {
545
+ reconcileBlockMarkForParagraphAtPos(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
546
+ }
547
+ dispatch(splitTr);
512
548
  }
513
549
  return true;
514
550
  }
@@ -581,11 +617,12 @@ const enter = (editorAnalyticsAPI, getContextIdentifier) => filter(isInsideTaskO
581
617
  // If the selection is a gap cursor at the end of the blockTaskItem,
582
618
  // we should insert a new taskItem.
583
619
  if ((!$from.parent.isTextblock || isInLastTextblockOfBlockTaskItem(state)) && $from.parentOffset === $from.parent.nodeSize - 2) {
584
- const newTaskItem = taskItem.createAndFill({
620
+ const currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
621
+ const newTaskNode = createTaskItemForCurrentTextSize(state, {
585
622
  localId: itemLocalId
586
- });
587
- if (newTaskItem) {
588
- tr.insert(blockTaskItemNode.pos + blockTaskItemNode.node.nodeSize, newTaskItem);
623
+ }, currentBlockTaskFontSizeAttrs);
624
+ if (newTaskNode) {
625
+ tr.insert(blockTaskItemNode.pos + blockTaskItemNode.node.nodeSize, newTaskNode);
589
626
 
590
627
  // Move the cursor to the end of the newly inserted blockTaskItem
591
628
  tr.setSelection(TextSelection.create(tr.doc, blockTaskItemNode.pos + blockTaskItemNode.node.nodeSize + 1));
@@ -594,12 +631,17 @@ const enter = (editorAnalyticsAPI, getContextIdentifier) => filter(isInsideTaskO
594
631
  }
595
632
 
596
633
  // Split near the depth of the current selection
597
- return tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
634
+ const splitTr = tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
598
635
  type: blockTaskItem,
599
636
  attrs: {
600
637
  localId: itemLocalId
601
638
  }
602
639
  }]);
640
+ const currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
641
+ if (currentBlockTaskFontSizeAttrs) {
642
+ reconcileBlockMarkForParagraphAtPos(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
643
+ }
644
+ return splitTr;
603
645
  }
604
646
  return tr.split($from.pos, 1, [{
605
647
  type: nodeType,
@@ -1,5 +1,9 @@
1
1
  import { uuid } from '@atlaskit/adf-schema';
2
+ import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs } from '@atlaskit/editor-common/lists';
3
+ import { isTaskList } from '@atlaskit/editor-common/transforms';
2
4
  import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
5
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
+
3
7
  /**
4
8
  * Transforms a paste slice to handle blockTaskItem nodes when pasting into task items.
5
9
  *
@@ -19,57 +23,180 @@ import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
19
23
  *
20
24
  * @see {@link https://hello.atlassian.net/wiki/spaces/EDITOR/pages/5626622054/Block+elements+in+task+-+Decision+log#Can-users-create-block-task-items%3F} for reasoning
21
25
  */
22
- export const tempTransformSliceToRemoveBlockTaskItem = (slice, view) => {
26
+ const getTaskPasteContext = view => {
27
+ var _schema$marks;
23
28
  const {
24
- schema
29
+ schema,
30
+ selection
25
31
  } = view.state;
26
32
  const {
27
33
  taskItem,
28
34
  blockTaskItem,
29
35
  paragraph
30
36
  } = schema.nodes;
31
-
32
- // Check if we're pasting into a taskItem
37
+ const fontSize = (_schema$marks = schema.marks) === null || _schema$marks === void 0 ? void 0 : _schema$marks.fontSize;
33
38
  const {
34
39
  $from
35
- } = view.state.selection;
36
- const isInTaskItem = $from.node().type === taskItem;
37
- if (isInTaskItem && blockTaskItem) {
38
- // Transform the slice to replace blockTaskItems with taskItems
40
+ } = selection;
41
+ const currentParent = $from.parent;
42
+ const currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
43
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === taskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem) {
44
+ return {
45
+ isInTaskContext: true,
46
+ smallTextAttrs: false
47
+ };
48
+ }
49
+ if (!blockTaskItem) {
50
+ return {
51
+ isInTaskContext: false,
52
+ smallTextAttrs: false
53
+ };
54
+ }
55
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === blockTaskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem) {
56
+ return {
57
+ isInTaskContext: true,
58
+ smallTextAttrs: fontSize ? getFirstParagraphBlockMarkAttrs(currentParent !== null && currentParent !== void 0 ? currentParent : currentNode, fontSize) : false
59
+ };
60
+ }
61
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem) {
62
+ return {
63
+ isInTaskContext: true,
64
+ smallTextAttrs: fontSize ? getBlockMarkAttrs(currentParent, fontSize) : false
65
+ };
66
+ }
67
+ return {
68
+ isInTaskContext: false,
69
+ smallTextAttrs: false
70
+ };
71
+ };
72
+ const convertTaskItemToBlockTaskItem = (node, schema, smallTextAttrs) => {
73
+ const {
74
+ blockTaskItem,
75
+ paragraph
76
+ } = schema.nodes;
77
+ const {
78
+ fontSize
79
+ } = schema.marks;
80
+ return blockTaskItem.create(node.attrs, paragraph.createChecked({}, node.content, [fontSize.create(smallTextAttrs)]));
81
+ };
82
+ const addSmallTextToBlockTaskItem = (node, schema, smallTextAttrs) => {
83
+ const {
84
+ paragraph
85
+ } = schema.nodes;
86
+ const {
87
+ fontSize
88
+ } = schema.marks;
89
+ const newContent = [];
90
+ node.content.forEach(child => {
91
+ if (child.type === paragraph) {
92
+ newContent.push(paragraph.createChecked(child.attrs, child.content, child.marks.filter(mark => mark.type !== fontSize).concat(fontSize.create(smallTextAttrs))));
93
+ } else {
94
+ newContent.push(child);
95
+ }
96
+ });
97
+ return node.type.create(node.attrs, newContent);
98
+ };
99
+ const normalizeBlockTaskItemToTaskItems = (node, schema) => {
100
+ const {
101
+ taskItem,
102
+ blockTaskItem,
103
+ paragraph
104
+ } = schema.nodes;
105
+ if (!blockTaskItem || node.type !== blockTaskItem) {
106
+ return [node];
107
+ }
108
+ let allChildrenAreParagraphs = true;
109
+ node.content.forEach(child => {
110
+ if (child.type !== paragraph) {
111
+ allChildrenAreParagraphs = false;
112
+ }
113
+ });
114
+ if (allChildrenAreParagraphs && node.childCount > 0) {
39
115
  const transformedContent = [];
40
- slice.content.forEach(node => {
41
- if (node.type === blockTaskItem) {
42
- // Check if blockTaskItem only contains paragraphs
43
- let allChildrenAreParagraphs = true;
44
- node.content.forEach(child => {
45
- if (child.type !== paragraph) {
46
- allChildrenAreParagraphs = false;
47
- }
48
- });
49
- if (allChildrenAreParagraphs && node.childCount > 0) {
50
- // Convert each paragraph to a taskItem
51
- node.content.forEach(paragraphNode => {
52
- const newTaskItem = taskItem.create({
53
- localId: uuid.generate(),
54
- state: node.attrs.state || 'TODO'
55
- }, paragraphNode.content);
56
- transformedContent.push(newTaskItem);
57
- });
58
- } else {
59
- // Keep the blockTaskItem as is if it doesn't only contain paragraphs
60
- transformedContent.push(node);
61
- }
62
- } else {
63
- // Keep other nodes as is
64
- transformedContent.push(node);
65
- }
116
+ node.content.forEach(paragraphNode => {
117
+ transformedContent.push(taskItem.create({
118
+ localId: uuid.generate(),
119
+ state: node.attrs.state || 'TODO'
120
+ }, paragraphNode.content));
66
121
  });
67
-
68
- // Create new slice with transformed content
69
- if (transformedContent.length !== slice.content.childCount || transformedContent.some((node, idx) => node !== slice.content.child(idx))) {
70
- const newFragment = Fragment.from(transformedContent);
71
- return new Slice(newFragment, slice.openStart, slice.openEnd);
72
- }
122
+ return transformedContent;
123
+ }
124
+ return [node];
125
+ };
126
+ const transformSliceContent = (slice, transformNode) => {
127
+ const transformedContent = [];
128
+ slice.content.forEach(node => {
129
+ transformedContent.push(...transformNode(node));
130
+ });
131
+ if (transformedContent.length !== slice.content.childCount || transformedContent.some((node, idx) => node !== slice.content.child(idx))) {
132
+ const newFragment = Fragment.from(transformedContent);
133
+ return new Slice(newFragment, slice.openStart, slice.openEnd);
73
134
  }
74
135
  return slice;
136
+ };
137
+ const transformSliceToRemoveBlockTaskItemLegacy = (slice, view) => {
138
+ const {
139
+ schema
140
+ } = view.state;
141
+ const {
142
+ taskItem,
143
+ blockTaskItem
144
+ } = schema.nodes;
145
+ const isInTaskItem = view.state.selection.$from.node().type === taskItem;
146
+ if (!isInTaskItem || !blockTaskItem) {
147
+ return slice;
148
+ }
149
+ return transformSliceContent(slice, node => normalizeBlockTaskItemToTaskItems(node, schema));
150
+ };
151
+ export const normalizeNodeForTaskTextSize = (node, schema, smallTextAttrs) => {
152
+ const {
153
+ taskList,
154
+ taskItem,
155
+ blockTaskItem
156
+ } = schema.nodes;
157
+ const {
158
+ fontSize
159
+ } = schema.marks;
160
+ if (!smallTextAttrs) {
161
+ return [node];
162
+ }
163
+ if (isTaskList(node.type)) {
164
+ const transformedChildren = [];
165
+ node.content.forEach(child => {
166
+ transformedChildren.push(...normalizeNodeForTaskTextSize(child, schema, smallTextAttrs));
167
+ });
168
+ return [taskList.create(node.attrs, transformedChildren)];
169
+ }
170
+ if (blockTaskItem && fontSize) {
171
+ if (node.type === taskItem) {
172
+ return [convertTaskItemToBlockTaskItem(node, schema, smallTextAttrs)];
173
+ }
174
+ if (node.type === blockTaskItem) {
175
+ return [addSmallTextToBlockTaskItem(node, schema, smallTextAttrs)];
176
+ }
177
+ }
178
+ return [node];
179
+ };
180
+ const normalizeNodeForTaskPaste = (node, schema, smallTextAttrs) => {
181
+ if (smallTextAttrs) {
182
+ return normalizeNodeForTaskTextSize(node, schema, smallTextAttrs);
183
+ }
184
+ return normalizeBlockTaskItemToTaskItems(node, schema);
185
+ };
186
+ export const tempTransformSliceToRemoveBlockTaskItem = (slice, view) => {
187
+ const fontSizeExperimentEnabled = expValEquals('platform_editor_small_font_size', 'isEnabled', true);
188
+ if (!fontSizeExperimentEnabled) {
189
+ return transformSliceToRemoveBlockTaskItemLegacy(slice, view);
190
+ }
191
+ const {
192
+ blockTaskItem
193
+ } = view.state.schema.nodes;
194
+ const {
195
+ isInTaskContext,
196
+ smallTextAttrs
197
+ } = getTaskPasteContext(view);
198
+ if (!isInTaskContext || !blockTaskItem) {
199
+ return slice;
200
+ }
201
+ return transformSliceContent(slice, node => normalizeNodeForTaskPaste(node, view.state.schema, smallTextAttrs));
75
202
  };
@@ -1,7 +1,11 @@
1
1
  import { findCutBefore } from '@atlaskit/editor-common/commands';
2
+ import { getFirstParagraphBlockMarkAttrs } from '@atlaskit/editor-common/lists';
3
+ import { isTaskList } from '@atlaskit/editor-common/transforms';
2
4
  import { findWrapping, ReplaceAroundStep } from '@atlaskit/editor-prosemirror/transform';
5
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
3
6
  import { getBlockRange, isActionOrDecisionItem, isActionOrDecisionList, liftBlock, subtreeHeight } from './helpers';
4
7
  import { findBlockTaskItem, normalizeTaskItemsSelection } from './utils';
8
+ import { normalizeNodeForTaskTextSize } from './utils/paste';
5
9
  export var liftSelection = function liftSelection(state, dispatch) {
6
10
  var normalizedSelection = normalizeTaskItemsSelection(state.selection);
7
11
  var $from = normalizedSelection.$from,
@@ -88,6 +92,7 @@ export var joinAtCut = function joinAtCut($pos) {
88
92
  return function (state, dispatch) {
89
93
  var $cut = findCutBefore($pos);
90
94
  var blockTaskItem = state.schema.nodes.blockTaskItem;
95
+ var fontSize = state.schema.marks.fontSize;
91
96
  if (!$cut) {
92
97
  return false;
93
98
  }
@@ -137,6 +142,21 @@ export var joinAtCut = function joinAtCut($pos) {
137
142
  // see https://prosemirror.net/docs/ref/#transform.ReplaceStep.constructor
138
143
  // see https://prosemirror.net/docs/ref/#transform.ReplaceAroundStep.constructor
139
144
  var tr = state.tr.step(new ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert, true));
145
+ if (fontSize && expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
146
+ var targetTaskListSmallTextAttrs = getFirstParagraphBlockMarkAttrs($cut.nodeBefore, fontSize);
147
+ var followingListPos = $cut.pos + $cut.nodeAfter.nodeSize;
148
+ var followingListNode = state.doc.resolve(followingListPos).nodeAfter;
149
+ if (followingListNode && isTaskList(followingListNode.type)) {
150
+ var normalizedListNode = normalizeNodeForTaskTextSize(followingListNode, state.schema, targetTaskListSmallTextAttrs)[0];
151
+ if (normalizedListNode && normalizedListNode !== followingListNode) {
152
+ var mappedFollowingListPos = tr.mapping.map(followingListPos);
153
+ var currentFollowingListNode = tr.doc.nodeAt(mappedFollowingListPos);
154
+ if (currentFollowingListNode) {
155
+ tr = tr.replaceWith(mappedFollowingListPos, mappedFollowingListPos + currentFollowingListNode.nodeSize, normalizedListNode);
156
+ }
157
+ }
158
+ }
159
+ }
140
160
  if (dispatch) {
141
161
  dispatch(tr);
142
162
  }
@@ -6,6 +6,7 @@ import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
6
6
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INDENT_DIRECTION, INDENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
7
7
  import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
8
8
  import { toggleTaskItemCheckbox, toggleTaskList as toggleTaskListKeymap } from '@atlaskit/editor-common/keymaps';
9
+ import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs, reconcileBlockMarkForParagraphAtPos } from '@atlaskit/editor-common/lists';
9
10
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
10
11
  import { deleteEmptyParagraphAndMoveBlockUp, filterCommand as filter, isEmptySelectionAtEnd, isEmptySelectionAtStart } from '@atlaskit/editor-common/utils';
11
12
  import { autoJoin, chainCommands } from '@atlaskit/editor-prosemirror/commands';
@@ -489,14 +490,40 @@ var splitListItemWith = function splitListItemWith(tr, content, $from, setSelect
489
490
  var creatParentListItemFragement = function creatParentListItemFragement(state) {
490
491
  return state.schema.nodes.listItem.create({}, state.schema.nodes.paragraph.create());
491
492
  };
492
- var splitListItem = function splitListItem(state, dispatch) {
493
- var tr = state.tr,
494
- $from = state.selection.$from;
493
+ var getCurrentBlockTaskFontSizeAttrs = function getCurrentBlockTaskFontSizeAttrs(state, $from) {
494
+ if (!expValEquals('platform_editor_small_font_size', 'isEnabled', true)) {
495
+ return false;
496
+ }
497
+ var fontSize = state.schema.marks.fontSize;
498
+ if (!fontSize) {
499
+ return false;
500
+ }
501
+ var result = findBlockTaskItem($from);
502
+ if (!result) {
503
+ return false;
504
+ }
505
+ return result.hasParagraph ? getBlockMarkAttrs($from.parent, fontSize) : getFirstParagraphBlockMarkAttrs(result.blockTaskItemNode, fontSize);
506
+ };
507
+ var createTaskItemForCurrentTextSize = function createTaskItemForCurrentTextSize(state, attrs, fontSizeAttrs) {
495
508
  var _state$schema$nodes5 = state.schema.nodes,
496
- listItem = _state$schema$nodes5.listItem,
497
- blockTaskItem = _state$schema$nodes5.blockTaskItem,
498
509
  taskItem = _state$schema$nodes5.taskItem,
510
+ blockTaskItem = _state$schema$nodes5.blockTaskItem,
499
511
  paragraph = _state$schema$nodes5.paragraph;
512
+ var fontSize = state.schema.marks.fontSize;
513
+ if (fontSizeAttrs && blockTaskItem && paragraph && fontSize) {
514
+ return blockTaskItem.createChecked(attrs, paragraph.createChecked({}, undefined, [fontSize.create(fontSizeAttrs)]));
515
+ }
516
+ return taskItem.createAndFill(attrs);
517
+ };
518
+ var splitListItem = function splitListItem(state, dispatch) {
519
+ var tr = state.tr,
520
+ $from = state.selection.$from;
521
+ var _state$schema$nodes6 = state.schema.nodes,
522
+ listItem = _state$schema$nodes6.listItem,
523
+ blockTaskItem = _state$schema$nodes6.blockTaskItem,
524
+ taskItem = _state$schema$nodes6.taskItem,
525
+ paragraph = _state$schema$nodes6.paragraph;
526
+ var currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
500
527
  if (actionDecisionFollowsOrNothing($from)) {
501
528
  if (dispatch) {
502
529
  // If previous node is a blockTaskItem we just want to delete the existing node and replace it with a paragraph
@@ -515,7 +542,11 @@ var splitListItem = function splitListItem(state, dispatch) {
515
542
  dispatch(splitListItemWith(tr, creatParentListItemFragement(state), $from, true));
516
543
  return true;
517
544
  }
518
- dispatch(splitListItemWith(tr, paragraph.createChecked(), $from, true));
545
+ var splitTr = splitListItemWith(tr, paragraph.createChecked(), $from, true);
546
+ if (currentBlockTaskFontSizeAttrs) {
547
+ reconcileBlockMarkForParagraphAtPos(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
548
+ }
549
+ dispatch(splitTr);
519
550
  }
520
551
  return true;
521
552
  }
@@ -583,11 +614,12 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
583
614
  // If the selection is a gap cursor at the end of the blockTaskItem,
584
615
  // we should insert a new taskItem.
585
616
  if ((!$from.parent.isTextblock || isInLastTextblockOfBlockTaskItem(state)) && $from.parentOffset === $from.parent.nodeSize - 2) {
586
- var _newTaskItem = taskItem.createAndFill({
617
+ var _currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
618
+ var newTaskNode = createTaskItemForCurrentTextSize(state, {
587
619
  localId: itemLocalId
588
- });
589
- if (_newTaskItem) {
590
- tr.insert(_blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize, _newTaskItem);
620
+ }, _currentBlockTaskFontSizeAttrs);
621
+ if (newTaskNode) {
622
+ tr.insert(_blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize, newTaskNode);
591
623
 
592
624
  // Move the cursor to the end of the newly inserted blockTaskItem
593
625
  tr.setSelection(TextSelection.create(tr.doc, _blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize + 1));
@@ -596,12 +628,17 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
596
628
  }
597
629
 
598
630
  // Split near the depth of the current selection
599
- return tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
631
+ var splitTr = tr.split($from.pos, $from !== null && $from !== void 0 && (_$from$parent = $from.parent) !== null && _$from$parent !== void 0 && _$from$parent.isTextblock ? 2 : 1, [{
600
632
  type: blockTaskItem,
601
633
  attrs: {
602
634
  localId: itemLocalId
603
635
  }
604
636
  }]);
637
+ var currentBlockTaskFontSizeAttrs = getCurrentBlockTaskFontSizeAttrs(state, $from);
638
+ if (currentBlockTaskFontSizeAttrs) {
639
+ reconcileBlockMarkForParagraphAtPos(splitTr, splitTr.selection.from, state.schema.marks.fontSize, currentBlockTaskFontSizeAttrs);
640
+ }
641
+ return splitTr;
605
642
  }
606
643
  return tr.split($from.pos, 1, [{
607
644
  type: nodeType,
@@ -1,5 +1,10 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
1
2
  import { uuid } from '@atlaskit/adf-schema';
3
+ import { getBlockMarkAttrs, getFirstParagraphBlockMarkAttrs } from '@atlaskit/editor-common/lists';
4
+ import { isTaskList } from '@atlaskit/editor-common/transforms';
2
5
  import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
6
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
+
3
8
  /**
4
9
  * Transforms a paste slice to handle blockTaskItem nodes when pasting into task items.
5
10
  *
@@ -19,54 +24,168 @@ import { Slice, Fragment } from '@atlaskit/editor-prosemirror/model';
19
24
  *
20
25
  * @see {@link https://hello.atlassian.net/wiki/spaces/EDITOR/pages/5626622054/Block+elements+in+task+-+Decision+log#Can-users-create-block-task-items%3F} for reasoning
21
26
  */
22
- export var tempTransformSliceToRemoveBlockTaskItem = function tempTransformSliceToRemoveBlockTaskItem(slice, view) {
23
- var schema = view.state.schema;
27
+ var getTaskPasteContext = function getTaskPasteContext(view) {
28
+ var _schema$marks;
29
+ var _view$state = view.state,
30
+ schema = _view$state.schema,
31
+ selection = _view$state.selection;
24
32
  var _schema$nodes = schema.nodes,
25
33
  taskItem = _schema$nodes.taskItem,
26
34
  blockTaskItem = _schema$nodes.blockTaskItem,
27
35
  paragraph = _schema$nodes.paragraph;
28
-
29
- // Check if we're pasting into a taskItem
30
- var $from = view.state.selection.$from;
31
- var isInTaskItem = $from.node().type === taskItem;
32
- if (isInTaskItem && blockTaskItem) {
33
- // Transform the slice to replace blockTaskItems with taskItems
36
+ var fontSize = (_schema$marks = schema.marks) === null || _schema$marks === void 0 ? void 0 : _schema$marks.fontSize;
37
+ var $from = selection.$from;
38
+ var currentParent = $from.parent;
39
+ var currentNode = typeof $from.node === 'function' ? $from.node() : undefined;
40
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === taskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === taskItem) {
41
+ return {
42
+ isInTaskContext: true,
43
+ smallTextAttrs: false
44
+ };
45
+ }
46
+ if (!blockTaskItem) {
47
+ return {
48
+ isInTaskContext: false,
49
+ smallTextAttrs: false
50
+ };
51
+ }
52
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === blockTaskItem || (currentNode === null || currentNode === void 0 ? void 0 : currentNode.type) === blockTaskItem) {
53
+ return {
54
+ isInTaskContext: true,
55
+ smallTextAttrs: fontSize ? getFirstParagraphBlockMarkAttrs(currentParent !== null && currentParent !== void 0 ? currentParent : currentNode, fontSize) : false
56
+ };
57
+ }
58
+ if ((currentParent === null || currentParent === void 0 ? void 0 : currentParent.type) === paragraph && $from.depth > 0 && $from.node($from.depth - 1).type === blockTaskItem) {
59
+ return {
60
+ isInTaskContext: true,
61
+ smallTextAttrs: fontSize ? getBlockMarkAttrs(currentParent, fontSize) : false
62
+ };
63
+ }
64
+ return {
65
+ isInTaskContext: false,
66
+ smallTextAttrs: false
67
+ };
68
+ };
69
+ var convertTaskItemToBlockTaskItem = function convertTaskItemToBlockTaskItem(node, schema, smallTextAttrs) {
70
+ var _schema$nodes2 = schema.nodes,
71
+ blockTaskItem = _schema$nodes2.blockTaskItem,
72
+ paragraph = _schema$nodes2.paragraph;
73
+ var fontSize = schema.marks.fontSize;
74
+ return blockTaskItem.create(node.attrs, paragraph.createChecked({}, node.content, [fontSize.create(smallTextAttrs)]));
75
+ };
76
+ var addSmallTextToBlockTaskItem = function addSmallTextToBlockTaskItem(node, schema, smallTextAttrs) {
77
+ var paragraph = schema.nodes.paragraph;
78
+ var fontSize = schema.marks.fontSize;
79
+ var newContent = [];
80
+ node.content.forEach(function (child) {
81
+ if (child.type === paragraph) {
82
+ newContent.push(paragraph.createChecked(child.attrs, child.content, child.marks.filter(function (mark) {
83
+ return mark.type !== fontSize;
84
+ }).concat(fontSize.create(smallTextAttrs))));
85
+ } else {
86
+ newContent.push(child);
87
+ }
88
+ });
89
+ return node.type.create(node.attrs, newContent);
90
+ };
91
+ var normalizeBlockTaskItemToTaskItems = function normalizeBlockTaskItemToTaskItems(node, schema) {
92
+ var _schema$nodes3 = schema.nodes,
93
+ taskItem = _schema$nodes3.taskItem,
94
+ blockTaskItem = _schema$nodes3.blockTaskItem,
95
+ paragraph = _schema$nodes3.paragraph;
96
+ if (!blockTaskItem || node.type !== blockTaskItem) {
97
+ return [node];
98
+ }
99
+ var allChildrenAreParagraphs = true;
100
+ node.content.forEach(function (child) {
101
+ if (child.type !== paragraph) {
102
+ allChildrenAreParagraphs = false;
103
+ }
104
+ });
105
+ if (allChildrenAreParagraphs && node.childCount > 0) {
34
106
  var transformedContent = [];
35
- slice.content.forEach(function (node) {
36
- if (node.type === blockTaskItem) {
37
- // Check if blockTaskItem only contains paragraphs
38
- var allChildrenAreParagraphs = true;
39
- node.content.forEach(function (child) {
40
- if (child.type !== paragraph) {
41
- allChildrenAreParagraphs = false;
42
- }
43
- });
44
- if (allChildrenAreParagraphs && node.childCount > 0) {
45
- // Convert each paragraph to a taskItem
46
- node.content.forEach(function (paragraphNode) {
47
- var newTaskItem = taskItem.create({
48
- localId: uuid.generate(),
49
- state: node.attrs.state || 'TODO'
50
- }, paragraphNode.content);
51
- transformedContent.push(newTaskItem);
52
- });
53
- } else {
54
- // Keep the blockTaskItem as is if it doesn't only contain paragraphs
55
- transformedContent.push(node);
56
- }
57
- } else {
58
- // Keep other nodes as is
59
- transformedContent.push(node);
60
- }
107
+ node.content.forEach(function (paragraphNode) {
108
+ transformedContent.push(taskItem.create({
109
+ localId: uuid.generate(),
110
+ state: node.attrs.state || 'TODO'
111
+ }, paragraphNode.content));
61
112
  });
62
-
63
- // Create new slice with transformed content
64
- if (transformedContent.length !== slice.content.childCount || transformedContent.some(function (node, idx) {
65
- return node !== slice.content.child(idx);
66
- })) {
67
- var newFragment = Fragment.from(transformedContent);
68
- return new Slice(newFragment, slice.openStart, slice.openEnd);
69
- }
113
+ return transformedContent;
114
+ }
115
+ return [node];
116
+ };
117
+ var transformSliceContent = function transformSliceContent(slice, transformNode) {
118
+ var transformedContent = [];
119
+ slice.content.forEach(function (node) {
120
+ transformedContent.push.apply(transformedContent, _toConsumableArray(transformNode(node)));
121
+ });
122
+ if (transformedContent.length !== slice.content.childCount || transformedContent.some(function (node, idx) {
123
+ return node !== slice.content.child(idx);
124
+ })) {
125
+ var newFragment = Fragment.from(transformedContent);
126
+ return new Slice(newFragment, slice.openStart, slice.openEnd);
70
127
  }
71
128
  return slice;
129
+ };
130
+ var transformSliceToRemoveBlockTaskItemLegacy = function transformSliceToRemoveBlockTaskItemLegacy(slice, view) {
131
+ var schema = view.state.schema;
132
+ var _schema$nodes4 = schema.nodes,
133
+ taskItem = _schema$nodes4.taskItem,
134
+ blockTaskItem = _schema$nodes4.blockTaskItem;
135
+ var isInTaskItem = view.state.selection.$from.node().type === taskItem;
136
+ if (!isInTaskItem || !blockTaskItem) {
137
+ return slice;
138
+ }
139
+ return transformSliceContent(slice, function (node) {
140
+ return normalizeBlockTaskItemToTaskItems(node, schema);
141
+ });
142
+ };
143
+ var _normalizeNodeForTaskTextSize = function normalizeNodeForTaskTextSize(node, schema, smallTextAttrs) {
144
+ var _schema$nodes5 = schema.nodes,
145
+ taskList = _schema$nodes5.taskList,
146
+ taskItem = _schema$nodes5.taskItem,
147
+ blockTaskItem = _schema$nodes5.blockTaskItem;
148
+ var fontSize = schema.marks.fontSize;
149
+ if (!smallTextAttrs) {
150
+ return [node];
151
+ }
152
+ if (isTaskList(node.type)) {
153
+ var transformedChildren = [];
154
+ node.content.forEach(function (child) {
155
+ transformedChildren.push.apply(transformedChildren, _toConsumableArray(_normalizeNodeForTaskTextSize(child, schema, smallTextAttrs)));
156
+ });
157
+ return [taskList.create(node.attrs, transformedChildren)];
158
+ }
159
+ if (blockTaskItem && fontSize) {
160
+ if (node.type === taskItem) {
161
+ return [convertTaskItemToBlockTaskItem(node, schema, smallTextAttrs)];
162
+ }
163
+ if (node.type === blockTaskItem) {
164
+ return [addSmallTextToBlockTaskItem(node, schema, smallTextAttrs)];
165
+ }
166
+ }
167
+ return [node];
168
+ };
169
+ export { _normalizeNodeForTaskTextSize as normalizeNodeForTaskTextSize };
170
+ var normalizeNodeForTaskPaste = function normalizeNodeForTaskPaste(node, schema, smallTextAttrs) {
171
+ if (smallTextAttrs) {
172
+ return _normalizeNodeForTaskTextSize(node, schema, smallTextAttrs);
173
+ }
174
+ return normalizeBlockTaskItemToTaskItems(node, schema);
175
+ };
176
+ export var tempTransformSliceToRemoveBlockTaskItem = function tempTransformSliceToRemoveBlockTaskItem(slice, view) {
177
+ var fontSizeExperimentEnabled = expValEquals('platform_editor_small_font_size', 'isEnabled', true);
178
+ if (!fontSizeExperimentEnabled) {
179
+ return transformSliceToRemoveBlockTaskItemLegacy(slice, view);
180
+ }
181
+ var blockTaskItem = view.state.schema.nodes.blockTaskItem;
182
+ var _getTaskPasteContext = getTaskPasteContext(view),
183
+ isInTaskContext = _getTaskPasteContext.isInTaskContext,
184
+ smallTextAttrs = _getTaskPasteContext.smallTextAttrs;
185
+ if (!isInTaskContext || !blockTaskItem) {
186
+ return slice;
187
+ }
188
+ return transformSliceContent(slice, function (node) {
189
+ return normalizeNodeForTaskPaste(node, view.state.schema, smallTextAttrs);
190
+ });
72
191
  };
@@ -1,22 +1,6 @@
1
+ import type { FontSizeMarkAttrs } from '@atlaskit/adf-schema';
1
2
  import { Slice } from '@atlaskit/editor-prosemirror/model';
3
+ import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
2
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
- /**
4
- * Transforms a paste slice to handle blockTaskItem nodes when pasting into task items.
5
- *
6
- * Initially we do not support user creation of blockTaskItem - it is intended primarily
7
- * for TinyMCE migration purposes however that may change in the future.
8
- * This function handles the behavior to work around Prosemirror behaviour which decides
9
- * that blockTaskItem is the appropriate node to use here.
10
- *
11
- * @param slice - The slice being pasted
12
- * @param view - The editor view where the paste is occurring
13
- * @returns The transformed slice with blockTaskItems converted to taskItems when appropriate
14
- *
15
- * @example
16
- * ```typescript
17
- * const transformedSlice = tempTransformSliceToRemoveBlockTaskItem(pasteSlice, editorView);
18
- * ```
19
- *
20
- * @see {@link https://hello.atlassian.net/wiki/spaces/EDITOR/pages/5626622054/Block+elements+in+task+-+Decision+log#Can-users-create-block-task-items%3F} for reasoning
21
- */
5
+ export declare const normalizeNodeForTaskTextSize: (node: PMNode, schema: Schema, smallTextAttrs: FontSizeMarkAttrs | false) => PMNode[];
22
6
  export declare const tempTransformSliceToRemoveBlockTaskItem: (slice: Slice, view: EditorView) => Slice;
@@ -1,22 +1,6 @@
1
+ import type { FontSizeMarkAttrs } from '@atlaskit/adf-schema';
1
2
  import { Slice } from '@atlaskit/editor-prosemirror/model';
3
+ import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
2
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
3
- /**
4
- * Transforms a paste slice to handle blockTaskItem nodes when pasting into task items.
5
- *
6
- * Initially we do not support user creation of blockTaskItem - it is intended primarily
7
- * for TinyMCE migration purposes however that may change in the future.
8
- * This function handles the behavior to work around Prosemirror behaviour which decides
9
- * that blockTaskItem is the appropriate node to use here.
10
- *
11
- * @param slice - The slice being pasted
12
- * @param view - The editor view where the paste is occurring
13
- * @returns The transformed slice with blockTaskItems converted to taskItems when appropriate
14
- *
15
- * @example
16
- * ```typescript
17
- * const transformedSlice = tempTransformSliceToRemoveBlockTaskItem(pasteSlice, editorView);
18
- * ```
19
- *
20
- * @see {@link https://hello.atlassian.net/wiki/spaces/EDITOR/pages/5626622054/Block+elements+in+task+-+Decision+log#Can-users-create-block-task-items%3F} for reasoning
21
- */
5
+ export declare const normalizeNodeForTaskTextSize: (node: PMNode, schema: Schema, smallTextAttrs: FontSizeMarkAttrs | false) => PMNode[];
22
6
  export declare const tempTransformSliceToRemoveBlockTaskItem: (slice: Slice, view: EditorView) => Slice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-tasks-and-decisions",
3
- "version": "11.3.6",
3
+ "version": "11.4.0",
4
4
  "description": "Tasks and decisions plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -49,14 +49,14 @@
49
49
  "@atlaskit/primitives": "^18.1.0",
50
50
  "@atlaskit/prosemirror-input-rules": "^3.6.0",
51
51
  "@atlaskit/task-decision": "^19.3.0",
52
- "@atlaskit/tmp-editor-statsig": "^48.0.0",
53
- "@atlaskit/tokens": "^11.3.0",
52
+ "@atlaskit/tmp-editor-statsig": "^49.0.0",
53
+ "@atlaskit/tokens": "^11.4.0",
54
54
  "@babel/runtime": "^7.0.0",
55
55
  "@compiled/react": "^0.20.0",
56
56
  "bind-event-listener": "^3.0.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
  "react-intl-next": "npm:react-intl@^5.18.1"