@atlaskit/editor-plugin-tasks-and-decisions 21.0.11 → 22.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/cjs/pm-plugins/commands.js +1 -74
- package/dist/cjs/pm-plugins/helpers.js +1 -51
- package/dist/cjs/pm-plugins/keymaps.js +25 -39
- package/dist/cjs/pm-plugins/main.js +0 -20
- package/dist/cjs/pm-plugins/task-list-indentation.js +3 -34
- package/dist/cjs/tasksAndDecisionsPlugin.js +44 -51
- package/dist/es2019/pm-plugins/commands.js +2 -80
- package/dist/es2019/pm-plugins/helpers.js +0 -48
- package/dist/es2019/pm-plugins/keymaps.js +28 -42
- package/dist/es2019/pm-plugins/main.js +0 -18
- package/dist/es2019/pm-plugins/task-list-indentation.js +3 -32
- package/dist/es2019/tasksAndDecisionsPlugin.js +45 -52
- package/dist/esm/pm-plugins/commands.js +2 -74
- package/dist/esm/pm-plugins/helpers.js +0 -50
- package/dist/esm/pm-plugins/keymaps.js +26 -40
- package/dist/esm/pm-plugins/main.js +0 -20
- package/dist/esm/pm-plugins/task-list-indentation.js +3 -35
- package/dist/esm/tasksAndDecisionsPlugin.js +45 -52
- package/dist/types/pm-plugins/commands.d.ts +0 -19
- package/dist/types/pm-plugins/helpers.d.ts +1 -14
- package/package.json +12 -15
- package/dist/cjs/pm-plugins/transforms.js +0 -150
- package/dist/es2019/pm-plugins/transforms.js +0 -104
- package/dist/esm/pm-plugins/transforms.js +0 -143
- package/dist/types/pm-plugins/transforms.d.ts +0 -10
|
@@ -11,9 +11,8 @@ import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
|
11
11
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
12
12
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
13
13
|
import { findParentNodeOfType, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
14
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
15
14
|
import { moveSelectedTaskListItems } from './actions/move-selected-task-list-items';
|
|
16
|
-
import { joinAtCut
|
|
15
|
+
import { joinAtCut } from './commands';
|
|
17
16
|
import { findFirstParentListNode, getBlockRange, getCurrentIndentLevel, getTaskItemIndex, isActionOrDecisionItem, isActionOrDecisionList, isEmptyTaskDecision, isInFirstTextblockOfBlockTaskItem, isInLastTextblockOfBlockTaskItem, isInsideDecision, isInsideTask, isInsideTaskOrDecisionItem, isTable, liftBlock, walkOut } from './helpers';
|
|
18
17
|
import { insertTaskDecisionWithAnalytics } from './insert-commands';
|
|
19
18
|
import { toggleTaskList } from './toggle-tasklist-commands';
|
|
@@ -91,24 +90,18 @@ const joinTaskDecisionFollowing = (state, dispatch) => {
|
|
|
91
90
|
export const getUnindentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => filter(isInsideTask, (state, dispatch) => {
|
|
92
91
|
const normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
93
92
|
const curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
94
|
-
if (
|
|
95
|
-
|
|
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;
|
|
93
|
+
if (!curIndentLevel) {
|
|
94
|
+
return true;
|
|
107
95
|
}
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
const outdentTr = moveSelectedTaskListItems(state.tr, -1);
|
|
97
|
+
if (outdentTr) {
|
|
98
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.OUTDENT, inputMethod))((_state, d) => {
|
|
99
|
+
d === null || d === void 0 ? void 0 : d(outdentTr);
|
|
100
|
+
return true;
|
|
101
|
+
})(state, dispatch);
|
|
102
|
+
return true;
|
|
110
103
|
}
|
|
111
|
-
return
|
|
104
|
+
return false;
|
|
112
105
|
});
|
|
113
106
|
|
|
114
107
|
// if selection is decision item or first action item in table cell
|
|
@@ -131,24 +124,18 @@ const shouldLetTabThroughInTable = state => {
|
|
|
131
124
|
export const getIndentCommand = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD) => filter(isInsideTask, (state, dispatch) => {
|
|
132
125
|
const normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
133
126
|
const curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
134
|
-
if (
|
|
135
|
-
|
|
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;
|
|
127
|
+
if (!curIndentLevel) {
|
|
128
|
+
return true;
|
|
147
129
|
}
|
|
148
|
-
|
|
130
|
+
const indentTr = moveSelectedTaskListItems(state.tr, 1);
|
|
131
|
+
if (indentTr) {
|
|
132
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.INDENT, inputMethod))((_state, d) => {
|
|
133
|
+
d === null || d === void 0 ? void 0 : d(indentTr);
|
|
134
|
+
return true;
|
|
135
|
+
})(state, dispatch);
|
|
149
136
|
return true;
|
|
150
137
|
}
|
|
151
|
-
return
|
|
138
|
+
return false;
|
|
152
139
|
});
|
|
153
140
|
const backspaceFrom = editorAnalyticsAPI => $from => (state, dispatch) => {
|
|
154
141
|
var _nodeBefore$firstChil, _nodeBefore$firstChil2, _nodeBefore$firstChil3;
|
|
@@ -602,15 +589,14 @@ const enter = (editorAnalyticsAPI, getContextIdentifier) => filter(isInsideTaskO
|
|
|
602
589
|
tr.insert(insertPos, newTask);
|
|
603
590
|
// Place cursor on the newly inserted empty task item above
|
|
604
591
|
// when nested inside another taskList.
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}
|
|
592
|
+
|
|
593
|
+
const {
|
|
594
|
+
taskList: taskListType
|
|
595
|
+
} = schema.nodes;
|
|
596
|
+
const parentTaskList = $from.node($from.depth - 1);
|
|
597
|
+
const grandparent = $from.depth >= 3 ? $from.node($from.depth - 2) : null;
|
|
598
|
+
if ((parentTaskList === null || parentTaskList === void 0 ? void 0 : parentTaskList.type) === taskListType && (grandparent === null || grandparent === void 0 ? void 0 : grandparent.type) === taskListType) {
|
|
599
|
+
tr.setSelection(TextSelection.create(tr.doc, insertPos + 1));
|
|
614
600
|
}
|
|
615
601
|
return tr;
|
|
616
602
|
}
|
|
@@ -6,14 +6,12 @@ import { getStepRange } from '@atlaskit/editor-common/utils';
|
|
|
6
6
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
7
7
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
|
-
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
10
9
|
import { DecisionItemNodeView } from '../nodeviews/DecisionItemNodeView';
|
|
11
10
|
import { taskView } from '../nodeviews/task-node-view';
|
|
12
11
|
import { focusTaskDecision, openRequestEditPopup, setProvider } from './actions';
|
|
13
12
|
import { focusCheckbox, focusCheckboxAndUpdateSelection, getTaskItemDataAtPos, getTaskItemDataToFocus, isInsideTask, removeCheckboxFocus } from './helpers';
|
|
14
13
|
import { stateKey } from './plugin-key';
|
|
15
14
|
import { taskItemOnChange } from './taskItemOnChange';
|
|
16
|
-
import { applyTaskListNormalisationFixes } from './transforms';
|
|
17
15
|
import { ACTIONS } from './types';
|
|
18
16
|
import { tempTransformSliceToRemoveBlockTaskItem } from './utils/paste';
|
|
19
17
|
function nodesBetweenChanged(tr, f, startPos) {
|
|
@@ -266,22 +264,6 @@ export function createPlugin(portalProviderAPI, eventDispatcher, dispatch, api,
|
|
|
266
264
|
* Note: we currently do not handle the edge case where two nodes may have the same localId
|
|
267
265
|
*/
|
|
268
266
|
appendTransaction: (transactions, _oldState, newState) => {
|
|
269
|
-
// Normalise taskList structure first — runs on its own transaction (without addToHistory: false)
|
|
270
|
-
// so it is included in history and correctly undone with the triggering operation.
|
|
271
|
-
if (expValEqualsNoExposure('platform_editor_flexible_list_schema', 'isEnabled', true) && transactions.some(t => t.docChanged)) {
|
|
272
|
-
const normTr = applyTaskListNormalisationFixes({
|
|
273
|
-
tr: newState.tr,
|
|
274
|
-
transactions,
|
|
275
|
-
doc: newState.doc,
|
|
276
|
-
schema: newState.schema
|
|
277
|
-
});
|
|
278
|
-
if (normTr.docChanged) {
|
|
279
|
-
// Return the normalisation transaction — the next appendTransaction call will
|
|
280
|
-
// assign any missing localIds to newly inserted nodes via the localId path below.
|
|
281
|
-
return normTr;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
267
|
// Assign unique localIds to any new nodes that don't have one.
|
|
286
268
|
// Runs with addToHistory: false so localId assignment is not part of the undo history.
|
|
287
269
|
const tr = newState.tr;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { uuid } from '@atlaskit/adf-schema/uuid';
|
|
2
|
-
import { flattenList as flattenListBase } from '@atlaskit/editor-common/lists';
|
|
3
|
-
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
|
-
|
|
5
2
|
/**
|
|
6
|
-
* Flattens a taskList into
|
|
7
|
-
*
|
|
3
|
+
* Flattens a taskList tree into an array of task items with computed depths.
|
|
4
|
+
* Only selected items have their depth adjusted by indentDelta.
|
|
8
5
|
*/
|
|
9
|
-
function
|
|
6
|
+
export function flattenTaskList(options) {
|
|
10
7
|
const {
|
|
11
8
|
doc,
|
|
12
9
|
rootListStart,
|
|
@@ -66,32 +63,6 @@ function flattenTaskListImpl(options) {
|
|
|
66
63
|
};
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
/**
|
|
70
|
-
* Flattens a taskList tree into an array of task items with computed depths.
|
|
71
|
-
* Only selected items have their depth adjusted by indentDelta.
|
|
72
|
-
*/
|
|
73
|
-
export function flattenTaskList(options) {
|
|
74
|
-
if (fg('platform_editor_flexible_list_normalization_fix')) {
|
|
75
|
-
return flattenTaskListImpl(options);
|
|
76
|
-
}
|
|
77
|
-
const {
|
|
78
|
-
taskList,
|
|
79
|
-
taskItem,
|
|
80
|
-
blockTaskItem
|
|
81
|
-
} = options.doc.type.schema.nodes;
|
|
82
|
-
return flattenListBase(options, {
|
|
83
|
-
isContentNode: (node, parent) => {
|
|
84
|
-
const isTaskItemType = node.type === taskItem || blockTaskItem != null && node.type === blockTaskItem;
|
|
85
|
-
return isTaskItemType && parent != null && parent.type === taskList;
|
|
86
|
-
},
|
|
87
|
-
getSelectionBounds: (node, pos) => ({
|
|
88
|
-
start: pos,
|
|
89
|
-
end: pos + node.nodeSize
|
|
90
|
-
}),
|
|
91
|
-
getDepth: (resolvedDepth, rootDepth) => resolvedDepth - rootDepth - 1
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
66
|
// Each stack entry collects children for a taskList at a given depth.
|
|
96
67
|
// The root entry (depth -1) is special: its children become the content
|
|
97
68
|
// of the outermost taskList directly (not wrapped in another taskList).
|
|
@@ -15,9 +15,7 @@ import { IconAction, IconDecision } from '@atlaskit/editor-common/quick-insert';
|
|
|
15
15
|
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
|
|
16
16
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
17
17
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
18
|
-
import {
|
|
19
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/editor-experiment';
|
|
20
|
-
import { closeRequestEditPopupAt, getCurrentIndentLevel, getTaskItemIndex, isInsideTask } from './pm-plugins/helpers';
|
|
18
|
+
import { closeRequestEditPopupAt, getCurrentIndentLevel, isInsideTask } from './pm-plugins/helpers';
|
|
21
19
|
// Ignored via go/ees005
|
|
22
20
|
// eslint-disable-next-line import/no-named-as-default
|
|
23
21
|
import inputRulePlugin from './pm-plugins/input-rules';
|
|
@@ -96,7 +94,7 @@ export const tasksAndDecisionsPlugin = ({
|
|
|
96
94
|
} = {},
|
|
97
95
|
api
|
|
98
96
|
}) => {
|
|
99
|
-
var _api$analytics2, _api$analytics3, _api$analytics4;
|
|
97
|
+
var _api$blockMenu, _api$analytics2, _api$analytics3, _api$analytics4;
|
|
100
98
|
const getIdentifierProvider = () => {
|
|
101
99
|
var _api$contextIdentifie, _api$contextIdentifie2;
|
|
102
100
|
return api === null || api === void 0 ? void 0 : (_api$contextIdentifie = api.contextIdentifier) === null || _api$contextIdentifie === void 0 ? void 0 : (_api$contextIdentifie2 = _api$contextIdentifie.sharedState.currentState()) === null || _api$contextIdentifie2 === void 0 ? void 0 : _api$contextIdentifie2.contextIdentifierProvider;
|
|
@@ -124,50 +122,47 @@ export const tasksAndDecisionsPlugin = ({
|
|
|
124
122
|
}) => setProvider(provider)(tr));
|
|
125
123
|
});
|
|
126
124
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
}]);
|
|
170
|
-
}
|
|
125
|
+
api === null || api === void 0 ? void 0 : (_api$blockMenu = api.blockMenu) === null || _api$blockMenu === void 0 ? void 0 : _api$blockMenu.actions.registerBlockMenuComponents([{
|
|
126
|
+
type: 'block-menu-item',
|
|
127
|
+
key: TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key,
|
|
128
|
+
parent: {
|
|
129
|
+
type: 'block-menu-section',
|
|
130
|
+
key: TRANSFORM_STRUCTURE_MENU_SECTION.key,
|
|
131
|
+
rank: TRANSFORM_STRUCTURE_MENU_SECTION_RANK[TRANSFORM_STRUCTURE_TASK_LIST_MENU_ITEM.key]
|
|
132
|
+
},
|
|
133
|
+
component: ({
|
|
134
|
+
isSuggested
|
|
135
|
+
} = {}) => {
|
|
136
|
+
return /*#__PURE__*/React.createElement(TaskListBlockMenuItem, {
|
|
137
|
+
api: api,
|
|
138
|
+
isSuggested: isSuggested
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
isHidden: () => {
|
|
142
|
+
var _api$blockMenu2;
|
|
143
|
+
return Boolean(api === null || api === void 0 ? void 0 : (_api$blockMenu2 = api.blockMenu) === null || _api$blockMenu2 === void 0 ? void 0 : _api$blockMenu2.actions.isTransformOptionDisabled(TASK_LIST_NODE_NAME));
|
|
144
|
+
}
|
|
145
|
+
}, {
|
|
146
|
+
type: 'block-menu-item',
|
|
147
|
+
key: TRANSFORM_STRUCTURE_DECISION_MENU_ITEM.key,
|
|
148
|
+
parent: {
|
|
149
|
+
type: 'block-menu-section',
|
|
150
|
+
key: TRANSFORM_STRUCTURE_MENU_SECTION.key,
|
|
151
|
+
rank: TRANSFORM_STRUCTURE_MENU_SECTION_RANK[TRANSFORM_STRUCTURE_DECISION_MENU_ITEM.key]
|
|
152
|
+
},
|
|
153
|
+
component: ({
|
|
154
|
+
isSuggested
|
|
155
|
+
} = {}) => {
|
|
156
|
+
return /*#__PURE__*/React.createElement(DecisionListBlockMenuItem, {
|
|
157
|
+
api: api,
|
|
158
|
+
isSuggested: isSuggested
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
isHidden: () => {
|
|
162
|
+
var _api$blockMenu3;
|
|
163
|
+
return Boolean(api === null || api === void 0 ? void 0 : (_api$blockMenu3 = api.blockMenu) === null || _api$blockMenu3 === void 0 ? void 0 : _api$blockMenu3.actions.isTransformOptionDisabled(DECISION_LIST_NODE_NAME));
|
|
164
|
+
}
|
|
165
|
+
}]);
|
|
171
166
|
return {
|
|
172
167
|
name: 'taskDecision',
|
|
173
168
|
nodes() {
|
|
@@ -194,13 +189,11 @@ export const tasksAndDecisionsPlugin = ({
|
|
|
194
189
|
}
|
|
195
190
|
const pluginState = taskPluginKey.getState(editorState);
|
|
196
191
|
const indentLevel = getCurrentIndentLevel(editorState.selection) || 0;
|
|
197
|
-
const itemIndex = getTaskItemIndex(editorState);
|
|
198
|
-
const isFlexibleListIndentationEnabled = expValEqualsNoExposure('platform_editor_flexible_list_indentation', 'isEnabled', true);
|
|
199
192
|
return {
|
|
200
193
|
focusedTaskItemLocalId: (pluginState === null || pluginState === void 0 ? void 0 : pluginState.focusedTaskItemLocalId) || null,
|
|
201
194
|
isInsideTask: isInsideTask(editorState),
|
|
202
|
-
indentDisabled:
|
|
203
|
-
outdentDisabled:
|
|
195
|
+
indentDisabled: indentLevel >= MAX_INDENTATION_LEVEL,
|
|
196
|
+
outdentDisabled: indentLevel <= 0,
|
|
204
197
|
// hasEditPermission is assumed to be true if pluginState.hasEditPermission is undefined
|
|
205
198
|
// this allows the default plugin state to initialise as true if the extra configuration is not provided
|
|
206
199
|
hasEditPermission: (pluginState === null || pluginState === void 0 ? void 0 : pluginState.hasEditPermission) !== undefined ? pluginState === null || pluginState === void 0 ? void 0 : pluginState.hasEditPermission : true,
|
|
@@ -1,81 +1,9 @@
|
|
|
1
1
|
import { findCutBefore } from '@atlaskit/editor-common/commands';
|
|
2
2
|
import { getFirstParagraphBlockMarkAttrs } from '@atlaskit/editor-common/lists';
|
|
3
3
|
import { isTaskList } from '@atlaskit/editor-common/transforms';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { findBlockTaskItem, normalizeTaskItemsSelection } from './utils';
|
|
4
|
+
import { ReplaceAroundStep } from '@atlaskit/editor-prosemirror/transform';
|
|
5
|
+
import { isActionOrDecisionItem, isActionOrDecisionList } from './helpers';
|
|
7
6
|
import { normalizeNodeForTaskTextSize } from './utils/paste';
|
|
8
|
-
export var liftSelection = function liftSelection(state, dispatch) {
|
|
9
|
-
var normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
10
|
-
var $from = normalizedSelection.$from,
|
|
11
|
-
$to = normalizedSelection.$to;
|
|
12
|
-
var tr = liftBlock(state.tr, $from, $to);
|
|
13
|
-
if (dispatch && tr) {
|
|
14
|
-
dispatch(tr);
|
|
15
|
-
}
|
|
16
|
-
return !!tr;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Wraps the current selection in a task list, respecting a maximum indentation depth of 6 levels.
|
|
21
|
-
*
|
|
22
|
-
* - Normalizes the selection to ensure it covers complete task items.
|
|
23
|
-
* - Determines the maximum depth of task list nesting within the selection.
|
|
24
|
-
* - If the selection is already nested at or beyond the maximum depth, the command does nothing.
|
|
25
|
-
* - Calculates the block range to wrap, handling both regular and block task items.
|
|
26
|
-
* - Wraps the block in a task list to increase indentation or create a new task list if necessary.
|
|
27
|
-
*
|
|
28
|
-
* @param state - The current editor state.
|
|
29
|
-
* @param dispatch - The dispatch function to apply the transaction.
|
|
30
|
-
* @returns `true` if the command was handled (even if no changes were made), otherwise `false`.
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* autoJoin(wrapSelectionInTaskList, ['taskList']))(state, dispatch);
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export var wrapSelectionInTaskList = function wrapSelectionInTaskList(state, dispatch) {
|
|
37
|
-
var _normalizeTaskItemsSe = normalizeTaskItemsSelection(state.selection),
|
|
38
|
-
$from = _normalizeTaskItemsSe.$from,
|
|
39
|
-
$to = _normalizeTaskItemsSe.$to;
|
|
40
|
-
|
|
41
|
-
// limit ui indentation to 6 levels
|
|
42
|
-
var _state$schema$nodes = state.schema.nodes,
|
|
43
|
-
taskList = _state$schema$nodes.taskList,
|
|
44
|
-
taskItem = _state$schema$nodes.taskItem,
|
|
45
|
-
blockTaskItem = _state$schema$nodes.blockTaskItem;
|
|
46
|
-
var maxDepth = subtreeHeight($from, $to, [taskList, taskItem]);
|
|
47
|
-
if (blockTaskItem) {
|
|
48
|
-
var resultOfFindBlockTaskItem = findBlockTaskItem($from);
|
|
49
|
-
if (resultOfFindBlockTaskItem) {
|
|
50
|
-
var hasParagraph = resultOfFindBlockTaskItem.hasParagraph;
|
|
51
|
-
// If the selection is inside a nested node inside the blockTaskItem
|
|
52
|
-
// Remove the difference in depth between the selection and the blockTaskItemNode
|
|
53
|
-
if (hasParagraph) {
|
|
54
|
-
maxDepth = subtreeHeight($from, $to, [taskList, blockTaskItem]) - 1;
|
|
55
|
-
} else {
|
|
56
|
-
maxDepth = subtreeHeight($from, $to, [taskList, blockTaskItem]);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (maxDepth >= 6) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
var blockRange = getBlockRange({
|
|
64
|
-
$from: $from,
|
|
65
|
-
$to: $to
|
|
66
|
-
});
|
|
67
|
-
if (!blockRange) {
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
var wrapping = findWrapping(blockRange, state.schema.nodes.taskList);
|
|
71
|
-
if (!wrapping) {
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
if (dispatch) {
|
|
75
|
-
dispatch(state.tr.wrap(blockRange, wrapping).scrollIntoView());
|
|
76
|
-
}
|
|
77
|
-
return true;
|
|
78
|
-
};
|
|
79
7
|
|
|
80
8
|
/**
|
|
81
9
|
* Tries to move the paragraph content near the given position into the taskItem or decisionItem
|
|
@@ -195,56 +195,6 @@ export var walkOut = function walkOut($startPos) {
|
|
|
195
195
|
return $pos;
|
|
196
196
|
};
|
|
197
197
|
|
|
198
|
-
/**
|
|
199
|
-
* Finds the height of a tree-like structure, given any position inside it.
|
|
200
|
-
*
|
|
201
|
-
* Traverses from the top of the tree to all leaf nodes, and returns the length
|
|
202
|
-
* of the longest path.
|
|
203
|
-
*
|
|
204
|
-
* This means you can use it with things like taskList, which
|
|
205
|
-
* do not nest themselves inside taskItems but rather as adjacent children.
|
|
206
|
-
*
|
|
207
|
-
* @param $pos Any position inside the tree.
|
|
208
|
-
* @param types The node types to consider traversable
|
|
209
|
-
*/
|
|
210
|
-
export var subtreeHeight = function subtreeHeight($from, $to, types) {
|
|
211
|
-
var root = findFarthestParentNode(function (node) {
|
|
212
|
-
return types.indexOf(node.type) > -1;
|
|
213
|
-
})($from);
|
|
214
|
-
if (!root) {
|
|
215
|
-
return -1;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// get the height between the root and the current position
|
|
219
|
-
var distToParent = $from.depth - root.depth;
|
|
220
|
-
|
|
221
|
-
// include any following taskList since nested lists appear
|
|
222
|
-
// as siblings
|
|
223
|
-
//
|
|
224
|
-
// this is unlike regular bullet lists where the orderedList
|
|
225
|
-
// appears as descendent of listItem
|
|
226
|
-
var blockRange = getBlockRange({
|
|
227
|
-
$from: $from,
|
|
228
|
-
$to: $to
|
|
229
|
-
});
|
|
230
|
-
if (!blockRange) {
|
|
231
|
-
return -1;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// and get the max height from the current position to the
|
|
235
|
-
// deepest leaf node
|
|
236
|
-
var maxChildDepth = $from.depth;
|
|
237
|
-
$from.doc.nodesBetween(blockRange.start, blockRange.end, function (descendent, relPos, _parent) {
|
|
238
|
-
maxChildDepth = Math.max($from.doc.resolve(relPos).depth, maxChildDepth);
|
|
239
|
-
|
|
240
|
-
// keep descending down the tree if we can
|
|
241
|
-
if (types.indexOf(descendent.type) > -1) {
|
|
242
|
-
return true;
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
return distToParent + (maxChildDepth - $from.depth);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
198
|
/**
|
|
249
199
|
* Determines if the current selection is inside an empty taskItem, decisionItem, or blockTaskItem.
|
|
250
200
|
*
|
|
@@ -14,9 +14,8 @@ import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
|
14
14
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
15
15
|
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
16
16
|
import { findParentNodeOfType, findParentNodeOfTypeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
17
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
18
17
|
import { moveSelectedTaskListItems } from './actions/move-selected-task-list-items';
|
|
19
|
-
import { joinAtCut
|
|
18
|
+
import { joinAtCut } from './commands';
|
|
20
19
|
import { findFirstParentListNode, getBlockRange, getCurrentIndentLevel, getTaskItemIndex, isActionOrDecisionItem, isActionOrDecisionList, isEmptyTaskDecision, isInFirstTextblockOfBlockTaskItem, isInLastTextblockOfBlockTaskItem, isInsideDecision, isInsideTask, isInsideTaskOrDecisionItem, isTable, liftBlock, walkOut } from './helpers';
|
|
21
20
|
import { insertTaskDecisionWithAnalytics } from './insert-commands';
|
|
22
21
|
import { toggleTaskList } from './toggle-tasklist-commands';
|
|
@@ -100,24 +99,18 @@ export var getUnindentCommand = function getUnindentCommand(editorAnalyticsAPI)
|
|
|
100
99
|
return filter(isInsideTask, function (state, dispatch) {
|
|
101
100
|
var normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
102
101
|
var curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
103
|
-
if (
|
|
104
|
-
|
|
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;
|
|
102
|
+
if (!curIndentLevel) {
|
|
103
|
+
return true;
|
|
116
104
|
}
|
|
117
|
-
|
|
118
|
-
|
|
105
|
+
var outdentTr = moveSelectedTaskListItems(state.tr, -1);
|
|
106
|
+
if (outdentTr) {
|
|
107
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.OUTDENT, inputMethod))(function (_state, d) {
|
|
108
|
+
d === null || d === void 0 || d(outdentTr);
|
|
109
|
+
return true;
|
|
110
|
+
})(state, dispatch);
|
|
111
|
+
return true;
|
|
119
112
|
}
|
|
120
|
-
return
|
|
113
|
+
return false;
|
|
121
114
|
});
|
|
122
115
|
};
|
|
123
116
|
};
|
|
@@ -144,24 +137,18 @@ export var getIndentCommand = function getIndentCommand(editorAnalyticsAPI) {
|
|
|
144
137
|
return filter(isInsideTask, function (state, dispatch) {
|
|
145
138
|
var normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
146
139
|
var curIndentLevel = getCurrentIndentLevel(normalizedSelection);
|
|
147
|
-
if (
|
|
148
|
-
|
|
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;
|
|
140
|
+
if (!curIndentLevel) {
|
|
141
|
+
return true;
|
|
160
142
|
}
|
|
161
|
-
|
|
143
|
+
var indentTr = moveSelectedTaskListItems(state.tr, 1);
|
|
144
|
+
if (indentTr) {
|
|
145
|
+
withAnalytics(editorAnalyticsAPI, indentationAnalytics(curIndentLevel, INDENT_DIRECTION.INDENT, inputMethod))(function (_state, d) {
|
|
146
|
+
d === null || d === void 0 || d(indentTr);
|
|
147
|
+
return true;
|
|
148
|
+
})(state, dispatch);
|
|
162
149
|
return true;
|
|
163
150
|
}
|
|
164
|
-
return
|
|
151
|
+
return false;
|
|
165
152
|
});
|
|
166
153
|
};
|
|
167
154
|
};
|
|
@@ -599,13 +586,12 @@ var enter = function enter(editorAnalyticsAPI, getContextIdentifier) {
|
|
|
599
586
|
tr.insert(insertPos, newTask);
|
|
600
587
|
// Place cursor on the newly inserted empty task item above
|
|
601
588
|
// when nested inside another taskList.
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}
|
|
589
|
+
|
|
590
|
+
var taskListType = schema.nodes.taskList;
|
|
591
|
+
var parentTaskList = $from.node($from.depth - 1);
|
|
592
|
+
var grandparent = $from.depth >= 3 ? $from.node($from.depth - 2) : null;
|
|
593
|
+
if ((parentTaskList === null || parentTaskList === void 0 ? void 0 : parentTaskList.type) === taskListType && (grandparent === null || grandparent === void 0 ? void 0 : grandparent.type) === taskListType) {
|
|
594
|
+
tr.setSelection(TextSelection.create(tr.doc, insertPos + 1));
|
|
609
595
|
}
|
|
610
596
|
return tr;
|
|
611
597
|
}
|
|
@@ -11,14 +11,12 @@ import { getStepRange } from '@atlaskit/editor-common/utils';
|
|
|
11
11
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
12
12
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
13
13
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
14
|
-
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
15
14
|
import { DecisionItemNodeView } from '../nodeviews/DecisionItemNodeView';
|
|
16
15
|
import { taskView } from '../nodeviews/task-node-view';
|
|
17
16
|
import { focusTaskDecision, openRequestEditPopup, setProvider } from './actions';
|
|
18
17
|
import { focusCheckbox, focusCheckboxAndUpdateSelection, getTaskItemDataAtPos, getTaskItemDataToFocus, isInsideTask, removeCheckboxFocus } from './helpers';
|
|
19
18
|
import { stateKey } from './plugin-key';
|
|
20
19
|
import { taskItemOnChange } from './taskItemOnChange';
|
|
21
|
-
import { applyTaskListNormalisationFixes } from './transforms';
|
|
22
20
|
import { ACTIONS } from './types';
|
|
23
21
|
import { tempTransformSliceToRemoveBlockTaskItem } from './utils/paste';
|
|
24
22
|
function nodesBetweenChanged(tr, f, startPos) {
|
|
@@ -263,24 +261,6 @@ export function createPlugin(portalProviderAPI, eventDispatcher, dispatch, api,
|
|
|
263
261
|
* Note: we currently do not handle the edge case where two nodes may have the same localId
|
|
264
262
|
*/
|
|
265
263
|
appendTransaction: function appendTransaction(transactions, _oldState, newState) {
|
|
266
|
-
// Normalise taskList structure first — runs on its own transaction (without addToHistory: false)
|
|
267
|
-
// so it is included in history and correctly undone with the triggering operation.
|
|
268
|
-
if (expValEqualsNoExposure('platform_editor_flexible_list_schema', 'isEnabled', true) && transactions.some(function (t) {
|
|
269
|
-
return t.docChanged;
|
|
270
|
-
})) {
|
|
271
|
-
var normTr = applyTaskListNormalisationFixes({
|
|
272
|
-
tr: newState.tr,
|
|
273
|
-
transactions: transactions,
|
|
274
|
-
doc: newState.doc,
|
|
275
|
-
schema: newState.schema
|
|
276
|
-
});
|
|
277
|
-
if (normTr.docChanged) {
|
|
278
|
-
// Return the normalisation transaction — the next appendTransaction call will
|
|
279
|
-
// assign any missing localIds to newly inserted nodes via the localId path below.
|
|
280
|
-
return normTr;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
264
|
// Assign unique localIds to any new nodes that don't have one.
|
|
285
265
|
// Runs with addToHistory: false so localId assignment is not part of the undo history.
|
|
286
266
|
var tr = newState.tr;
|