@atlaskit/editor-plugin-list 8.2.18 → 8.2.20
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 +16 -0
- package/dist/cjs/pm-plugins/commands/index.js +24 -33
- package/dist/cjs/pm-plugins/main.js +7 -114
- package/dist/es2019/pm-plugins/commands/index.js +25 -34
- package/dist/es2019/pm-plugins/main.js +5 -111
- package/dist/esm/pm-plugins/commands/index.js +24 -33
- package/dist/esm/pm-plugins/main.js +6 -113
- package/dist/types/pm-plugins/main.d.ts +2 -4
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -4
- package/package.json +7 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-list
|
|
2
2
|
|
|
3
|
+
## 8.2.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`73a49fd4c204c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/73a49fd4c204c) -
|
|
8
|
+
Cleanup FG platform_editor_new_list_decorations_logic
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 8.2.19
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`fa963aec58f3d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fa963aec58f3d) -
|
|
16
|
+
EDITOR-3064 Clean up feature gate platform_editor_split_list_item_for_gap_cursor
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 8.2.18
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -16,7 +16,6 @@ var _commands2 = require("@atlaskit/editor-prosemirror/commands");
|
|
|
16
16
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
17
17
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
18
18
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
19
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
20
19
|
var _conversions = require("../actions/conversions");
|
|
21
20
|
var _wrapAndJoinLists = require("../actions/wrap-and-join-lists");
|
|
22
21
|
var _transforms = require("../transforms");
|
|
@@ -39,9 +38,9 @@ var enterKeyCommand = exports.enterKeyCommand = function enterKeyCommand(editorA
|
|
|
39
38
|
codeBlock = _state$schema$nodes.codeBlock;
|
|
40
39
|
|
|
41
40
|
// the list item is the parent of the gap cursor
|
|
42
|
-
// while for text, list item is the
|
|
41
|
+
// while for text, list item is the grandparent of the text node
|
|
43
42
|
var isGapCursorSelection = selection instanceof _selection.GapCursorSelection;
|
|
44
|
-
var wrapper = isGapCursorSelection
|
|
43
|
+
var wrapper = isGapCursorSelection ? $from.parent : $from.node($from.depth - 1);
|
|
45
44
|
if (wrapper && wrapper.type === listItem) {
|
|
46
45
|
/** Check if the wrapper has any visible content */
|
|
47
46
|
var wrapperHasContent = (0, _utils.hasVisibleContent)(wrapper);
|
|
@@ -208,17 +207,16 @@ function splitListItem(itemType) {
|
|
|
208
207
|
return false;
|
|
209
208
|
}
|
|
210
209
|
|
|
211
|
-
// list item is the parent of the gap cursor instead of
|
|
212
|
-
// rename grantParent to WrapperlistItem once we clean up platform_editor_split_list_item_for_gap_cursor
|
|
210
|
+
// list item is the parent of the gap cursor instead of grandparent
|
|
213
211
|
var isGapCursorSelection = ref instanceof _selection.GapCursorSelection;
|
|
214
|
-
var
|
|
215
|
-
if (
|
|
212
|
+
var wrapperListItem = isGapCursorSelection ? $from.parent : $from.node(-1);
|
|
213
|
+
if (wrapperListItem.type !== itemType) {
|
|
216
214
|
return false;
|
|
217
215
|
}
|
|
218
216
|
/** --> The following line changed from the original PM implementation to allow list additions with multiple paragraphs */
|
|
219
217
|
if (
|
|
220
218
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
221
|
-
|
|
219
|
+
wrapperListItem.content.content.length <= 1 && $from.parent.content.size === 0 && !(wrapperListItem.content.size === 0)) {
|
|
222
220
|
// In an empty block. If this is a nested list, the wrapping
|
|
223
221
|
// list item should be split. Otherwise, bail out and let next
|
|
224
222
|
// command handle lifting.
|
|
@@ -245,38 +243,31 @@ function splitListItem(itemType) {
|
|
|
245
243
|
}
|
|
246
244
|
return true;
|
|
247
245
|
}
|
|
248
|
-
var nextType = $to.pos === $from.end() ?
|
|
246
|
+
var nextType = $to.pos === $from.end() ? wrapperListItem.contentMatchAt(0).defaultType : null;
|
|
249
247
|
var tr = state.tr.delete($from.pos, $to.pos);
|
|
250
248
|
var types = nextType && [null, {
|
|
251
249
|
type: nextType
|
|
252
250
|
}];
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (ref instanceof _state.TextSelection) {
|
|
257
|
-
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
258
|
-
return true;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// create new list item with empty paragraph when user click enter on gap cursor
|
|
262
|
-
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
263
|
-
// For gap cursor selection , we can not split the list item directly
|
|
264
|
-
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
265
|
-
var _state$schema$nodes2 = state.schema.nodes,
|
|
266
|
-
listItem = _state$schema$nodes2.listItem,
|
|
267
|
-
paragraph = _state$schema$nodes2.paragraph;
|
|
268
|
-
var newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
269
|
-
dispatch(tr.insert($from.pos, newListItem).setSelection(_state.Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
270
|
-
return true;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return false;
|
|
274
|
-
} else {
|
|
275
|
-
if (dispatch) {
|
|
251
|
+
if (dispatch) {
|
|
252
|
+
var _$from$nodeBefore;
|
|
253
|
+
if (ref instanceof _state.TextSelection) {
|
|
276
254
|
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// create new list item with empty paragraph when user clicks enter on gap cursor
|
|
259
|
+
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
260
|
+
// For gap cursor selection, we cannot split the list item directly
|
|
261
|
+
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
262
|
+
var _state$schema$nodes2 = state.schema.nodes,
|
|
263
|
+
listItem = _state$schema$nodes2.listItem,
|
|
264
|
+
paragraph = _state$schema$nodes2.paragraph;
|
|
265
|
+
var newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
266
|
+
dispatch(tr.insert($from.pos, newListItem).setSelection(_state.Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
267
|
+
return true;
|
|
277
268
|
}
|
|
278
|
-
return true;
|
|
279
269
|
}
|
|
270
|
+
return false;
|
|
280
271
|
};
|
|
281
272
|
}
|
|
282
273
|
var deletePreviousEmptyListItem = function deletePreviousEmptyListItem(state, dispatch) {
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
7
|
+
exports.pluginKey = exports.getDecorations = exports.createPlugin = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
10
10
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
@@ -13,7 +13,6 @@ var _utils = require("@atlaskit/editor-common/utils");
|
|
|
13
13
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
14
14
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
15
15
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
16
|
-
var _insm = require("@atlaskit/insm");
|
|
17
16
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
18
17
|
var _selection2 = require("./utils/selection");
|
|
19
18
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -27,79 +26,6 @@ var initialState = {
|
|
|
27
26
|
orderedListDisabled: false,
|
|
28
27
|
decorationSet: _view.DecorationSet.empty
|
|
29
28
|
};
|
|
30
|
-
var computeListDecorations = exports.computeListDecorations = function computeListDecorations(doc) {
|
|
31
|
-
var from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
32
|
-
var to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : doc.content.size;
|
|
33
|
-
var decorations = [];
|
|
34
|
-
|
|
35
|
-
// this stack keeps track of each (nested) list to calculate the indentation level
|
|
36
|
-
var processedListsStack = [];
|
|
37
|
-
doc.nodesBetween(from, to, function (node, currentNodeStartPos) {
|
|
38
|
-
if (processedListsStack.length > 0) {
|
|
39
|
-
var isOutsideLastList = true;
|
|
40
|
-
while (isOutsideLastList && processedListsStack.length > 0) {
|
|
41
|
-
var lastList = processedListsStack[processedListsStack.length - 1];
|
|
42
|
-
var lastListEndPos = lastList.startPos + lastList.node.nodeSize;
|
|
43
|
-
isOutsideLastList = currentNodeStartPos >= lastListEndPos;
|
|
44
|
-
// once we finish iterating over each innermost list, pop the stack to
|
|
45
|
-
// decrease the indent level attribute accordingly
|
|
46
|
-
if (isOutsideLastList) {
|
|
47
|
-
processedListsStack.pop();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if ((0, _utils.isListNode)(node)) {
|
|
52
|
-
processedListsStack.push({
|
|
53
|
-
node: node,
|
|
54
|
-
startPos: currentNodeStartPos
|
|
55
|
-
});
|
|
56
|
-
var _from = currentNodeStartPos;
|
|
57
|
-
var _to = currentNodeStartPos + node.nodeSize;
|
|
58
|
-
var depth = processedListsStack.length;
|
|
59
|
-
decorations.push(_view.Decoration.node(_from, _to, {
|
|
60
|
-
'data-indent-level': "".concat(depth)
|
|
61
|
-
}));
|
|
62
|
-
if (node.type.name === 'orderedList') {
|
|
63
|
-
var _node$attrs;
|
|
64
|
-
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
65
|
-
// spacing to account for the extra digit chars
|
|
66
|
-
var digitsSize = (0, _utils.getItemCounterDigitsSize)({
|
|
67
|
-
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
68
|
-
order: node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
69
|
-
});
|
|
70
|
-
if (digitsSize && digitsSize > 1) {
|
|
71
|
-
decorations.push(_view.Decoration.node(_from, _to, {
|
|
72
|
-
style: (0, _styles.getOrderedListInlineStyles)(digitsSize, 'string')
|
|
73
|
-
}));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
return decorations;
|
|
79
|
-
};
|
|
80
|
-
var updateListDecorations = exports.updateListDecorations = function updateListDecorations(decorationSet, tr) {
|
|
81
|
-
var nextDecorationSet = decorationSet.map(tr.mapping, tr.doc);
|
|
82
|
-
tr.mapping.maps.forEach(function (stepMap, index) {
|
|
83
|
-
stepMap.forEach(function (oldStart, oldEnd) {
|
|
84
|
-
var start = tr.mapping.slice(index).map(oldStart, -1);
|
|
85
|
-
var end = tr.mapping.slice(index).map(oldEnd);
|
|
86
|
-
|
|
87
|
-
// Remove decorations in this range
|
|
88
|
-
var decorationsToRemove = nextDecorationSet.find(start, end);
|
|
89
|
-
nextDecorationSet = nextDecorationSet.remove(decorationsToRemove);
|
|
90
|
-
|
|
91
|
-
// Recompute decorations for this range
|
|
92
|
-
// Expand the range by 1 on each side to catch adjacent list nodes
|
|
93
|
-
var from = Math.max(0, start - 1);
|
|
94
|
-
var to = Math.min(tr.doc.content.size, end + 1);
|
|
95
|
-
var decorationsToAdd = computeListDecorations(tr.doc, from, to);
|
|
96
|
-
nextDecorationSet = nextDecorationSet.add(tr.doc, decorationsToAdd);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
return nextDecorationSet;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// delete getDecorations during platform_editor_new_list_decorations_logic experiment clean up
|
|
103
29
|
var getDecorations = exports.getDecorations = function getDecorations(doc, state, featureFlags) {
|
|
104
30
|
var decorations = [];
|
|
105
31
|
|
|
@@ -131,12 +57,12 @@ var getDecorations = exports.getDecorations = function getDecorations(doc, state
|
|
|
131
57
|
'data-indent-level': "".concat(depth)
|
|
132
58
|
}));
|
|
133
59
|
if (node.type.name === 'orderedList') {
|
|
134
|
-
var _node$
|
|
60
|
+
var _node$attrs;
|
|
135
61
|
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
136
62
|
// spacing to account for the extra digit chars
|
|
137
63
|
var digitsSize = (0, _utils.getItemCounterDigitsSize)({
|
|
138
64
|
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
139
|
-
order: node === null || node === void 0 || (_node$
|
|
65
|
+
order: node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
140
66
|
});
|
|
141
67
|
if (digitsSize && digitsSize > 1) {
|
|
142
68
|
decorations.push(_view.Decoration.node(from, to, {
|
|
@@ -199,15 +125,8 @@ var reducer = function reducer() {
|
|
|
199
125
|
var createInitialState = function createInitialState(featureFlags, api) {
|
|
200
126
|
return function (state) {
|
|
201
127
|
var isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
|
|
202
|
-
var getInitialDecorations = function getInitialDecorations() {
|
|
203
|
-
var _insm$session, _insm$session2;
|
|
204
|
-
(_insm$session = _insm.insm.session) === null || _insm$session === void 0 || _insm$session.startFeature('listDecorationsInit');
|
|
205
|
-
var decorations = computeListDecorations(state.doc);
|
|
206
|
-
(_insm$session2 = _insm.insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('listDecorationsInit');
|
|
207
|
-
return decorations;
|
|
208
|
-
};
|
|
209
128
|
return _objectSpread(_objectSpread({}, isToolbarAIFCEnabled && (0, _expValEquals.expValEquals)('platform_editor_toolbar_aifc_patch_3', 'isEnabled', true) ? getListState(state.doc, state.selection) : initialState), {}, {
|
|
210
|
-
decorationSet:
|
|
129
|
+
decorationSet: getDecorations(state.doc, state, featureFlags)
|
|
211
130
|
});
|
|
212
131
|
};
|
|
213
132
|
};
|
|
@@ -218,39 +137,13 @@ var createPlugin = exports.createPlugin = function createPlugin(eventDispatch, f
|
|
|
218
137
|
}),
|
|
219
138
|
getPluginState = _pluginFactory.getPluginState,
|
|
220
139
|
createPluginState = _pluginFactory.createPluginState;
|
|
221
|
-
var pluginState = createPluginState(eventDispatch, createInitialState(featureFlags, api));
|
|
222
|
-
var pluginStateInit = function pluginStateInit(_, state) {
|
|
223
|
-
return createInitialState(featureFlags)(state);
|
|
224
|
-
};
|
|
225
|
-
var pluginStateApply = function pluginStateApply(tr, oldPluginState, _oldEditorState, _newEditorState) {
|
|
226
|
-
var nextPluginState = oldPluginState;
|
|
227
|
-
if (tr.docChanged) {
|
|
228
|
-
var _insm$session3, _insm$session4;
|
|
229
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
230
|
-
(_insm$session3 = _insm.insm.session) === null || _insm$session3 === void 0 || _insm$session3.startFeature('listDecorationUpdate');
|
|
231
|
-
var nextDecorationSet = updateListDecorations(nextPluginState.decorationSet, tr);
|
|
232
|
-
(_insm$session4 = _insm.insm.session) === null || _insm$session4 === void 0 || _insm$session4.endFeature('listDecorationUpdate');
|
|
233
|
-
nextPluginState = _objectSpread(_objectSpread({}, nextPluginState), {}, {
|
|
234
|
-
decorationSet: nextDecorationSet
|
|
235
|
-
});
|
|
236
|
-
} else if (tr.selectionSet) {
|
|
237
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
238
|
-
}
|
|
239
|
-
if (nextPluginState !== oldPluginState) {
|
|
240
|
-
eventDispatch(listPluginKey, nextPluginState);
|
|
241
|
-
}
|
|
242
|
-
return nextPluginState;
|
|
243
|
-
};
|
|
244
140
|
return new _safePlugin.SafePlugin({
|
|
245
|
-
state:
|
|
246
|
-
init: (0, _expValEquals.expValEquals)('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateInit : pluginState.init,
|
|
247
|
-
apply: (0, _expValEquals.expValEquals)('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateApply : pluginState.apply
|
|
248
|
-
},
|
|
141
|
+
state: createPluginState(eventDispatch, createInitialState(featureFlags, api)),
|
|
249
142
|
key: listPluginKey,
|
|
250
143
|
props: {
|
|
251
144
|
decorations: function decorations(state) {
|
|
252
|
-
var
|
|
253
|
-
decorationSet =
|
|
145
|
+
var _getPluginState = getPluginState(state),
|
|
146
|
+
decorationSet = _getPluginState.decorationSet;
|
|
254
147
|
return decorationSet;
|
|
255
148
|
},
|
|
256
149
|
handleClick: function handleClick(view, pos, event) {
|
|
@@ -8,7 +8,6 @@ import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
|
|
8
8
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
9
9
|
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
10
10
|
import { findPositionOfNodeBefore, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
11
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
12
11
|
import { convertListType } from '../actions/conversions';
|
|
13
12
|
import { wrapInListAndJoin } from '../actions/wrap-and-join-lists';
|
|
14
13
|
import { liftFollowingList, liftNodeSelectionList, liftTextSelectionList } from '../transforms';
|
|
@@ -32,9 +31,9 @@ export const enterKeyCommand = editorAnalyticsAPI => () => (state, dispatch) =>
|
|
|
32
31
|
} = state.schema.nodes;
|
|
33
32
|
|
|
34
33
|
// the list item is the parent of the gap cursor
|
|
35
|
-
// while for text, list item is the
|
|
34
|
+
// while for text, list item is the grandparent of the text node
|
|
36
35
|
const isGapCursorSelection = selection instanceof GapCursorSelection;
|
|
37
|
-
const wrapper = isGapCursorSelection
|
|
36
|
+
const wrapper = isGapCursorSelection ? $from.parent : $from.node($from.depth - 1);
|
|
38
37
|
if (wrapper && wrapper.type === listItem) {
|
|
39
38
|
/** Check if the wrapper has any visible content */
|
|
40
39
|
const wrapperHasContent = hasVisibleContent(wrapper);
|
|
@@ -191,17 +190,16 @@ function splitListItem(itemType) {
|
|
|
191
190
|
return false;
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
// list item is the parent of the gap cursor instead of
|
|
195
|
-
// rename grantParent to WrapperlistItem once we clean up platform_editor_split_list_item_for_gap_cursor
|
|
193
|
+
// list item is the parent of the gap cursor instead of grandparent
|
|
196
194
|
const isGapCursorSelection = ref instanceof GapCursorSelection;
|
|
197
|
-
const
|
|
198
|
-
if (
|
|
195
|
+
const wrapperListItem = isGapCursorSelection ? $from.parent : $from.node(-1);
|
|
196
|
+
if (wrapperListItem.type !== itemType) {
|
|
199
197
|
return false;
|
|
200
198
|
}
|
|
201
199
|
/** --> The following line changed from the original PM implementation to allow list additions with multiple paragraphs */
|
|
202
200
|
if (
|
|
203
201
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
204
|
-
|
|
202
|
+
wrapperListItem.content.content.length <= 1 && $from.parent.content.size === 0 && !(wrapperListItem.content.size === 0)) {
|
|
205
203
|
// In an empty block. If this is a nested list, the wrapping
|
|
206
204
|
// list item should be split. Otherwise, bail out and let next
|
|
207
205
|
// command handle lifting.
|
|
@@ -228,39 +226,32 @@ function splitListItem(itemType) {
|
|
|
228
226
|
}
|
|
229
227
|
return true;
|
|
230
228
|
}
|
|
231
|
-
const nextType = $to.pos === $from.end() ?
|
|
229
|
+
const nextType = $to.pos === $from.end() ? wrapperListItem.contentMatchAt(0).defaultType : null;
|
|
232
230
|
const tr = state.tr.delete($from.pos, $to.pos);
|
|
233
231
|
const types = nextType && [null, {
|
|
234
232
|
type: nextType
|
|
235
233
|
}];
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (ref instanceof TextSelection) {
|
|
240
|
-
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
241
|
-
return true;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// create new list item with empty paragraph when user click enter on gap cursor
|
|
245
|
-
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
246
|
-
// For gap cursor selection , we can not split the list item directly
|
|
247
|
-
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
248
|
-
const {
|
|
249
|
-
listItem,
|
|
250
|
-
paragraph
|
|
251
|
-
} = state.schema.nodes;
|
|
252
|
-
const newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
253
|
-
dispatch(tr.insert($from.pos, newListItem).setSelection(Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return false;
|
|
258
|
-
} else {
|
|
259
|
-
if (dispatch) {
|
|
234
|
+
if (dispatch) {
|
|
235
|
+
var _$from$nodeBefore;
|
|
236
|
+
if (ref instanceof TextSelection) {
|
|
260
237
|
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// create new list item with empty paragraph when user clicks enter on gap cursor
|
|
242
|
+
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
243
|
+
// For gap cursor selection, we cannot split the list item directly
|
|
244
|
+
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
245
|
+
const {
|
|
246
|
+
listItem,
|
|
247
|
+
paragraph
|
|
248
|
+
} = state.schema.nodes;
|
|
249
|
+
const newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
250
|
+
dispatch(tr.insert($from.pos, newListItem).setSelection(Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
251
|
+
return true;
|
|
261
252
|
}
|
|
262
|
-
return true;
|
|
263
253
|
}
|
|
254
|
+
return false;
|
|
264
255
|
};
|
|
265
256
|
}
|
|
266
257
|
const deletePreviousEmptyListItem = (state, dispatch) => {
|
|
@@ -5,7 +5,6 @@ import { getItemCounterDigitsSize, isListNode, pluginFactory } from '@atlaskit/e
|
|
|
5
5
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
6
|
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
7
7
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
|
-
import { insm } from '@atlaskit/insm';
|
|
9
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
10
9
|
import { isWrappingPossible } from './utils/selection';
|
|
11
10
|
const listPluginKey = new PluginKey('listPlugin');
|
|
@@ -17,77 +16,6 @@ const initialState = {
|
|
|
17
16
|
orderedListDisabled: false,
|
|
18
17
|
decorationSet: DecorationSet.empty
|
|
19
18
|
};
|
|
20
|
-
export const computeListDecorations = (doc, from = 0, to = doc.content.size) => {
|
|
21
|
-
const decorations = [];
|
|
22
|
-
|
|
23
|
-
// this stack keeps track of each (nested) list to calculate the indentation level
|
|
24
|
-
const processedListsStack = [];
|
|
25
|
-
doc.nodesBetween(from, to, (node, currentNodeStartPos) => {
|
|
26
|
-
if (processedListsStack.length > 0) {
|
|
27
|
-
let isOutsideLastList = true;
|
|
28
|
-
while (isOutsideLastList && processedListsStack.length > 0) {
|
|
29
|
-
const lastList = processedListsStack[processedListsStack.length - 1];
|
|
30
|
-
const lastListEndPos = lastList.startPos + lastList.node.nodeSize;
|
|
31
|
-
isOutsideLastList = currentNodeStartPos >= lastListEndPos;
|
|
32
|
-
// once we finish iterating over each innermost list, pop the stack to
|
|
33
|
-
// decrease the indent level attribute accordingly
|
|
34
|
-
if (isOutsideLastList) {
|
|
35
|
-
processedListsStack.pop();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (isListNode(node)) {
|
|
40
|
-
processedListsStack.push({
|
|
41
|
-
node,
|
|
42
|
-
startPos: currentNodeStartPos
|
|
43
|
-
});
|
|
44
|
-
const from = currentNodeStartPos;
|
|
45
|
-
const to = currentNodeStartPos + node.nodeSize;
|
|
46
|
-
const depth = processedListsStack.length;
|
|
47
|
-
decorations.push(Decoration.node(from, to, {
|
|
48
|
-
'data-indent-level': `${depth}`
|
|
49
|
-
}));
|
|
50
|
-
if (node.type.name === 'orderedList') {
|
|
51
|
-
var _node$attrs;
|
|
52
|
-
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
53
|
-
// spacing to account for the extra digit chars
|
|
54
|
-
const digitsSize = getItemCounterDigitsSize({
|
|
55
|
-
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
56
|
-
order: node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
57
|
-
});
|
|
58
|
-
if (digitsSize && digitsSize > 1) {
|
|
59
|
-
decorations.push(Decoration.node(from, to, {
|
|
60
|
-
style: getOrderedListInlineStyles(digitsSize, 'string')
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
return decorations;
|
|
67
|
-
};
|
|
68
|
-
export const updateListDecorations = (decorationSet, tr) => {
|
|
69
|
-
let nextDecorationSet = decorationSet.map(tr.mapping, tr.doc);
|
|
70
|
-
tr.mapping.maps.forEach((stepMap, index) => {
|
|
71
|
-
stepMap.forEach((oldStart, oldEnd) => {
|
|
72
|
-
const start = tr.mapping.slice(index).map(oldStart, -1);
|
|
73
|
-
const end = tr.mapping.slice(index).map(oldEnd);
|
|
74
|
-
|
|
75
|
-
// Remove decorations in this range
|
|
76
|
-
const decorationsToRemove = nextDecorationSet.find(start, end);
|
|
77
|
-
nextDecorationSet = nextDecorationSet.remove(decorationsToRemove);
|
|
78
|
-
|
|
79
|
-
// Recompute decorations for this range
|
|
80
|
-
// Expand the range by 1 on each side to catch adjacent list nodes
|
|
81
|
-
const from = Math.max(0, start - 1);
|
|
82
|
-
const to = Math.min(tr.doc.content.size, end + 1);
|
|
83
|
-
const decorationsToAdd = computeListDecorations(tr.doc, from, to);
|
|
84
|
-
nextDecorationSet = nextDecorationSet.add(tr.doc, decorationsToAdd);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
return nextDecorationSet;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
// delete getDecorations during platform_editor_new_list_decorations_logic experiment clean up
|
|
91
19
|
export const getDecorations = (doc, state, featureFlags) => {
|
|
92
20
|
const decorations = [];
|
|
93
21
|
|
|
@@ -119,12 +47,12 @@ export const getDecorations = (doc, state, featureFlags) => {
|
|
|
119
47
|
'data-indent-level': `${depth}`
|
|
120
48
|
}));
|
|
121
49
|
if (node.type.name === 'orderedList') {
|
|
122
|
-
var _node$
|
|
50
|
+
var _node$attrs;
|
|
123
51
|
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
124
52
|
// spacing to account for the extra digit chars
|
|
125
53
|
const digitsSize = getItemCounterDigitsSize({
|
|
126
54
|
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
127
|
-
order: node === null || node === void 0 ? void 0 : (_node$
|
|
55
|
+
order: node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
128
56
|
});
|
|
129
57
|
if (digitsSize && digitsSize > 1) {
|
|
130
58
|
decorations.push(Decoration.node(from, to, {
|
|
@@ -186,18 +114,11 @@ const reducer = () => state => {
|
|
|
186
114
|
};
|
|
187
115
|
const createInitialState = (featureFlags, api) => state => {
|
|
188
116
|
const isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
|
|
189
|
-
const getInitialDecorations = () => {
|
|
190
|
-
var _insm$session, _insm$session2;
|
|
191
|
-
(_insm$session = insm.session) === null || _insm$session === void 0 ? void 0 : _insm$session.startFeature('listDecorationsInit');
|
|
192
|
-
const decorations = computeListDecorations(state.doc);
|
|
193
|
-
(_insm$session2 = insm.session) === null || _insm$session2 === void 0 ? void 0 : _insm$session2.endFeature('listDecorationsInit');
|
|
194
|
-
return decorations;
|
|
195
|
-
};
|
|
196
117
|
return {
|
|
197
118
|
// When plugin is initialised, editor state is defined with selection
|
|
198
119
|
// hence returning the list state based on the selection to avoid list button in primary toolbar flickering during initial load
|
|
199
120
|
...(isToolbarAIFCEnabled && expValEquals('platform_editor_toolbar_aifc_patch_3', 'isEnabled', true) ? getListState(state.doc, state.selection) : initialState),
|
|
200
|
-
decorationSet:
|
|
121
|
+
decorationSet: getDecorations(state.doc, state, featureFlags)
|
|
201
122
|
};
|
|
202
123
|
};
|
|
203
124
|
export const createPlugin = (eventDispatch, featureFlags, api) => {
|
|
@@ -208,41 +129,14 @@ export const createPlugin = (eventDispatch, featureFlags, api) => {
|
|
|
208
129
|
onDocChanged: handleDocChanged(featureFlags),
|
|
209
130
|
onSelectionChanged: handleSelectionChanged
|
|
210
131
|
});
|
|
211
|
-
const pluginState = createPluginState(eventDispatch, createInitialState(featureFlags, api));
|
|
212
|
-
const pluginStateInit = (_, state) => {
|
|
213
|
-
return createInitialState(featureFlags)(state);
|
|
214
|
-
};
|
|
215
|
-
const pluginStateApply = (tr, oldPluginState, _oldEditorState, _newEditorState) => {
|
|
216
|
-
let nextPluginState = oldPluginState;
|
|
217
|
-
if (tr.docChanged) {
|
|
218
|
-
var _insm$session3, _insm$session4;
|
|
219
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
220
|
-
(_insm$session3 = insm.session) === null || _insm$session3 === void 0 ? void 0 : _insm$session3.startFeature('listDecorationUpdate');
|
|
221
|
-
const nextDecorationSet = updateListDecorations(nextPluginState.decorationSet, tr);
|
|
222
|
-
(_insm$session4 = insm.session) === null || _insm$session4 === void 0 ? void 0 : _insm$session4.endFeature('listDecorationUpdate');
|
|
223
|
-
nextPluginState = {
|
|
224
|
-
...nextPluginState,
|
|
225
|
-
decorationSet: nextDecorationSet
|
|
226
|
-
};
|
|
227
|
-
} else if (tr.selectionSet) {
|
|
228
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
229
|
-
}
|
|
230
|
-
if (nextPluginState !== oldPluginState) {
|
|
231
|
-
eventDispatch(listPluginKey, nextPluginState);
|
|
232
|
-
}
|
|
233
|
-
return nextPluginState;
|
|
234
|
-
};
|
|
235
132
|
return new SafePlugin({
|
|
236
|
-
state:
|
|
237
|
-
init: expValEquals('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateInit : pluginState.init,
|
|
238
|
-
apply: expValEquals('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateApply : pluginState.apply
|
|
239
|
-
},
|
|
133
|
+
state: createPluginState(eventDispatch, createInitialState(featureFlags, api)),
|
|
240
134
|
key: listPluginKey,
|
|
241
135
|
props: {
|
|
242
136
|
decorations(state) {
|
|
243
137
|
const {
|
|
244
138
|
decorationSet
|
|
245
|
-
} =
|
|
139
|
+
} = getPluginState(state);
|
|
246
140
|
return decorationSet;
|
|
247
141
|
},
|
|
248
142
|
handleClick: (view, pos, event) => {
|
|
@@ -11,7 +11,6 @@ import { chainCommands } from '@atlaskit/editor-prosemirror/commands';
|
|
|
11
11
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
12
12
|
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
13
13
|
import { findPositionOfNodeBefore, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
14
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
14
|
import { convertListType } from '../actions/conversions';
|
|
16
15
|
import { wrapInListAndJoin } from '../actions/wrap-and-join-lists';
|
|
17
16
|
import { liftFollowingList, liftNodeSelectionList, liftTextSelectionList } from '../transforms';
|
|
@@ -32,9 +31,9 @@ export var enterKeyCommand = function enterKeyCommand(editorAnalyticsAPI) {
|
|
|
32
31
|
codeBlock = _state$schema$nodes.codeBlock;
|
|
33
32
|
|
|
34
33
|
// the list item is the parent of the gap cursor
|
|
35
|
-
// while for text, list item is the
|
|
34
|
+
// while for text, list item is the grandparent of the text node
|
|
36
35
|
var isGapCursorSelection = selection instanceof GapCursorSelection;
|
|
37
|
-
var wrapper = isGapCursorSelection
|
|
36
|
+
var wrapper = isGapCursorSelection ? $from.parent : $from.node($from.depth - 1);
|
|
38
37
|
if (wrapper && wrapper.type === listItem) {
|
|
39
38
|
/** Check if the wrapper has any visible content */
|
|
40
39
|
var wrapperHasContent = hasVisibleContent(wrapper);
|
|
@@ -201,17 +200,16 @@ function splitListItem(itemType) {
|
|
|
201
200
|
return false;
|
|
202
201
|
}
|
|
203
202
|
|
|
204
|
-
// list item is the parent of the gap cursor instead of
|
|
205
|
-
// rename grantParent to WrapperlistItem once we clean up platform_editor_split_list_item_for_gap_cursor
|
|
203
|
+
// list item is the parent of the gap cursor instead of grandparent
|
|
206
204
|
var isGapCursorSelection = ref instanceof GapCursorSelection;
|
|
207
|
-
var
|
|
208
|
-
if (
|
|
205
|
+
var wrapperListItem = isGapCursorSelection ? $from.parent : $from.node(-1);
|
|
206
|
+
if (wrapperListItem.type !== itemType) {
|
|
209
207
|
return false;
|
|
210
208
|
}
|
|
211
209
|
/** --> The following line changed from the original PM implementation to allow list additions with multiple paragraphs */
|
|
212
210
|
if (
|
|
213
211
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
-
|
|
212
|
+
wrapperListItem.content.content.length <= 1 && $from.parent.content.size === 0 && !(wrapperListItem.content.size === 0)) {
|
|
215
213
|
// In an empty block. If this is a nested list, the wrapping
|
|
216
214
|
// list item should be split. Otherwise, bail out and let next
|
|
217
215
|
// command handle lifting.
|
|
@@ -238,38 +236,31 @@ function splitListItem(itemType) {
|
|
|
238
236
|
}
|
|
239
237
|
return true;
|
|
240
238
|
}
|
|
241
|
-
var nextType = $to.pos === $from.end() ?
|
|
239
|
+
var nextType = $to.pos === $from.end() ? wrapperListItem.contentMatchAt(0).defaultType : null;
|
|
242
240
|
var tr = state.tr.delete($from.pos, $to.pos);
|
|
243
241
|
var types = nextType && [null, {
|
|
244
242
|
type: nextType
|
|
245
243
|
}];
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (ref instanceof TextSelection) {
|
|
250
|
-
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// create new list item with empty paragraph when user click enter on gap cursor
|
|
255
|
-
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
256
|
-
// For gap cursor selection , we can not split the list item directly
|
|
257
|
-
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
258
|
-
var _state$schema$nodes2 = state.schema.nodes,
|
|
259
|
-
listItem = _state$schema$nodes2.listItem,
|
|
260
|
-
paragraph = _state$schema$nodes2.paragraph;
|
|
261
|
-
var newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
262
|
-
dispatch(tr.insert($from.pos, newListItem).setSelection(Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return false;
|
|
267
|
-
} else {
|
|
268
|
-
if (dispatch) {
|
|
244
|
+
if (dispatch) {
|
|
245
|
+
var _$from$nodeBefore;
|
|
246
|
+
if (ref instanceof TextSelection) {
|
|
269
247
|
dispatch(tr.split($from.pos, 2, types !== null && types !== void 0 ? types : undefined).scrollIntoView());
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// create new list item with empty paragraph when user clicks enter on gap cursor
|
|
252
|
+
if (isGapCursorSelection && (_$from$nodeBefore = $from.nodeBefore) !== null && _$from$nodeBefore !== void 0 && _$from$nodeBefore.isBlock) {
|
|
253
|
+
// For gap cursor selection, we cannot split the list item directly
|
|
254
|
+
// We need to insert a new list item after the current list item to simulate the split behaviour
|
|
255
|
+
var _state$schema$nodes2 = state.schema.nodes,
|
|
256
|
+
listItem = _state$schema$nodes2.listItem,
|
|
257
|
+
paragraph = _state$schema$nodes2.paragraph;
|
|
258
|
+
var newListItem = listItem.createChecked({}, paragraph.createChecked());
|
|
259
|
+
dispatch(tr.insert($from.pos, newListItem).setSelection(Selection.near(tr.doc.resolve($to.pos + 1))).scrollIntoView());
|
|
260
|
+
return true;
|
|
270
261
|
}
|
|
271
|
-
return true;
|
|
272
262
|
}
|
|
263
|
+
return false;
|
|
273
264
|
};
|
|
274
265
|
}
|
|
275
266
|
var deletePreviousEmptyListItem = function deletePreviousEmptyListItem(state, dispatch) {
|
|
@@ -8,7 +8,6 @@ import { getItemCounterDigitsSize, isListNode, pluginFactory } from '@atlaskit/e
|
|
|
8
8
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
9
9
|
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
10
10
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
11
|
-
import { insm } from '@atlaskit/insm';
|
|
12
11
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
12
|
import { isWrappingPossible } from './utils/selection';
|
|
14
13
|
var listPluginKey = new PluginKey('listPlugin');
|
|
@@ -20,79 +19,6 @@ var initialState = {
|
|
|
20
19
|
orderedListDisabled: false,
|
|
21
20
|
decorationSet: DecorationSet.empty
|
|
22
21
|
};
|
|
23
|
-
export var computeListDecorations = function computeListDecorations(doc) {
|
|
24
|
-
var from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
25
|
-
var to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : doc.content.size;
|
|
26
|
-
var decorations = [];
|
|
27
|
-
|
|
28
|
-
// this stack keeps track of each (nested) list to calculate the indentation level
|
|
29
|
-
var processedListsStack = [];
|
|
30
|
-
doc.nodesBetween(from, to, function (node, currentNodeStartPos) {
|
|
31
|
-
if (processedListsStack.length > 0) {
|
|
32
|
-
var isOutsideLastList = true;
|
|
33
|
-
while (isOutsideLastList && processedListsStack.length > 0) {
|
|
34
|
-
var lastList = processedListsStack[processedListsStack.length - 1];
|
|
35
|
-
var lastListEndPos = lastList.startPos + lastList.node.nodeSize;
|
|
36
|
-
isOutsideLastList = currentNodeStartPos >= lastListEndPos;
|
|
37
|
-
// once we finish iterating over each innermost list, pop the stack to
|
|
38
|
-
// decrease the indent level attribute accordingly
|
|
39
|
-
if (isOutsideLastList) {
|
|
40
|
-
processedListsStack.pop();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (isListNode(node)) {
|
|
45
|
-
processedListsStack.push({
|
|
46
|
-
node: node,
|
|
47
|
-
startPos: currentNodeStartPos
|
|
48
|
-
});
|
|
49
|
-
var _from = currentNodeStartPos;
|
|
50
|
-
var _to = currentNodeStartPos + node.nodeSize;
|
|
51
|
-
var depth = processedListsStack.length;
|
|
52
|
-
decorations.push(Decoration.node(_from, _to, {
|
|
53
|
-
'data-indent-level': "".concat(depth)
|
|
54
|
-
}));
|
|
55
|
-
if (node.type.name === 'orderedList') {
|
|
56
|
-
var _node$attrs;
|
|
57
|
-
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
58
|
-
// spacing to account for the extra digit chars
|
|
59
|
-
var digitsSize = getItemCounterDigitsSize({
|
|
60
|
-
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
61
|
-
order: node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
62
|
-
});
|
|
63
|
-
if (digitsSize && digitsSize > 1) {
|
|
64
|
-
decorations.push(Decoration.node(_from, _to, {
|
|
65
|
-
style: getOrderedListInlineStyles(digitsSize, 'string')
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
return decorations;
|
|
72
|
-
};
|
|
73
|
-
export var updateListDecorations = function updateListDecorations(decorationSet, tr) {
|
|
74
|
-
var nextDecorationSet = decorationSet.map(tr.mapping, tr.doc);
|
|
75
|
-
tr.mapping.maps.forEach(function (stepMap, index) {
|
|
76
|
-
stepMap.forEach(function (oldStart, oldEnd) {
|
|
77
|
-
var start = tr.mapping.slice(index).map(oldStart, -1);
|
|
78
|
-
var end = tr.mapping.slice(index).map(oldEnd);
|
|
79
|
-
|
|
80
|
-
// Remove decorations in this range
|
|
81
|
-
var decorationsToRemove = nextDecorationSet.find(start, end);
|
|
82
|
-
nextDecorationSet = nextDecorationSet.remove(decorationsToRemove);
|
|
83
|
-
|
|
84
|
-
// Recompute decorations for this range
|
|
85
|
-
// Expand the range by 1 on each side to catch adjacent list nodes
|
|
86
|
-
var from = Math.max(0, start - 1);
|
|
87
|
-
var to = Math.min(tr.doc.content.size, end + 1);
|
|
88
|
-
var decorationsToAdd = computeListDecorations(tr.doc, from, to);
|
|
89
|
-
nextDecorationSet = nextDecorationSet.add(tr.doc, decorationsToAdd);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
return nextDecorationSet;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// delete getDecorations during platform_editor_new_list_decorations_logic experiment clean up
|
|
96
22
|
export var getDecorations = function getDecorations(doc, state, featureFlags) {
|
|
97
23
|
var decorations = [];
|
|
98
24
|
|
|
@@ -124,12 +50,12 @@ export var getDecorations = function getDecorations(doc, state, featureFlags) {
|
|
|
124
50
|
'data-indent-level': "".concat(depth)
|
|
125
51
|
}));
|
|
126
52
|
if (node.type.name === 'orderedList') {
|
|
127
|
-
var _node$
|
|
53
|
+
var _node$attrs;
|
|
128
54
|
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
129
55
|
// spacing to account for the extra digit chars
|
|
130
56
|
var digitsSize = getItemCounterDigitsSize({
|
|
131
57
|
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
132
|
-
order: node === null || node === void 0 || (_node$
|
|
58
|
+
order: node === null || node === void 0 || (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
133
59
|
});
|
|
134
60
|
if (digitsSize && digitsSize > 1) {
|
|
135
61
|
decorations.push(Decoration.node(from, to, {
|
|
@@ -192,15 +118,8 @@ var reducer = function reducer() {
|
|
|
192
118
|
var createInitialState = function createInitialState(featureFlags, api) {
|
|
193
119
|
return function (state) {
|
|
194
120
|
var isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar);
|
|
195
|
-
var getInitialDecorations = function getInitialDecorations() {
|
|
196
|
-
var _insm$session, _insm$session2;
|
|
197
|
-
(_insm$session = insm.session) === null || _insm$session === void 0 || _insm$session.startFeature('listDecorationsInit');
|
|
198
|
-
var decorations = computeListDecorations(state.doc);
|
|
199
|
-
(_insm$session2 = insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('listDecorationsInit');
|
|
200
|
-
return decorations;
|
|
201
|
-
};
|
|
202
121
|
return _objectSpread(_objectSpread({}, isToolbarAIFCEnabled && expValEquals('platform_editor_toolbar_aifc_patch_3', 'isEnabled', true) ? getListState(state.doc, state.selection) : initialState), {}, {
|
|
203
|
-
decorationSet:
|
|
122
|
+
decorationSet: getDecorations(state.doc, state, featureFlags)
|
|
204
123
|
});
|
|
205
124
|
};
|
|
206
125
|
};
|
|
@@ -211,39 +130,13 @@ export var createPlugin = function createPlugin(eventDispatch, featureFlags, api
|
|
|
211
130
|
}),
|
|
212
131
|
getPluginState = _pluginFactory.getPluginState,
|
|
213
132
|
createPluginState = _pluginFactory.createPluginState;
|
|
214
|
-
var pluginState = createPluginState(eventDispatch, createInitialState(featureFlags, api));
|
|
215
|
-
var pluginStateInit = function pluginStateInit(_, state) {
|
|
216
|
-
return createInitialState(featureFlags)(state);
|
|
217
|
-
};
|
|
218
|
-
var pluginStateApply = function pluginStateApply(tr, oldPluginState, _oldEditorState, _newEditorState) {
|
|
219
|
-
var nextPluginState = oldPluginState;
|
|
220
|
-
if (tr.docChanged) {
|
|
221
|
-
var _insm$session3, _insm$session4;
|
|
222
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
223
|
-
(_insm$session3 = insm.session) === null || _insm$session3 === void 0 || _insm$session3.startFeature('listDecorationUpdate');
|
|
224
|
-
var nextDecorationSet = updateListDecorations(nextPluginState.decorationSet, tr);
|
|
225
|
-
(_insm$session4 = insm.session) === null || _insm$session4 === void 0 || _insm$session4.endFeature('listDecorationUpdate');
|
|
226
|
-
nextPluginState = _objectSpread(_objectSpread({}, nextPluginState), {}, {
|
|
227
|
-
decorationSet: nextDecorationSet
|
|
228
|
-
});
|
|
229
|
-
} else if (tr.selectionSet) {
|
|
230
|
-
nextPluginState = handleSelectionChanged(tr, nextPluginState);
|
|
231
|
-
}
|
|
232
|
-
if (nextPluginState !== oldPluginState) {
|
|
233
|
-
eventDispatch(listPluginKey, nextPluginState);
|
|
234
|
-
}
|
|
235
|
-
return nextPluginState;
|
|
236
|
-
};
|
|
237
133
|
return new SafePlugin({
|
|
238
|
-
state:
|
|
239
|
-
init: expValEquals('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateInit : pluginState.init,
|
|
240
|
-
apply: expValEquals('platform_editor_new_list_decorations_logic', 'isEnabled', true) ? pluginStateApply : pluginState.apply
|
|
241
|
-
},
|
|
134
|
+
state: createPluginState(eventDispatch, createInitialState(featureFlags, api)),
|
|
242
135
|
key: listPluginKey,
|
|
243
136
|
props: {
|
|
244
137
|
decorations: function decorations(state) {
|
|
245
|
-
var
|
|
246
|
-
decorationSet =
|
|
138
|
+
var _getPluginState = getPluginState(state),
|
|
139
|
+
decorationSet = _getPluginState.decorationSet;
|
|
247
140
|
return decorationSet;
|
|
248
141
|
},
|
|
249
142
|
handleClick: function handleClick(view, pos, event) {
|
|
@@ -3,12 +3,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
|
3
3
|
import type { ExtractInjectionAPI, FeatureFlags } from '@atlaskit/editor-common/types';
|
|
4
4
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
-
import type { EditorState
|
|
7
|
-
import {
|
|
6
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import type { ListPlugin } from '../listPluginType';
|
|
9
9
|
import type { ListState } from '../types';
|
|
10
10
|
export declare const pluginKey: PluginKey<ListState>;
|
|
11
|
-
export declare const computeListDecorations: (doc: Node, from?: number, to?: number) => Decoration[];
|
|
12
|
-
export declare const updateListDecorations: (decorationSet: DecorationSet, tr: ReadonlyTransaction) => DecorationSet;
|
|
13
11
|
export declare const getDecorations: (doc: Node, state: EditorState, featureFlags: FeatureFlags) => DecorationSet;
|
|
14
12
|
export declare const createPlugin: (eventDispatch: Dispatch, featureFlags: FeatureFlags, api?: ExtractInjectionAPI<ListPlugin>) => SafePlugin;
|
|
@@ -3,12 +3,10 @@ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
|
3
3
|
import type { ExtractInjectionAPI, FeatureFlags } from '@atlaskit/editor-common/types';
|
|
4
4
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
-
import type { EditorState
|
|
7
|
-
import {
|
|
6
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import type { ListPlugin } from '../listPluginType';
|
|
9
9
|
import type { ListState } from '../types';
|
|
10
10
|
export declare const pluginKey: PluginKey<ListState>;
|
|
11
|
-
export declare const computeListDecorations: (doc: Node, from?: number, to?: number) => Decoration[];
|
|
12
|
-
export declare const updateListDecorations: (decorationSet: DecorationSet, tr: ReadonlyTransaction) => DecorationSet;
|
|
13
11
|
export declare const getDecorations: (doc: Node, state: EditorState, featureFlags: FeatureFlags) => DecorationSet;
|
|
14
12
|
export declare const createPlugin: (eventDispatch: Dispatch, featureFlags: FeatureFlags, api?: ExtractInjectionAPI<ListPlugin>) => SafePlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-list",
|
|
3
|
-
"version": "8.2.
|
|
3
|
+
"version": "8.2.20",
|
|
4
4
|
"description": "List plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,23 +27,22 @@
|
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"atlaskit:src": "src/index.ts",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@atlaskit/adf-schema": "^51.5.
|
|
30
|
+
"@atlaskit/adf-schema": "^51.5.0",
|
|
31
31
|
"@atlaskit/editor-plugin-analytics": "^6.2.0",
|
|
32
|
-
"@atlaskit/editor-plugin-block-menu": "^5.
|
|
32
|
+
"@atlaskit/editor-plugin-block-menu": "^5.2.0",
|
|
33
33
|
"@atlaskit/editor-plugin-feature-flags": "^5.0.0",
|
|
34
34
|
"@atlaskit/editor-plugin-toolbar": "^3.4.0",
|
|
35
|
-
"@atlaskit/editor-prosemirror": "7.
|
|
35
|
+
"@atlaskit/editor-prosemirror": "^7.2.0",
|
|
36
36
|
"@atlaskit/editor-toolbar": "^0.18.0",
|
|
37
|
-
"@atlaskit/icon": "^29.
|
|
38
|
-
"@atlaskit/insm": "^0.2.0",
|
|
37
|
+
"@atlaskit/icon": "^29.3.0",
|
|
39
38
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
40
39
|
"@atlaskit/prosemirror-history": "^0.2.0",
|
|
41
40
|
"@atlaskit/prosemirror-input-rules": "^3.6.0",
|
|
42
|
-
"@atlaskit/tmp-editor-statsig": "^15.
|
|
41
|
+
"@atlaskit/tmp-editor-statsig": "^15.15.0",
|
|
43
42
|
"@babel/runtime": "^7.0.0"
|
|
44
43
|
},
|
|
45
44
|
"peerDependencies": {
|
|
46
|
-
"@atlaskit/editor-common": "^110.
|
|
45
|
+
"@atlaskit/editor-common": "^110.46.0",
|
|
47
46
|
"react": "^18.2.0",
|
|
48
47
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
49
48
|
},
|
|
@@ -83,9 +82,6 @@
|
|
|
83
82
|
}
|
|
84
83
|
},
|
|
85
84
|
"platform-feature-flags": {
|
|
86
|
-
"platform_editor_split_list_item_for_gap_cursor": {
|
|
87
|
-
"type": "boolean"
|
|
88
|
-
},
|
|
89
85
|
"platform_editor_adf_with_localid": {
|
|
90
86
|
"type": "boolean"
|
|
91
87
|
}
|