@atlaskit/editor-plugin-tasks-and-decisions 11.2.1 → 11.3.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 +12 -0
- package/dist/cjs/pm-plugins/actions/move-selected-task-list-items.js +88 -0
- package/dist/cjs/pm-plugins/keymaps.js +34 -4
- package/dist/cjs/pm-plugins/task-list-indentation.js +213 -0
- package/dist/es2019/pm-plugins/actions/move-selected-task-list-items.js +92 -0
- package/dist/es2019/pm-plugins/keymaps.js +30 -0
- package/dist/es2019/pm-plugins/task-list-indentation.js +194 -0
- package/dist/esm/pm-plugins/actions/move-selected-task-list-items.js +82 -0
- package/dist/esm/pm-plugins/keymaps.js +30 -0
- package/dist/esm/pm-plugins/task-list-indentation.js +206 -0
- package/dist/types/pm-plugins/actions/move-selected-task-list-items.d.ts +2 -0
- package/dist/types/pm-plugins/task-list-indentation.d.ts +36 -0
- package/dist/types-ts4.5/pm-plugins/actions/move-selected-task-list-items.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/task-list-indentation.d.ts +36 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-tasks-and-decisions
|
|
2
2
|
|
|
3
|
+
## 11.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`65cb641586cc0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/65cb641586cc0) -
|
|
8
|
+
Add flexible per-item task list indentation with breakout support behind
|
|
9
|
+
platform_editor_flexible_list_indentation experiment
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
3
15
|
## 11.2.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.moveSelectedTaskListItems = moveSelectedTaskListItems;
|
|
7
|
+
var _lists = require("@atlaskit/editor-common/lists");
|
|
8
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
9
|
+
var _taskListIndentation = require("../task-list-indentation");
|
|
10
|
+
var MAX_TASK_LIST_DEPTH = 6;
|
|
11
|
+
function moveSelectedTaskListItems(tr, indentDelta) {
|
|
12
|
+
var doc = tr.doc,
|
|
13
|
+
selection = tr.selection;
|
|
14
|
+
var schema = doc.type.schema;
|
|
15
|
+
var taskList = schema.nodes.taskList;
|
|
16
|
+
var $from = selection.$from,
|
|
17
|
+
$to = selection.$to;
|
|
18
|
+
var rootListResult = (0, _utils.findFarthestParentNode)(function (node) {
|
|
19
|
+
return node.type === taskList;
|
|
20
|
+
})($from);
|
|
21
|
+
if (!rootListResult) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
var rootListStart = rootListResult.pos;
|
|
25
|
+
var rootListEnd = rootListStart + rootListResult.node.nodeSize;
|
|
26
|
+
var flattenResult = (0, _taskListIndentation.flattenTaskList)({
|
|
27
|
+
doc: doc,
|
|
28
|
+
rootListStart: rootListStart,
|
|
29
|
+
rootListEnd: rootListEnd,
|
|
30
|
+
selectionFrom: $from.pos,
|
|
31
|
+
selectionTo: $to.pos,
|
|
32
|
+
indentDelta: indentDelta,
|
|
33
|
+
maxDepth: MAX_TASK_LIST_DEPTH
|
|
34
|
+
});
|
|
35
|
+
if (!flattenResult) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
var flattenedItems = flattenResult.items,
|
|
39
|
+
startIndex = flattenResult.startIndex,
|
|
40
|
+
endIndex = flattenResult.endIndex;
|
|
41
|
+
var _buildReplacementFrag = (0, _lists.buildReplacementFragment)({
|
|
42
|
+
items: flattenedItems,
|
|
43
|
+
schema: schema,
|
|
44
|
+
rebuildFn: _taskListIndentation.rebuildTaskList,
|
|
45
|
+
extractContentFn: function extractContentFn(item, s) {
|
|
46
|
+
// Extract task item content for breakout.
|
|
47
|
+
// taskItem has inline content, so wrap in a paragraph.
|
|
48
|
+
// blockTaskItem already has paragraph children.
|
|
49
|
+
var blockTaskItem = s.nodes.blockTaskItem;
|
|
50
|
+
if (blockTaskItem != null && item.node.type === blockTaskItem) {
|
|
51
|
+
// blockTaskItem children are already paragraphs/extensions
|
|
52
|
+
var children = [];
|
|
53
|
+
item.node.forEach(function (child) {
|
|
54
|
+
return children.push(child);
|
|
55
|
+
});
|
|
56
|
+
return children;
|
|
57
|
+
}
|
|
58
|
+
// Regular taskItem — wrap inline content in a paragraph
|
|
59
|
+
return [s.nodes.paragraph.create(null, item.node.content)];
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
fragment = _buildReplacementFrag.fragment,
|
|
63
|
+
contentStartOffsets = _buildReplacementFrag.contentStartOffsets;
|
|
64
|
+
if (fragment.size === 0) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
tr.replaceWith(rootListStart, rootListEnd, fragment);
|
|
68
|
+
var _computeSelectionOffs = (0, _lists.computeSelectionOffsets)({
|
|
69
|
+
items: flattenedItems,
|
|
70
|
+
startIndex: startIndex,
|
|
71
|
+
endIndex: endIndex,
|
|
72
|
+
originalFrom: $from.pos,
|
|
73
|
+
originalTo: $to.pos,
|
|
74
|
+
contentStartOffsets: contentStartOffsets,
|
|
75
|
+
rootListStart: rootListStart,
|
|
76
|
+
docSize: tr.doc.content.size
|
|
77
|
+
}),
|
|
78
|
+
from = _computeSelectionOffs.from,
|
|
79
|
+
to = _computeSelectionOffs.to;
|
|
80
|
+
(0, _lists.restoreSelection)({
|
|
81
|
+
tr: tr,
|
|
82
|
+
originalSelection: selection,
|
|
83
|
+
from: from,
|
|
84
|
+
to: to
|
|
85
|
+
});
|
|
86
|
+
tr.scrollIntoView();
|
|
87
|
+
return tr;
|
|
88
|
+
}
|
|
@@ -17,9 +17,11 @@ var _utils = require("@atlaskit/editor-common/utils");
|
|
|
17
17
|
var _commands = require("@atlaskit/editor-prosemirror/commands");
|
|
18
18
|
var _keymap = require("@atlaskit/editor-prosemirror/keymap");
|
|
19
19
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
20
|
-
var
|
|
20
|
+
var _state2 = require("@atlaskit/editor-prosemirror/state");
|
|
21
21
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
22
22
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
23
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
24
|
+
var _moveSelectedTaskListItems = require("./actions/move-selected-task-list-items");
|
|
23
25
|
var _commands2 = require("./commands");
|
|
24
26
|
var _helpers = require("./helpers");
|
|
25
27
|
var _insertCommands = require("./insert-commands");
|
|
@@ -106,6 +108,20 @@ var getUnindentCommand = exports.getUnindentCommand = function getUnindentComman
|
|
|
106
108
|
return (0, _utils.filterCommand)(_helpers.isInsideTask, function (state, dispatch) {
|
|
107
109
|
var normalizedSelection = (0, _utils3.normalizeTaskItemsSelection)(state.selection);
|
|
108
110
|
var curIndentLevel = (0, _helpers.getCurrentIndentLevel)(normalizedSelection);
|
|
111
|
+
if ((0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
112
|
+
if (!curIndentLevel) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
var outdentTr = (0, _moveSelectedTaskListItems.moveSelectedTaskListItems)(state.tr, -1);
|
|
116
|
+
if (outdentTr) {
|
|
117
|
+
(0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, _analytics.INDENT_DIRECTION.OUTDENT, inputMethod))(function (_state, d) {
|
|
118
|
+
d === null || d === void 0 || d(outdentTr);
|
|
119
|
+
return true;
|
|
120
|
+
})(state, dispatch);
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
109
125
|
if (!curIndentLevel || curIndentLevel === 1) {
|
|
110
126
|
return false;
|
|
111
127
|
}
|
|
@@ -136,6 +152,20 @@ var getIndentCommand = exports.getIndentCommand = function getIndentCommand(edit
|
|
|
136
152
|
return (0, _utils.filterCommand)(_helpers.isInsideTask, function (state, dispatch) {
|
|
137
153
|
var normalizedSelection = (0, _utils3.normalizeTaskItemsSelection)(state.selection);
|
|
138
154
|
var curIndentLevel = (0, _helpers.getCurrentIndentLevel)(normalizedSelection);
|
|
155
|
+
if ((0, _expValEquals.expValEquals)('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
156
|
+
if (!curIndentLevel) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
var indentTr = (0, _moveSelectedTaskListItems.moveSelectedTaskListItems)(state.tr, 1);
|
|
160
|
+
if (indentTr) {
|
|
161
|
+
(0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, _analytics.INDENT_DIRECTION.INDENT, inputMethod))(function (_state, d) {
|
|
162
|
+
d === null || d === void 0 || d(indentTr);
|
|
163
|
+
return true;
|
|
164
|
+
})(state, dispatch);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
139
169
|
if (!curIndentLevel || curIndentLevel >= 6) {
|
|
140
170
|
return true;
|
|
141
171
|
}
|
|
@@ -379,7 +409,7 @@ var processNestedActionItem = function processNestedActionItem(tr, $from, previo
|
|
|
379
409
|
|
|
380
410
|
// Set custom selection for nested action inside lists using previosuly calculated previousListItem position
|
|
381
411
|
var stableResolvedPos = tr.doc.resolve(previousListItemPos);
|
|
382
|
-
tr.setSelection(
|
|
412
|
+
tr.setSelection(_state2.TextSelection.create(tr.doc, stableResolvedPos.after() + 2));
|
|
383
413
|
};
|
|
384
414
|
var splitListItemWith = function splitListItemWith(tr, content, $from, setSelection) {
|
|
385
415
|
var _frag$firstChild;
|
|
@@ -469,7 +499,7 @@ var splitListItemWith = function splitListItemWith(tr, content, $from, setSelect
|
|
|
469
499
|
if (isGapCursorSelection) {
|
|
470
500
|
tr = tr.setSelection(new _selection.GapCursorSelection(tr.doc.resolve(newPos), _selection.Side.LEFT));
|
|
471
501
|
} else {
|
|
472
|
-
tr = tr.setSelection(new
|
|
502
|
+
tr = tr.setSelection(new _state2.TextSelection(tr.doc.resolve(newPos)));
|
|
473
503
|
}
|
|
474
504
|
}
|
|
475
505
|
|
|
@@ -608,7 +638,7 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
|
|
|
608
638
|
tr.insert(_blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize, _newTaskItem);
|
|
609
639
|
|
|
610
640
|
// Move the cursor to the end of the newly inserted blockTaskItem
|
|
611
|
-
tr.setSelection(
|
|
641
|
+
tr.setSelection(_state2.TextSelection.create(tr.doc, _blockTaskItemNode.pos + _blockTaskItemNode.node.nodeSize + 1));
|
|
612
642
|
return tr;
|
|
613
643
|
}
|
|
614
644
|
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.flattenTaskList = flattenTaskList;
|
|
7
|
+
exports.rebuildTaskList = rebuildTaskList;
|
|
8
|
+
var _adfSchema = require("@atlaskit/adf-schema");
|
|
9
|
+
var _lists = require("@atlaskit/editor-common/lists");
|
|
10
|
+
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; } } }; }
|
|
11
|
+
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; } }
|
|
12
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
13
|
+
/**
|
|
14
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
15
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
16
|
+
*
|
|
17
|
+
* Delegates to the shared `flattenList` with task-list-specific callbacks.
|
|
18
|
+
*/
|
|
19
|
+
function flattenTaskList(options) {
|
|
20
|
+
var _options$doc$type$sch = options.doc.type.schema.nodes,
|
|
21
|
+
taskList = _options$doc$type$sch.taskList,
|
|
22
|
+
taskItem = _options$doc$type$sch.taskItem,
|
|
23
|
+
blockTaskItem = _options$doc$type$sch.blockTaskItem;
|
|
24
|
+
return (0, _lists.flattenList)(options, {
|
|
25
|
+
isContentNode: function isContentNode(node, parent) {
|
|
26
|
+
var isTaskItemType = node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
27
|
+
return isTaskItemType && parent != null && parent.type === taskList;
|
|
28
|
+
},
|
|
29
|
+
getSelectionBounds: function getSelectionBounds(node, pos) {
|
|
30
|
+
return {
|
|
31
|
+
start: pos,
|
|
32
|
+
end: pos + node.nodeSize
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
getDepth: function getDepth(resolvedDepth, rootDepth) {
|
|
36
|
+
return resolvedDepth - rootDepth - 1;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Rebuilds a taskList tree from a flattened array of task items.
|
|
43
|
+
* Uses a stack-based approach to create proper nesting.
|
|
44
|
+
*
|
|
45
|
+
* Preserves original taskList attributes (e.g. localId) for wrappers
|
|
46
|
+
* of unselected items. Only generates fresh UUIDs for newly-created
|
|
47
|
+
* nesting levels (i.e. when items were moved via indent/outdent).
|
|
48
|
+
*
|
|
49
|
+
* Given items with depths [A:0, B:1, C:2, D:1, E:0], produces:
|
|
50
|
+
*
|
|
51
|
+
* taskList
|
|
52
|
+
* taskItem 'A'
|
|
53
|
+
* taskList
|
|
54
|
+
* taskItem 'B'
|
|
55
|
+
* taskList
|
|
56
|
+
* taskItem 'C'
|
|
57
|
+
* taskItem 'D'
|
|
58
|
+
* taskItem 'E'
|
|
59
|
+
*
|
|
60
|
+
* Also computes `contentStartOffsets`: for each item (by index),
|
|
61
|
+
* the offset within the returned fragment where the item's content
|
|
62
|
+
* begins. This is used for accurate selection restoration.
|
|
63
|
+
*/
|
|
64
|
+
function rebuildTaskList(items, schema) {
|
|
65
|
+
var _stack$0$listAttrs;
|
|
66
|
+
var taskList = schema.nodes.taskList;
|
|
67
|
+
var contentStartOffsets = new Array(items.length);
|
|
68
|
+
if (items.length === 0) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Each stack entry collects children for a taskList at a given depth.
|
|
73
|
+
// The root entry (depth -1) is special: its children become the content
|
|
74
|
+
// of the outermost taskList directly (not wrapped in another taskList).
|
|
75
|
+
// Entries at depth >= 0 each produce a nested taskList when popped.
|
|
76
|
+
// listAttrs preserves the original parent's attributes when available.
|
|
77
|
+
// sourceParentAttrs tracks the original parent taskList attrs of the items
|
|
78
|
+
// in this entry, used to decide whether consecutive same-depth items
|
|
79
|
+
// should share a wrapper or be separated.
|
|
80
|
+
|
|
81
|
+
// Start with the root level (depth -1 represents the root taskList wrapper)
|
|
82
|
+
var stack = [{
|
|
83
|
+
depth: -1,
|
|
84
|
+
children: [],
|
|
85
|
+
listAttrs: items[0].parentListAttrs,
|
|
86
|
+
sourceParentAttrs: items[0].parentListAttrs
|
|
87
|
+
}];
|
|
88
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
89
|
+
_step;
|
|
90
|
+
try {
|
|
91
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
92
|
+
var item = _step.value;
|
|
93
|
+
var targetDepth = item.depth;
|
|
94
|
+
|
|
95
|
+
// Pop stack entries strictly deeper than target, wrapping them into taskLists
|
|
96
|
+
while (stack.length > 1 && stack[stack.length - 1].depth > targetDepth) {
|
|
97
|
+
var _popped$listAttrs2;
|
|
98
|
+
var _popped = stack.pop();
|
|
99
|
+
if (!_popped) {
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
var _attrs = (_popped$listAttrs2 = _popped.listAttrs) !== null && _popped$listAttrs2 !== void 0 ? _popped$listAttrs2 : {
|
|
103
|
+
localId: _adfSchema.uuid.generate()
|
|
104
|
+
};
|
|
105
|
+
var _wrappedList = taskList.create(_attrs, _popped.children);
|
|
106
|
+
stack[stack.length - 1].children.push(_wrappedList);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// If the stack top is at the same depth as the target, decide whether
|
|
110
|
+
// to merge into the existing entry or close it and start a new one.
|
|
111
|
+
// Unselected items from different original parent taskLists get
|
|
112
|
+
// separate wrappers (preserving original nesting). Selected (moved)
|
|
113
|
+
// items always merge with whatever is already at the target depth,
|
|
114
|
+
// since they're being placed into a new structural context.
|
|
115
|
+
if (stack.length > 1 && stack[stack.length - 1].depth === targetDepth && !item.isSelected) {
|
|
116
|
+
var top = stack[stack.length - 1];
|
|
117
|
+
if (top.sourceParentAttrs !== item.parentListAttrs) {
|
|
118
|
+
var _popped2$listAttrs;
|
|
119
|
+
var _popped2 = stack.pop();
|
|
120
|
+
if (!_popped2) {
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
var _attrs2 = (_popped2$listAttrs = _popped2.listAttrs) !== null && _popped2$listAttrs !== void 0 ? _popped2$listAttrs : {
|
|
124
|
+
localId: _adfSchema.uuid.generate()
|
|
125
|
+
};
|
|
126
|
+
var _wrappedList2 = taskList.create(_attrs2, _popped2.children);
|
|
127
|
+
stack[stack.length - 1].children.push(_wrappedList2);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Push new stack entries to reach the target depth.
|
|
132
|
+
// Skip intermediate entries at depth 0 — depth-0 items belong
|
|
133
|
+
// directly in the root entry (depth -1), so we only need
|
|
134
|
+
// intermediates for depths > 1.
|
|
135
|
+
while (stack[stack.length - 1].depth < targetDepth - 1) {
|
|
136
|
+
var nextDepth = Math.max(stack[stack.length - 1].depth + 1, 1);
|
|
137
|
+
stack.push({
|
|
138
|
+
depth: nextDepth,
|
|
139
|
+
children: [],
|
|
140
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
141
|
+
sourceParentAttrs: item.parentListAttrs
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Add the item at the target depth
|
|
146
|
+
if (targetDepth === 0) {
|
|
147
|
+
// Depth 0 items go directly into the root taskList
|
|
148
|
+
stack[0].children.push(item.node);
|
|
149
|
+
} else {
|
|
150
|
+
// Ensure there's a stack entry at depth targetDepth to hold this item
|
|
151
|
+
if (stack[stack.length - 1].depth < targetDepth) {
|
|
152
|
+
stack.push({
|
|
153
|
+
depth: targetDepth,
|
|
154
|
+
children: [],
|
|
155
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
156
|
+
sourceParentAttrs: item.parentListAttrs
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
stack[stack.length - 1].children.push(item.node);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Close remaining stack entries
|
|
164
|
+
} catch (err) {
|
|
165
|
+
_iterator.e(err);
|
|
166
|
+
} finally {
|
|
167
|
+
_iterator.f();
|
|
168
|
+
}
|
|
169
|
+
while (stack.length > 1) {
|
|
170
|
+
var _popped$listAttrs;
|
|
171
|
+
var popped = stack.pop();
|
|
172
|
+
if (!popped) {
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
var attrs = (_popped$listAttrs = popped.listAttrs) !== null && _popped$listAttrs !== void 0 ? _popped$listAttrs : {
|
|
176
|
+
localId: _adfSchema.uuid.generate()
|
|
177
|
+
};
|
|
178
|
+
var wrappedList = taskList.create(attrs, popped.children);
|
|
179
|
+
stack[stack.length - 1].children.push(wrappedList);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// The root entry's children form the root taskList.
|
|
183
|
+
// Preserve the root's original attrs when available.
|
|
184
|
+
var rootChildren = stack[0].children;
|
|
185
|
+
var rootAttrs = (_stack$0$listAttrs = stack[0].listAttrs) !== null && _stack$0$listAttrs !== void 0 ? _stack$0$listAttrs : {
|
|
186
|
+
localId: _adfSchema.uuid.generate()
|
|
187
|
+
};
|
|
188
|
+
var rootList = taskList.create(rootAttrs, rootChildren);
|
|
189
|
+
|
|
190
|
+
// Compute contentStartOffsets by walking the rebuilt tree.
|
|
191
|
+
// Each taskItem's content starts at (pos_within_root + 1) for the taskItem opening tag.
|
|
192
|
+
// We add +1 for the root taskList's opening tag.
|
|
193
|
+
var isTaskItemType = function isTaskItemType(node) {
|
|
194
|
+
var _schema$nodes = schema.nodes,
|
|
195
|
+
taskItem = _schema$nodes.taskItem,
|
|
196
|
+
blockTaskItem = _schema$nodes.blockTaskItem;
|
|
197
|
+
return node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
198
|
+
};
|
|
199
|
+
var itemIdx = 0;
|
|
200
|
+
rootList.descendants(function (node, pos) {
|
|
201
|
+
if (isTaskItemType(node) && itemIdx < items.length) {
|
|
202
|
+
// pos is relative to rootList content start;
|
|
203
|
+
// +1 for rootList's opening tag, +1 for taskItem's opening tag
|
|
204
|
+
contentStartOffsets[itemIdx] = 1 + pos + 1;
|
|
205
|
+
itemIdx++;
|
|
206
|
+
}
|
|
207
|
+
return true;
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
node: rootList,
|
|
211
|
+
contentStartOffsets: contentStartOffsets
|
|
212
|
+
};
|
|
213
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { buildReplacementFragment, computeSelectionOffsets, restoreSelection } from '@atlaskit/editor-common/lists';
|
|
2
|
+
import { findFarthestParentNode } from '@atlaskit/editor-common/utils';
|
|
3
|
+
import { flattenTaskList, rebuildTaskList } from '../task-list-indentation';
|
|
4
|
+
const MAX_TASK_LIST_DEPTH = 6;
|
|
5
|
+
export function moveSelectedTaskListItems(tr, indentDelta) {
|
|
6
|
+
const {
|
|
7
|
+
doc,
|
|
8
|
+
selection
|
|
9
|
+
} = tr;
|
|
10
|
+
const {
|
|
11
|
+
schema
|
|
12
|
+
} = doc.type;
|
|
13
|
+
const {
|
|
14
|
+
taskList
|
|
15
|
+
} = schema.nodes;
|
|
16
|
+
const {
|
|
17
|
+
$from,
|
|
18
|
+
$to
|
|
19
|
+
} = selection;
|
|
20
|
+
const rootListResult = findFarthestParentNode(node => node.type === taskList)($from);
|
|
21
|
+
if (!rootListResult) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const rootListStart = rootListResult.pos;
|
|
25
|
+
const rootListEnd = rootListStart + rootListResult.node.nodeSize;
|
|
26
|
+
const flattenResult = flattenTaskList({
|
|
27
|
+
doc,
|
|
28
|
+
rootListStart,
|
|
29
|
+
rootListEnd,
|
|
30
|
+
selectionFrom: $from.pos,
|
|
31
|
+
selectionTo: $to.pos,
|
|
32
|
+
indentDelta,
|
|
33
|
+
maxDepth: MAX_TASK_LIST_DEPTH
|
|
34
|
+
});
|
|
35
|
+
if (!flattenResult) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const {
|
|
39
|
+
items: flattenedItems,
|
|
40
|
+
startIndex,
|
|
41
|
+
endIndex
|
|
42
|
+
} = flattenResult;
|
|
43
|
+
const {
|
|
44
|
+
fragment,
|
|
45
|
+
contentStartOffsets
|
|
46
|
+
} = buildReplacementFragment({
|
|
47
|
+
items: flattenedItems,
|
|
48
|
+
schema,
|
|
49
|
+
rebuildFn: rebuildTaskList,
|
|
50
|
+
extractContentFn: (item, s) => {
|
|
51
|
+
// Extract task item content for breakout.
|
|
52
|
+
// taskItem has inline content, so wrap in a paragraph.
|
|
53
|
+
// blockTaskItem already has paragraph children.
|
|
54
|
+
const {
|
|
55
|
+
blockTaskItem
|
|
56
|
+
} = s.nodes;
|
|
57
|
+
if (blockTaskItem != null && item.node.type === blockTaskItem) {
|
|
58
|
+
// blockTaskItem children are already paragraphs/extensions
|
|
59
|
+
const children = [];
|
|
60
|
+
item.node.forEach(child => children.push(child));
|
|
61
|
+
return children;
|
|
62
|
+
}
|
|
63
|
+
// Regular taskItem — wrap inline content in a paragraph
|
|
64
|
+
return [s.nodes.paragraph.create(null, item.node.content)];
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
if (fragment.size === 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
tr.replaceWith(rootListStart, rootListEnd, fragment);
|
|
71
|
+
const {
|
|
72
|
+
from,
|
|
73
|
+
to
|
|
74
|
+
} = computeSelectionOffsets({
|
|
75
|
+
items: flattenedItems,
|
|
76
|
+
startIndex,
|
|
77
|
+
endIndex,
|
|
78
|
+
originalFrom: $from.pos,
|
|
79
|
+
originalTo: $to.pos,
|
|
80
|
+
contentStartOffsets,
|
|
81
|
+
rootListStart,
|
|
82
|
+
docSize: tr.doc.content.size
|
|
83
|
+
});
|
|
84
|
+
restoreSelection({
|
|
85
|
+
tr,
|
|
86
|
+
originalSelection: selection,
|
|
87
|
+
from,
|
|
88
|
+
to
|
|
89
|
+
});
|
|
90
|
+
tr.scrollIntoView();
|
|
91
|
+
return tr;
|
|
92
|
+
}
|
|
@@ -11,6 +11,8 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
|
11
11
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
12
12
|
import { findParentNodeOfType, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
13
13
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
14
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
15
|
+
import { moveSelectedTaskListItems } from './actions/move-selected-task-list-items';
|
|
14
16
|
import { joinAtCut, liftSelection, wrapSelectionInTaskList } from './commands';
|
|
15
17
|
import { findFirstParentListNode, getBlockRange, getCurrentIndentLevel, getTaskItemIndex, isActionOrDecisionItem, isActionOrDecisionList, isEmptyTaskDecision, isInFirstTextblockOfBlockTaskItem, isInLastTextblockOfBlockTaskItem, isInsideDecision, isInsideTask, isInsideTaskOrDecisionItem, isTable, liftBlock, walkOut } from './helpers';
|
|
16
18
|
import { insertTaskDecisionWithAnalytics } from './insert-commands';
|
|
@@ -89,6 +91,20 @@ const joinTaskDecisionFollowing = (state, dispatch) => {
|
|
|
89
91
|
export const getUnindentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => filter(isInsideTask, (state, dispatch) => {
|
|
90
92
|
const normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
91
93
|
const curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
94
|
+
if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
95
|
+
if (!curIndentLevel) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
const outdentTr = moveSelectedTaskListItems(state.tr, -1);
|
|
99
|
+
if (outdentTr) {
|
|
100
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.OUTDENT, inputMethod))((_state, d) => {
|
|
101
|
+
d === null || d === void 0 ? void 0 : d(outdentTr);
|
|
102
|
+
return true;
|
|
103
|
+
})(state, dispatch);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
92
108
|
if (!curIndentLevel || curIndentLevel === 1) {
|
|
93
109
|
return false;
|
|
94
110
|
}
|
|
@@ -115,6 +131,20 @@ const shouldLetTabThroughInTable = state => {
|
|
|
115
131
|
export const getIndentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => filter(isInsideTask, (state, dispatch) => {
|
|
116
132
|
const normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
117
133
|
const curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
134
|
+
if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
135
|
+
if (!curIndentLevel) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
const indentTr = moveSelectedTaskListItems(state.tr, 1);
|
|
139
|
+
if (indentTr) {
|
|
140
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.INDENT, inputMethod))((_state, d) => {
|
|
141
|
+
d === null || d === void 0 ? void 0 : d(indentTr);
|
|
142
|
+
return true;
|
|
143
|
+
})(state, dispatch);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
118
148
|
if (!curIndentLevel || curIndentLevel >= 6) {
|
|
119
149
|
return true;
|
|
120
150
|
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { uuid } from '@atlaskit/adf-schema';
|
|
2
|
+
import { flattenList as flattenListBase } from '@atlaskit/editor-common/lists';
|
|
3
|
+
/**
|
|
4
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
5
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
6
|
+
*
|
|
7
|
+
* Delegates to the shared `flattenList` with task-list-specific callbacks.
|
|
8
|
+
*/
|
|
9
|
+
export function flattenTaskList(options) {
|
|
10
|
+
const {
|
|
11
|
+
taskList,
|
|
12
|
+
taskItem,
|
|
13
|
+
blockTaskItem
|
|
14
|
+
} = options.doc.type.schema.nodes;
|
|
15
|
+
return flattenListBase(options, {
|
|
16
|
+
isContentNode: (node, parent) => {
|
|
17
|
+
const isTaskItemType = node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
18
|
+
return isTaskItemType && parent != null && parent.type === taskList;
|
|
19
|
+
},
|
|
20
|
+
getSelectionBounds: (node, pos) => ({
|
|
21
|
+
start: pos,
|
|
22
|
+
end: pos + node.nodeSize
|
|
23
|
+
}),
|
|
24
|
+
getDepth: (resolvedDepth, rootDepth) => resolvedDepth - rootDepth - 1
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Rebuilds a taskList tree from a flattened array of task items.
|
|
30
|
+
* Uses a stack-based approach to create proper nesting.
|
|
31
|
+
*
|
|
32
|
+
* Preserves original taskList attributes (e.g. localId) for wrappers
|
|
33
|
+
* of unselected items. Only generates fresh UUIDs for newly-created
|
|
34
|
+
* nesting levels (i.e. when items were moved via indent/outdent).
|
|
35
|
+
*
|
|
36
|
+
* Given items with depths [A:0, B:1, C:2, D:1, E:0], produces:
|
|
37
|
+
*
|
|
38
|
+
* taskList
|
|
39
|
+
* taskItem 'A'
|
|
40
|
+
* taskList
|
|
41
|
+
* taskItem 'B'
|
|
42
|
+
* taskList
|
|
43
|
+
* taskItem 'C'
|
|
44
|
+
* taskItem 'D'
|
|
45
|
+
* taskItem 'E'
|
|
46
|
+
*
|
|
47
|
+
* Also computes `contentStartOffsets`: for each item (by index),
|
|
48
|
+
* the offset within the returned fragment where the item's content
|
|
49
|
+
* begins. This is used for accurate selection restoration.
|
|
50
|
+
*/
|
|
51
|
+
export function rebuildTaskList(items, schema) {
|
|
52
|
+
var _stack$0$listAttrs;
|
|
53
|
+
const {
|
|
54
|
+
taskList
|
|
55
|
+
} = schema.nodes;
|
|
56
|
+
const contentStartOffsets = new Array(items.length);
|
|
57
|
+
if (items.length === 0) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Each stack entry collects children for a taskList at a given depth.
|
|
62
|
+
// The root entry (depth -1) is special: its children become the content
|
|
63
|
+
// of the outermost taskList directly (not wrapped in another taskList).
|
|
64
|
+
// Entries at depth >= 0 each produce a nested taskList when popped.
|
|
65
|
+
// listAttrs preserves the original parent's attributes when available.
|
|
66
|
+
// sourceParentAttrs tracks the original parent taskList attrs of the items
|
|
67
|
+
// in this entry, used to decide whether consecutive same-depth items
|
|
68
|
+
// should share a wrapper or be separated.
|
|
69
|
+
|
|
70
|
+
// Start with the root level (depth -1 represents the root taskList wrapper)
|
|
71
|
+
const stack = [{
|
|
72
|
+
depth: -1,
|
|
73
|
+
children: [],
|
|
74
|
+
listAttrs: items[0].parentListAttrs,
|
|
75
|
+
sourceParentAttrs: items[0].parentListAttrs
|
|
76
|
+
}];
|
|
77
|
+
for (const item of items) {
|
|
78
|
+
const targetDepth = item.depth;
|
|
79
|
+
|
|
80
|
+
// Pop stack entries strictly deeper than target, wrapping them into taskLists
|
|
81
|
+
while (stack.length > 1 && stack[stack.length - 1].depth > targetDepth) {
|
|
82
|
+
var _popped$listAttrs;
|
|
83
|
+
const popped = stack.pop();
|
|
84
|
+
if (!popped) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const attrs = (_popped$listAttrs = popped.listAttrs) !== null && _popped$listAttrs !== void 0 ? _popped$listAttrs : {
|
|
88
|
+
localId: uuid.generate()
|
|
89
|
+
};
|
|
90
|
+
const wrappedList = taskList.create(attrs, popped.children);
|
|
91
|
+
stack[stack.length - 1].children.push(wrappedList);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If the stack top is at the same depth as the target, decide whether
|
|
95
|
+
// to merge into the existing entry or close it and start a new one.
|
|
96
|
+
// Unselected items from different original parent taskLists get
|
|
97
|
+
// separate wrappers (preserving original nesting). Selected (moved)
|
|
98
|
+
// items always merge with whatever is already at the target depth,
|
|
99
|
+
// since they're being placed into a new structural context.
|
|
100
|
+
if (stack.length > 1 && stack[stack.length - 1].depth === targetDepth && !item.isSelected) {
|
|
101
|
+
const top = stack[stack.length - 1];
|
|
102
|
+
if (top.sourceParentAttrs !== item.parentListAttrs) {
|
|
103
|
+
var _popped$listAttrs2;
|
|
104
|
+
const popped = stack.pop();
|
|
105
|
+
if (!popped) {
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
const attrs = (_popped$listAttrs2 = popped.listAttrs) !== null && _popped$listAttrs2 !== void 0 ? _popped$listAttrs2 : {
|
|
109
|
+
localId: uuid.generate()
|
|
110
|
+
};
|
|
111
|
+
const wrappedList = taskList.create(attrs, popped.children);
|
|
112
|
+
stack[stack.length - 1].children.push(wrappedList);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Push new stack entries to reach the target depth.
|
|
117
|
+
// Skip intermediate entries at depth 0 — depth-0 items belong
|
|
118
|
+
// directly in the root entry (depth -1), so we only need
|
|
119
|
+
// intermediates for depths > 1.
|
|
120
|
+
while (stack[stack.length - 1].depth < targetDepth - 1) {
|
|
121
|
+
const nextDepth = Math.max(stack[stack.length - 1].depth + 1, 1);
|
|
122
|
+
stack.push({
|
|
123
|
+
depth: nextDepth,
|
|
124
|
+
children: [],
|
|
125
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
126
|
+
sourceParentAttrs: item.parentListAttrs
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Add the item at the target depth
|
|
131
|
+
if (targetDepth === 0) {
|
|
132
|
+
// Depth 0 items go directly into the root taskList
|
|
133
|
+
stack[0].children.push(item.node);
|
|
134
|
+
} else {
|
|
135
|
+
// Ensure there's a stack entry at depth targetDepth to hold this item
|
|
136
|
+
if (stack[stack.length - 1].depth < targetDepth) {
|
|
137
|
+
stack.push({
|
|
138
|
+
depth: targetDepth,
|
|
139
|
+
children: [],
|
|
140
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
141
|
+
sourceParentAttrs: item.parentListAttrs
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
stack[stack.length - 1].children.push(item.node);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Close remaining stack entries
|
|
149
|
+
while (stack.length > 1) {
|
|
150
|
+
var _popped$listAttrs3;
|
|
151
|
+
const popped = stack.pop();
|
|
152
|
+
if (!popped) {
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
const attrs = (_popped$listAttrs3 = popped.listAttrs) !== null && _popped$listAttrs3 !== void 0 ? _popped$listAttrs3 : {
|
|
156
|
+
localId: uuid.generate()
|
|
157
|
+
};
|
|
158
|
+
const wrappedList = taskList.create(attrs, popped.children);
|
|
159
|
+
stack[stack.length - 1].children.push(wrappedList);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// The root entry's children form the root taskList.
|
|
163
|
+
// Preserve the root's original attrs when available.
|
|
164
|
+
const rootChildren = stack[0].children;
|
|
165
|
+
const rootAttrs = (_stack$0$listAttrs = stack[0].listAttrs) !== null && _stack$0$listAttrs !== void 0 ? _stack$0$listAttrs : {
|
|
166
|
+
localId: uuid.generate()
|
|
167
|
+
};
|
|
168
|
+
const rootList = taskList.create(rootAttrs, rootChildren);
|
|
169
|
+
|
|
170
|
+
// Compute contentStartOffsets by walking the rebuilt tree.
|
|
171
|
+
// Each taskItem's content starts at (pos_within_root + 1) for the taskItem opening tag.
|
|
172
|
+
// We add +1 for the root taskList's opening tag.
|
|
173
|
+
const isTaskItemType = node => {
|
|
174
|
+
const {
|
|
175
|
+
taskItem,
|
|
176
|
+
blockTaskItem
|
|
177
|
+
} = schema.nodes;
|
|
178
|
+
return node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
179
|
+
};
|
|
180
|
+
let itemIdx = 0;
|
|
181
|
+
rootList.descendants((node, pos) => {
|
|
182
|
+
if (isTaskItemType(node) && itemIdx < items.length) {
|
|
183
|
+
// pos is relative to rootList content start;
|
|
184
|
+
// +1 for rootList's opening tag, +1 for taskItem's opening tag
|
|
185
|
+
contentStartOffsets[itemIdx] = 1 + pos + 1;
|
|
186
|
+
itemIdx++;
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
node: rootList,
|
|
192
|
+
contentStartOffsets
|
|
193
|
+
};
|
|
194
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { buildReplacementFragment, computeSelectionOffsets, restoreSelection } from '@atlaskit/editor-common/lists';
|
|
2
|
+
import { findFarthestParentNode } from '@atlaskit/editor-common/utils';
|
|
3
|
+
import { flattenTaskList, rebuildTaskList } from '../task-list-indentation';
|
|
4
|
+
var MAX_TASK_LIST_DEPTH = 6;
|
|
5
|
+
export function moveSelectedTaskListItems(tr, indentDelta) {
|
|
6
|
+
var doc = tr.doc,
|
|
7
|
+
selection = tr.selection;
|
|
8
|
+
var schema = doc.type.schema;
|
|
9
|
+
var taskList = schema.nodes.taskList;
|
|
10
|
+
var $from = selection.$from,
|
|
11
|
+
$to = selection.$to;
|
|
12
|
+
var rootListResult = findFarthestParentNode(function (node) {
|
|
13
|
+
return node.type === taskList;
|
|
14
|
+
})($from);
|
|
15
|
+
if (!rootListResult) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
var rootListStart = rootListResult.pos;
|
|
19
|
+
var rootListEnd = rootListStart + rootListResult.node.nodeSize;
|
|
20
|
+
var flattenResult = flattenTaskList({
|
|
21
|
+
doc: doc,
|
|
22
|
+
rootListStart: rootListStart,
|
|
23
|
+
rootListEnd: rootListEnd,
|
|
24
|
+
selectionFrom: $from.pos,
|
|
25
|
+
selectionTo: $to.pos,
|
|
26
|
+
indentDelta: indentDelta,
|
|
27
|
+
maxDepth: MAX_TASK_LIST_DEPTH
|
|
28
|
+
});
|
|
29
|
+
if (!flattenResult) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
var flattenedItems = flattenResult.items,
|
|
33
|
+
startIndex = flattenResult.startIndex,
|
|
34
|
+
endIndex = flattenResult.endIndex;
|
|
35
|
+
var _buildReplacementFrag = buildReplacementFragment({
|
|
36
|
+
items: flattenedItems,
|
|
37
|
+
schema: schema,
|
|
38
|
+
rebuildFn: rebuildTaskList,
|
|
39
|
+
extractContentFn: function extractContentFn(item, s) {
|
|
40
|
+
// Extract task item content for breakout.
|
|
41
|
+
// taskItem has inline content, so wrap in a paragraph.
|
|
42
|
+
// blockTaskItem already has paragraph children.
|
|
43
|
+
var blockTaskItem = s.nodes.blockTaskItem;
|
|
44
|
+
if (blockTaskItem != null && item.node.type === blockTaskItem) {
|
|
45
|
+
// blockTaskItem children are already paragraphs/extensions
|
|
46
|
+
var children = [];
|
|
47
|
+
item.node.forEach(function (child) {
|
|
48
|
+
return children.push(child);
|
|
49
|
+
});
|
|
50
|
+
return children;
|
|
51
|
+
}
|
|
52
|
+
// Regular taskItem — wrap inline content in a paragraph
|
|
53
|
+
return [s.nodes.paragraph.create(null, item.node.content)];
|
|
54
|
+
}
|
|
55
|
+
}),
|
|
56
|
+
fragment = _buildReplacementFrag.fragment,
|
|
57
|
+
contentStartOffsets = _buildReplacementFrag.contentStartOffsets;
|
|
58
|
+
if (fragment.size === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
tr.replaceWith(rootListStart, rootListEnd, fragment);
|
|
62
|
+
var _computeSelectionOffs = computeSelectionOffsets({
|
|
63
|
+
items: flattenedItems,
|
|
64
|
+
startIndex: startIndex,
|
|
65
|
+
endIndex: endIndex,
|
|
66
|
+
originalFrom: $from.pos,
|
|
67
|
+
originalTo: $to.pos,
|
|
68
|
+
contentStartOffsets: contentStartOffsets,
|
|
69
|
+
rootListStart: rootListStart,
|
|
70
|
+
docSize: tr.doc.content.size
|
|
71
|
+
}),
|
|
72
|
+
from = _computeSelectionOffs.from,
|
|
73
|
+
to = _computeSelectionOffs.to;
|
|
74
|
+
restoreSelection({
|
|
75
|
+
tr: tr,
|
|
76
|
+
originalSelection: selection,
|
|
77
|
+
from: from,
|
|
78
|
+
to: to
|
|
79
|
+
});
|
|
80
|
+
tr.scrollIntoView();
|
|
81
|
+
return tr;
|
|
82
|
+
}
|
|
@@ -14,6 +14,8 @@ import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
|
14
14
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
15
15
|
import { findParentNodeOfType, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
16
16
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
17
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
18
|
+
import { moveSelectedTaskListItems } from './actions/move-selected-task-list-items';
|
|
17
19
|
import { joinAtCut, liftSelection, wrapSelectionInTaskList } from './commands';
|
|
18
20
|
import { findFirstParentListNode, getBlockRange, getCurrentIndentLevel, getTaskItemIndex, isActionOrDecisionItem, isActionOrDecisionList, isEmptyTaskDecision, isInFirstTextblockOfBlockTaskItem, isInLastTextblockOfBlockTaskItem, isInsideDecision, isInsideTask, isInsideTaskOrDecisionItem, isTable, liftBlock, walkOut } from './helpers';
|
|
19
21
|
import { insertTaskDecisionWithAnalytics } from './insert-commands';
|
|
@@ -98,6 +100,20 @@ export var getUnindentCommand = function getUnindentCommand(editorAnalyticsAPI)
|
|
|
98
100
|
return filter(isInsideTask, function (state, dispatch) {
|
|
99
101
|
var normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
100
102
|
var curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
103
|
+
if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
104
|
+
if (!curIndentLevel) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
var outdentTr = moveSelectedTaskListItems(state.tr, -1);
|
|
108
|
+
if (outdentTr) {
|
|
109
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.OUTDENT, inputMethod))(function (_state, d) {
|
|
110
|
+
d === null || d === void 0 || d(outdentTr);
|
|
111
|
+
return true;
|
|
112
|
+
})(state, dispatch);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
101
117
|
if (!curIndentLevel || curIndentLevel === 1) {
|
|
102
118
|
return false;
|
|
103
119
|
}
|
|
@@ -128,6 +144,20 @@ export var getIndentCommand = function getIndentCommand(editorAnalyticsAPI) {
|
|
|
128
144
|
return filter(isInsideTask, function (state, dispatch) {
|
|
129
145
|
var normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
130
146
|
var curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
147
|
+
if (expValEquals('platform_editor_flexible_list_indentation', 'isEnabled', true)) {
|
|
148
|
+
if (!curIndentLevel) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
var indentTr = moveSelectedTaskListItems(state.tr, 1);
|
|
152
|
+
if (indentTr) {
|
|
153
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.INDENT, inputMethod))(function (_state, d) {
|
|
154
|
+
d === null || d === void 0 || d(indentTr);
|
|
155
|
+
return true;
|
|
156
|
+
})(state, dispatch);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
131
161
|
if (!curIndentLevel || curIndentLevel >= 6) {
|
|
132
162
|
return true;
|
|
133
163
|
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
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; } } }; }
|
|
2
|
+
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; } }
|
|
3
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
4
|
+
import { uuid } from '@atlaskit/adf-schema';
|
|
5
|
+
import { flattenList as flattenListBase } from '@atlaskit/editor-common/lists';
|
|
6
|
+
/**
|
|
7
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
8
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
9
|
+
*
|
|
10
|
+
* Delegates to the shared `flattenList` with task-list-specific callbacks.
|
|
11
|
+
*/
|
|
12
|
+
export function flattenTaskList(options) {
|
|
13
|
+
var _options$doc$type$sch = options.doc.type.schema.nodes,
|
|
14
|
+
taskList = _options$doc$type$sch.taskList,
|
|
15
|
+
taskItem = _options$doc$type$sch.taskItem,
|
|
16
|
+
blockTaskItem = _options$doc$type$sch.blockTaskItem;
|
|
17
|
+
return flattenListBase(options, {
|
|
18
|
+
isContentNode: function isContentNode(node, parent) {
|
|
19
|
+
var isTaskItemType = node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
20
|
+
return isTaskItemType && parent != null && parent.type === taskList;
|
|
21
|
+
},
|
|
22
|
+
getSelectionBounds: function getSelectionBounds(node, pos) {
|
|
23
|
+
return {
|
|
24
|
+
start: pos,
|
|
25
|
+
end: pos + node.nodeSize
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
getDepth: function getDepth(resolvedDepth, rootDepth) {
|
|
29
|
+
return resolvedDepth - rootDepth - 1;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Rebuilds a taskList tree from a flattened array of task items.
|
|
36
|
+
* Uses a stack-based approach to create proper nesting.
|
|
37
|
+
*
|
|
38
|
+
* Preserves original taskList attributes (e.g. localId) for wrappers
|
|
39
|
+
* of unselected items. Only generates fresh UUIDs for newly-created
|
|
40
|
+
* nesting levels (i.e. when items were moved via indent/outdent).
|
|
41
|
+
*
|
|
42
|
+
* Given items with depths [A:0, B:1, C:2, D:1, E:0], produces:
|
|
43
|
+
*
|
|
44
|
+
* taskList
|
|
45
|
+
* taskItem 'A'
|
|
46
|
+
* taskList
|
|
47
|
+
* taskItem 'B'
|
|
48
|
+
* taskList
|
|
49
|
+
* taskItem 'C'
|
|
50
|
+
* taskItem 'D'
|
|
51
|
+
* taskItem 'E'
|
|
52
|
+
*
|
|
53
|
+
* Also computes `contentStartOffsets`: for each item (by index),
|
|
54
|
+
* the offset within the returned fragment where the item's content
|
|
55
|
+
* begins. This is used for accurate selection restoration.
|
|
56
|
+
*/
|
|
57
|
+
export function rebuildTaskList(items, schema) {
|
|
58
|
+
var _stack$0$listAttrs;
|
|
59
|
+
var taskList = schema.nodes.taskList;
|
|
60
|
+
var contentStartOffsets = new Array(items.length);
|
|
61
|
+
if (items.length === 0) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Each stack entry collects children for a taskList at a given depth.
|
|
66
|
+
// The root entry (depth -1) is special: its children become the content
|
|
67
|
+
// of the outermost taskList directly (not wrapped in another taskList).
|
|
68
|
+
// Entries at depth >= 0 each produce a nested taskList when popped.
|
|
69
|
+
// listAttrs preserves the original parent's attributes when available.
|
|
70
|
+
// sourceParentAttrs tracks the original parent taskList attrs of the items
|
|
71
|
+
// in this entry, used to decide whether consecutive same-depth items
|
|
72
|
+
// should share a wrapper or be separated.
|
|
73
|
+
|
|
74
|
+
// Start with the root level (depth -1 represents the root taskList wrapper)
|
|
75
|
+
var stack = [{
|
|
76
|
+
depth: -1,
|
|
77
|
+
children: [],
|
|
78
|
+
listAttrs: items[0].parentListAttrs,
|
|
79
|
+
sourceParentAttrs: items[0].parentListAttrs
|
|
80
|
+
}];
|
|
81
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
82
|
+
_step;
|
|
83
|
+
try {
|
|
84
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
85
|
+
var item = _step.value;
|
|
86
|
+
var targetDepth = item.depth;
|
|
87
|
+
|
|
88
|
+
// Pop stack entries strictly deeper than target, wrapping them into taskLists
|
|
89
|
+
while (stack.length > 1 && stack[stack.length - 1].depth > targetDepth) {
|
|
90
|
+
var _popped$listAttrs2;
|
|
91
|
+
var _popped = stack.pop();
|
|
92
|
+
if (!_popped) {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
var _attrs = (_popped$listAttrs2 = _popped.listAttrs) !== null && _popped$listAttrs2 !== void 0 ? _popped$listAttrs2 : {
|
|
96
|
+
localId: uuid.generate()
|
|
97
|
+
};
|
|
98
|
+
var _wrappedList = taskList.create(_attrs, _popped.children);
|
|
99
|
+
stack[stack.length - 1].children.push(_wrappedList);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// If the stack top is at the same depth as the target, decide whether
|
|
103
|
+
// to merge into the existing entry or close it and start a new one.
|
|
104
|
+
// Unselected items from different original parent taskLists get
|
|
105
|
+
// separate wrappers (preserving original nesting). Selected (moved)
|
|
106
|
+
// items always merge with whatever is already at the target depth,
|
|
107
|
+
// since they're being placed into a new structural context.
|
|
108
|
+
if (stack.length > 1 && stack[stack.length - 1].depth === targetDepth && !item.isSelected) {
|
|
109
|
+
var top = stack[stack.length - 1];
|
|
110
|
+
if (top.sourceParentAttrs !== item.parentListAttrs) {
|
|
111
|
+
var _popped2$listAttrs;
|
|
112
|
+
var _popped2 = stack.pop();
|
|
113
|
+
if (!_popped2) {
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
var _attrs2 = (_popped2$listAttrs = _popped2.listAttrs) !== null && _popped2$listAttrs !== void 0 ? _popped2$listAttrs : {
|
|
117
|
+
localId: uuid.generate()
|
|
118
|
+
};
|
|
119
|
+
var _wrappedList2 = taskList.create(_attrs2, _popped2.children);
|
|
120
|
+
stack[stack.length - 1].children.push(_wrappedList2);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Push new stack entries to reach the target depth.
|
|
125
|
+
// Skip intermediate entries at depth 0 — depth-0 items belong
|
|
126
|
+
// directly in the root entry (depth -1), so we only need
|
|
127
|
+
// intermediates for depths > 1.
|
|
128
|
+
while (stack[stack.length - 1].depth < targetDepth - 1) {
|
|
129
|
+
var nextDepth = Math.max(stack[stack.length - 1].depth + 1, 1);
|
|
130
|
+
stack.push({
|
|
131
|
+
depth: nextDepth,
|
|
132
|
+
children: [],
|
|
133
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
134
|
+
sourceParentAttrs: item.parentListAttrs
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Add the item at the target depth
|
|
139
|
+
if (targetDepth === 0) {
|
|
140
|
+
// Depth 0 items go directly into the root taskList
|
|
141
|
+
stack[0].children.push(item.node);
|
|
142
|
+
} else {
|
|
143
|
+
// Ensure there's a stack entry at depth targetDepth to hold this item
|
|
144
|
+
if (stack[stack.length - 1].depth < targetDepth) {
|
|
145
|
+
stack.push({
|
|
146
|
+
depth: targetDepth,
|
|
147
|
+
children: [],
|
|
148
|
+
listAttrs: item.isSelected ? null : item.parentListAttrs,
|
|
149
|
+
sourceParentAttrs: item.parentListAttrs
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
stack[stack.length - 1].children.push(item.node);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Close remaining stack entries
|
|
157
|
+
} catch (err) {
|
|
158
|
+
_iterator.e(err);
|
|
159
|
+
} finally {
|
|
160
|
+
_iterator.f();
|
|
161
|
+
}
|
|
162
|
+
while (stack.length > 1) {
|
|
163
|
+
var _popped$listAttrs;
|
|
164
|
+
var popped = stack.pop();
|
|
165
|
+
if (!popped) {
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
var attrs = (_popped$listAttrs = popped.listAttrs) !== null && _popped$listAttrs !== void 0 ? _popped$listAttrs : {
|
|
169
|
+
localId: uuid.generate()
|
|
170
|
+
};
|
|
171
|
+
var wrappedList = taskList.create(attrs, popped.children);
|
|
172
|
+
stack[stack.length - 1].children.push(wrappedList);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// The root entry's children form the root taskList.
|
|
176
|
+
// Preserve the root's original attrs when available.
|
|
177
|
+
var rootChildren = stack[0].children;
|
|
178
|
+
var rootAttrs = (_stack$0$listAttrs = stack[0].listAttrs) !== null && _stack$0$listAttrs !== void 0 ? _stack$0$listAttrs : {
|
|
179
|
+
localId: uuid.generate()
|
|
180
|
+
};
|
|
181
|
+
var rootList = taskList.create(rootAttrs, rootChildren);
|
|
182
|
+
|
|
183
|
+
// Compute contentStartOffsets by walking the rebuilt tree.
|
|
184
|
+
// Each taskItem's content starts at (pos_within_root + 1) for the taskItem opening tag.
|
|
185
|
+
// We add +1 for the root taskList's opening tag.
|
|
186
|
+
var isTaskItemType = function isTaskItemType(node) {
|
|
187
|
+
var _schema$nodes = schema.nodes,
|
|
188
|
+
taskItem = _schema$nodes.taskItem,
|
|
189
|
+
blockTaskItem = _schema$nodes.blockTaskItem;
|
|
190
|
+
return node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
191
|
+
};
|
|
192
|
+
var itemIdx = 0;
|
|
193
|
+
rootList.descendants(function (node, pos) {
|
|
194
|
+
if (isTaskItemType(node) && itemIdx < items.length) {
|
|
195
|
+
// pos is relative to rootList content start;
|
|
196
|
+
// +1 for rootList's opening tag, +1 for taskItem's opening tag
|
|
197
|
+
contentStartOffsets[itemIdx] = 1 + pos + 1;
|
|
198
|
+
itemIdx++;
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
});
|
|
202
|
+
return {
|
|
203
|
+
node: rootList,
|
|
204
|
+
contentStartOffsets: contentStartOffsets
|
|
205
|
+
};
|
|
206
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type FlattenedItem, type FlattenListOptions, type FlattenListResult } from '@atlaskit/editor-common/lists';
|
|
2
|
+
import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
5
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
6
|
+
*
|
|
7
|
+
* Delegates to the shared `flattenList` with task-list-specific callbacks.
|
|
8
|
+
*/
|
|
9
|
+
export declare function flattenTaskList(options: FlattenListOptions): FlattenListResult | null;
|
|
10
|
+
/**
|
|
11
|
+
* Rebuilds a taskList tree from a flattened array of task items.
|
|
12
|
+
* Uses a stack-based approach to create proper nesting.
|
|
13
|
+
*
|
|
14
|
+
* Preserves original taskList attributes (e.g. localId) for wrappers
|
|
15
|
+
* of unselected items. Only generates fresh UUIDs for newly-created
|
|
16
|
+
* nesting levels (i.e. when items were moved via indent/outdent).
|
|
17
|
+
*
|
|
18
|
+
* Given items with depths [A:0, B:1, C:2, D:1, E:0], produces:
|
|
19
|
+
*
|
|
20
|
+
* taskList
|
|
21
|
+
* taskItem 'A'
|
|
22
|
+
* taskList
|
|
23
|
+
* taskItem 'B'
|
|
24
|
+
* taskList
|
|
25
|
+
* taskItem 'C'
|
|
26
|
+
* taskItem 'D'
|
|
27
|
+
* taskItem 'E'
|
|
28
|
+
*
|
|
29
|
+
* Also computes `contentStartOffsets`: for each item (by index),
|
|
30
|
+
* the offset within the returned fragment where the item's content
|
|
31
|
+
* begins. This is used for accurate selection restoration.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rebuildTaskList(items: FlattenedItem[], schema: Schema): {
|
|
34
|
+
contentStartOffsets: number[];
|
|
35
|
+
node: PMNode;
|
|
36
|
+
} | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type FlattenedItem, type FlattenListOptions, type FlattenListResult } from '@atlaskit/editor-common/lists';
|
|
2
|
+
import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
5
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
6
|
+
*
|
|
7
|
+
* Delegates to the shared `flattenList` with task-list-specific callbacks.
|
|
8
|
+
*/
|
|
9
|
+
export declare function flattenTaskList(options: FlattenListOptions): FlattenListResult | null;
|
|
10
|
+
/**
|
|
11
|
+
* Rebuilds a taskList tree from a flattened array of task items.
|
|
12
|
+
* Uses a stack-based approach to create proper nesting.
|
|
13
|
+
*
|
|
14
|
+
* Preserves original taskList attributes (e.g. localId) for wrappers
|
|
15
|
+
* of unselected items. Only generates fresh UUIDs for newly-created
|
|
16
|
+
* nesting levels (i.e. when items were moved via indent/outdent).
|
|
17
|
+
*
|
|
18
|
+
* Given items with depths [A:0, B:1, C:2, D:1, E:0], produces:
|
|
19
|
+
*
|
|
20
|
+
* taskList
|
|
21
|
+
* taskItem 'A'
|
|
22
|
+
* taskList
|
|
23
|
+
* taskItem 'B'
|
|
24
|
+
* taskList
|
|
25
|
+
* taskItem 'C'
|
|
26
|
+
* taskItem 'D'
|
|
27
|
+
* taskItem 'E'
|
|
28
|
+
*
|
|
29
|
+
* Also computes `contentStartOffsets`: for each item (by index),
|
|
30
|
+
* the offset within the returned fragment where the item's content
|
|
31
|
+
* begins. This is used for accurate selection restoration.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rebuildTaskList(items: FlattenedItem[], schema: Schema): {
|
|
34
|
+
contentStartOffsets: number[];
|
|
35
|
+
node: PMNode;
|
|
36
|
+
} | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-tasks-and-decisions",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.3.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.0.0",
|
|
50
50
|
"@atlaskit/prosemirror-input-rules": "^3.6.0",
|
|
51
51
|
"@atlaskit/task-decision": "^19.3.0",
|
|
52
|
-
"@atlaskit/tmp-editor-statsig": "^44.
|
|
52
|
+
"@atlaskit/tmp-editor-statsig": "^44.1.0",
|
|
53
53
|
"@atlaskit/tokens": "^11.1.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.
|
|
59
|
+
"@atlaskit/editor-common": "^112.8.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"
|