@atlaskit/editor-plugin-list 0.2.0 → 1.0.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/.eslintrc.js +14 -0
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/cjs/actions/conversions.js +153 -0
- package/dist/cjs/actions/indent-list-items-selected.js +125 -0
- package/dist/cjs/actions/indent-list.js +49 -0
- package/dist/cjs/actions/join-list-items-forward.js +59 -0
- package/dist/cjs/actions/join-list-items-scenarios/index.js +40 -0
- package/dist/cjs/actions/join-list-items-scenarios/join-list-item-with-paragraph.js +88 -0
- package/dist/cjs/actions/join-list-items-scenarios/join-list-item-with-parent-nested-list.js +85 -0
- package/dist/cjs/actions/join-list-items-scenarios/join-nested-list-with-parent-list-item.js +79 -0
- package/dist/cjs/actions/join-list-items-scenarios/join-paragraph-with-list.js +45 -0
- package/dist/cjs/actions/join-list-items-scenarios/join-sibling-list-items.js +56 -0
- package/dist/cjs/actions/merge-lists.js +27 -0
- package/dist/cjs/actions/outdent-list-items-selected.js +291 -0
- package/dist/cjs/actions/wrap-and-join-lists.js +100 -0
- package/dist/cjs/commands/indent-list.js +71 -0
- package/dist/cjs/commands/index.js +350 -0
- package/dist/cjs/commands/isFirstChildOfParent.js +12 -0
- package/dist/cjs/commands/join-list-item-forward.js +61 -0
- package/dist/cjs/commands/listBackspace.js +284 -0
- package/dist/cjs/commands/outdent-list.js +70 -0
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/messages.js +37 -0
- package/dist/cjs/plugin.js +133 -0
- package/dist/cjs/pm-plugins/input-rules/create-list-input-rule.js +63 -0
- package/dist/cjs/pm-plugins/input-rules/index.js +38 -0
- package/dist/cjs/pm-plugins/input-rules/wrapping-join-rule.js +60 -0
- package/dist/cjs/pm-plugins/keymap.js +27 -0
- package/dist/cjs/pm-plugins/main.js +166 -0
- package/dist/cjs/transforms.js +99 -0
- package/dist/cjs/types.js +4 -1
- package/dist/cjs/utils/analytics.js +22 -0
- package/dist/cjs/utils/find.js +68 -0
- package/dist/cjs/utils/indentation.js +22 -0
- package/dist/cjs/utils/mark.js +40 -0
- package/dist/cjs/utils/node.js +16 -0
- package/dist/cjs/utils/selection.js +95 -0
- package/dist/es2019/actions/conversions.js +160 -0
- package/dist/es2019/actions/indent-list-items-selected.js +124 -0
- package/dist/es2019/actions/indent-list.js +44 -0
- package/dist/es2019/actions/join-list-items-forward.js +54 -0
- package/dist/es2019/actions/join-list-items-scenarios/index.js +5 -0
- package/dist/es2019/actions/join-list-items-scenarios/join-list-item-with-paragraph.js +74 -0
- package/dist/es2019/actions/join-list-items-scenarios/join-list-item-with-parent-nested-list.js +77 -0
- package/dist/es2019/actions/join-list-items-scenarios/join-nested-list-with-parent-list-item.js +71 -0
- package/dist/es2019/actions/join-list-items-scenarios/join-paragraph-with-list.js +37 -0
- package/dist/es2019/actions/join-list-items-scenarios/join-sibling-list-items.js +48 -0
- package/dist/es2019/actions/merge-lists.js +24 -0
- package/dist/es2019/actions/outdent-list-items-selected.js +295 -0
- package/dist/es2019/actions/wrap-and-join-lists.js +93 -0
- package/dist/es2019/commands/indent-list.js +62 -0
- package/dist/es2019/commands/index.js +326 -0
- package/dist/es2019/commands/isFirstChildOfParent.js +7 -0
- package/dist/es2019/commands/join-list-item-forward.js +53 -0
- package/dist/es2019/commands/listBackspace.js +276 -0
- package/dist/es2019/commands/outdent-list.js +60 -0
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/messages.js +29 -0
- package/dist/es2019/plugin.js +121 -0
- package/dist/es2019/pm-plugins/input-rules/create-list-input-rule.js +56 -0
- package/dist/es2019/pm-plugins/input-rules/index.js +35 -0
- package/dist/es2019/pm-plugins/input-rules/wrapping-join-rule.js +55 -0
- package/dist/es2019/pm-plugins/keymap.js +19 -0
- package/dist/es2019/pm-plugins/main.js +156 -0
- package/dist/es2019/transforms.js +101 -0
- package/dist/es2019/types.js +1 -1
- package/dist/es2019/utils/analytics.js +12 -0
- package/dist/es2019/utils/find.js +61 -0
- package/dist/es2019/utils/indentation.js +15 -0
- package/dist/es2019/utils/mark.js +30 -0
- package/dist/es2019/utils/node.js +12 -0
- package/dist/es2019/utils/selection.js +96 -0
- package/dist/esm/actions/conversions.js +147 -0
- package/dist/esm/actions/indent-list-items-selected.js +117 -0
- package/dist/esm/actions/indent-list.js +43 -0
- package/dist/esm/actions/join-list-items-forward.js +52 -0
- package/dist/esm/actions/join-list-items-scenarios/index.js +5 -0
- package/dist/esm/actions/join-list-items-scenarios/join-list-item-with-paragraph.js +81 -0
- package/dist/esm/actions/join-list-items-scenarios/join-list-item-with-parent-nested-list.js +78 -0
- package/dist/esm/actions/join-list-items-scenarios/join-nested-list-with-parent-list-item.js +72 -0
- package/dist/esm/actions/join-list-items-scenarios/join-paragraph-with-list.js +38 -0
- package/dist/esm/actions/join-list-items-scenarios/join-sibling-list-items.js +49 -0
- package/dist/esm/actions/merge-lists.js +21 -0
- package/dist/esm/actions/outdent-list-items-selected.js +283 -0
- package/dist/esm/actions/wrap-and-join-lists.js +94 -0
- package/dist/esm/commands/indent-list.js +63 -0
- package/dist/esm/commands/index.js +324 -0
- package/dist/esm/commands/isFirstChildOfParent.js +5 -0
- package/dist/esm/commands/join-list-item-forward.js +53 -0
- package/dist/esm/commands/listBackspace.js +275 -0
- package/dist/esm/commands/outdent-list.js +62 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/messages.js +29 -0
- package/dist/esm/plugin.js +126 -0
- package/dist/esm/pm-plugins/input-rules/create-list-input-rule.js +57 -0
- package/dist/esm/pm-plugins/input-rules/index.js +32 -0
- package/dist/esm/pm-plugins/input-rules/wrapping-join-rule.js +54 -0
- package/dist/esm/pm-plugins/keymap.js +19 -0
- package/dist/esm/pm-plugins/main.js +156 -0
- package/dist/esm/transforms.js +91 -0
- package/dist/esm/types.js +1 -1
- package/dist/esm/utils/analytics.js +12 -0
- package/dist/esm/utils/find.js +59 -0
- package/dist/esm/utils/indentation.js +15 -0
- package/dist/esm/utils/mark.js +33 -0
- package/dist/esm/utils/node.js +10 -0
- package/dist/esm/utils/selection.js +81 -0
- package/dist/types/actions/conversions.d.ts +6 -0
- package/dist/types/actions/indent-list-items-selected.d.ts +2 -0
- package/dist/types/actions/indent-list.d.ts +2 -0
- package/dist/types/actions/join-list-items-forward.d.ts +13 -0
- package/dist/types/actions/join-list-items-scenarios/index.d.ts +5 -0
- package/dist/types/actions/join-list-items-scenarios/join-list-item-with-paragraph.d.ts +9 -0
- package/dist/types/actions/join-list-items-scenarios/join-list-item-with-parent-nested-list.d.ts +9 -0
- package/dist/types/actions/join-list-items-scenarios/join-nested-list-with-parent-list-item.d.ts +9 -0
- package/dist/types/actions/join-list-items-scenarios/join-paragraph-with-list.d.ts +9 -0
- package/dist/types/actions/join-list-items-scenarios/join-sibling-list-items.d.ts +9 -0
- package/dist/types/actions/merge-lists.d.ts +7 -0
- package/dist/types/actions/outdent-list-items-selected.d.ts +3 -0
- package/dist/types/actions/wrap-and-join-lists.d.ts +17 -0
- package/dist/types/commands/indent-list.d.ts +6 -0
- package/dist/types/commands/index.d.ts +16 -0
- package/dist/types/commands/isFirstChildOfParent.d.ts +2 -0
- package/dist/types/commands/join-list-item-forward.d.ts +3 -0
- package/dist/types/commands/listBackspace.d.ts +10 -0
- package/dist/types/commands/outdent-list.d.ts +6 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/messages.d.ts +27 -0
- package/dist/types/plugin.d.ts +2 -0
- package/dist/types/pm-plugins/input-rules/create-list-input-rule.d.ts +11 -0
- package/dist/types/pm-plugins/input-rules/index.d.ts +5 -0
- package/dist/types/pm-plugins/input-rules/wrapping-join-rule.d.ts +13 -0
- package/dist/types/pm-plugins/keymap.d.ts +5 -0
- package/dist/types/pm-plugins/main.d.ts +11 -0
- package/dist/types/transforms.d.ts +4 -0
- package/dist/types/types.d.ts +4 -6
- package/dist/types/utils/analytics.d.ts +5 -0
- package/dist/types/utils/find.d.ts +10 -0
- package/dist/types/utils/indentation.d.ts +2 -0
- package/dist/types/utils/mark.d.ts +8 -0
- package/dist/types/utils/node.d.ts +2 -0
- package/dist/types/utils/selection.d.ts +14 -0
- package/dist/types-ts4.5/actions/conversions.d.ts +6 -0
- package/dist/types-ts4.5/actions/indent-list-items-selected.d.ts +2 -0
- package/dist/types-ts4.5/actions/indent-list.d.ts +2 -0
- package/dist/types-ts4.5/actions/join-list-items-forward.d.ts +16 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/index.d.ts +5 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/join-list-item-with-paragraph.d.ts +9 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/join-list-item-with-parent-nested-list.d.ts +9 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/join-nested-list-with-parent-list-item.d.ts +9 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/join-paragraph-with-list.d.ts +9 -0
- package/dist/types-ts4.5/actions/join-list-items-scenarios/join-sibling-list-items.d.ts +9 -0
- package/dist/types-ts4.5/actions/merge-lists.d.ts +7 -0
- package/dist/types-ts4.5/actions/outdent-list-items-selected.d.ts +3 -0
- package/dist/types-ts4.5/actions/wrap-and-join-lists.d.ts +17 -0
- package/dist/types-ts4.5/commands/indent-list.d.ts +6 -0
- package/dist/types-ts4.5/commands/index.d.ts +16 -0
- package/dist/types-ts4.5/commands/isFirstChildOfParent.d.ts +2 -0
- package/dist/types-ts4.5/commands/join-list-item-forward.d.ts +3 -0
- package/dist/types-ts4.5/commands/listBackspace.d.ts +13 -0
- package/dist/types-ts4.5/commands/outdent-list.d.ts +6 -0
- package/dist/types-ts4.5/index.d.ts +2 -1
- package/dist/types-ts4.5/messages.d.ts +27 -0
- package/dist/types-ts4.5/plugin.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/input-rules/create-list-input-rule.d.ts +11 -0
- package/dist/types-ts4.5/pm-plugins/input-rules/index.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/input-rules/wrapping-join-rule.d.ts +13 -0
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +11 -0
- package/dist/types-ts4.5/transforms.d.ts +4 -0
- package/dist/types-ts4.5/types.d.ts +4 -6
- package/dist/types-ts4.5/utils/analytics.d.ts +5 -0
- package/dist/types-ts4.5/utils/find.d.ts +10 -0
- package/dist/types-ts4.5/utils/indentation.d.ts +2 -0
- package/dist/types-ts4.5/utils/mark.d.ts +8 -0
- package/dist/types-ts4.5/utils/node.d.ts +2 -0
- package/dist/types-ts4.5/utils/selection.d.ts +14 -0
- package/package.json +8 -5
- package/report.api.md +6 -2
- package/tmp/api-report-tmp.d.ts +4 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, OUTDENT_SCENARIOS } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { getCommonListAnalyticsAttributes } from '@atlaskit/editor-common/lists';
|
|
3
|
+
import { isBulletList } from '@atlaskit/editor-common/utils';
|
|
4
|
+
import { closeHistory } from '@atlaskit/editor-prosemirror/history';
|
|
5
|
+
import { outdentListItemsSelected as outdentListAction } from '../actions/outdent-list-items-selected';
|
|
6
|
+
import { getRestartListsAttributes } from '../utils/analytics';
|
|
7
|
+
import { findFirstParentListNode } from '../utils/find';
|
|
8
|
+
import { isInsideListItem, isInsideTableCell } from '../utils/selection';
|
|
9
|
+
export const outdentList = editorAnalyticsAPI => (inputMethod = INPUT_METHOD.KEYBOARD, featureFlags) => {
|
|
10
|
+
return function (state, dispatch) {
|
|
11
|
+
if (!isInsideListItem(state)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const {
|
|
15
|
+
$from
|
|
16
|
+
} = state.selection;
|
|
17
|
+
const parentListNode = findFirstParentListNode($from);
|
|
18
|
+
if (!parentListNode) {
|
|
19
|
+
// Even though this is a non-operation, we don't want to send this event to the browser. Because if we return false, the browser will move the focus to another place
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Save the history, so it could undo/revert to the same state before the outdent, see https://product-fabric.atlassian.net/browse/ED-14753
|
|
24
|
+
closeHistory(state.tr);
|
|
25
|
+
const actionSubjectId = isBulletList(parentListNode.node) ? ACTION_SUBJECT_ID.FORMAT_LIST_BULLET : ACTION_SUBJECT_ID.FORMAT_LIST_NUMBER;
|
|
26
|
+
let customTr = state.tr;
|
|
27
|
+
outdentListAction(customTr, state, featureFlags);
|
|
28
|
+
if (!customTr || !customTr.docChanged) {
|
|
29
|
+
// Even though this is a non-operation, we don't want to send this event to the browser. Because if we return false, the browser will move the focus to another place
|
|
30
|
+
// If inside table cell and can't outdent list, then let it handle by table keymap
|
|
31
|
+
return !isInsideTableCell(state);
|
|
32
|
+
}
|
|
33
|
+
const restartListsAttributes = {};
|
|
34
|
+
if (featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists) {
|
|
35
|
+
const {
|
|
36
|
+
outdentScenario,
|
|
37
|
+
splitListStartNumber
|
|
38
|
+
} = getRestartListsAttributes(customTr);
|
|
39
|
+
if (outdentScenario === OUTDENT_SCENARIOS.SPLIT_LIST) {
|
|
40
|
+
restartListsAttributes.outdentScenario = outdentScenario;
|
|
41
|
+
restartListsAttributes.splitListStartNumber = splitListStartNumber;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
45
|
+
action: ACTION.OUTDENTED,
|
|
46
|
+
actionSubject: ACTION_SUBJECT.LIST,
|
|
47
|
+
actionSubjectId,
|
|
48
|
+
eventType: EVENT_TYPE.TRACK,
|
|
49
|
+
attributes: {
|
|
50
|
+
...getCommonListAnalyticsAttributes(state),
|
|
51
|
+
...restartListsAttributes,
|
|
52
|
+
inputMethod
|
|
53
|
+
}
|
|
54
|
+
})(customTr);
|
|
55
|
+
if (dispatch) {
|
|
56
|
+
dispatch(customTr);
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
};
|
|
60
|
+
};
|
package/dist/es2019/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export { listPlugin } from './plugin';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Common Translations will live here
|
|
2
|
+
import { defineMessages } from 'react-intl-next';
|
|
3
|
+
export const messages = defineMessages({
|
|
4
|
+
unorderedList: {
|
|
5
|
+
id: 'fabric.editor.unorderedList',
|
|
6
|
+
defaultMessage: 'Bullet list',
|
|
7
|
+
description: 'A list with bullets. Also known as an “unordered” list'
|
|
8
|
+
},
|
|
9
|
+
unorderedListDescription: {
|
|
10
|
+
id: 'fabric.editor.unorderedList.description',
|
|
11
|
+
defaultMessage: 'Create an unordered list',
|
|
12
|
+
description: ''
|
|
13
|
+
},
|
|
14
|
+
orderedList: {
|
|
15
|
+
id: 'fabric.editor.orderedList',
|
|
16
|
+
defaultMessage: 'Numbered list',
|
|
17
|
+
description: 'A list with ordered items 1… 2… 3…'
|
|
18
|
+
},
|
|
19
|
+
orderedListDescription: {
|
|
20
|
+
id: 'fabric.editor.orderedList.description',
|
|
21
|
+
defaultMessage: 'Create an ordered list',
|
|
22
|
+
description: ''
|
|
23
|
+
},
|
|
24
|
+
lists: {
|
|
25
|
+
id: 'fabric.editor.lists',
|
|
26
|
+
defaultMessage: 'Lists',
|
|
27
|
+
description: 'Menu shows ordered/bullet list and unordered/numbered lists'
|
|
28
|
+
}
|
|
29
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { bulletList, listItem, orderedList, orderedListWithOrder } from '@atlaskit/adf-schema';
|
|
3
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { toggleBulletList, toggleOrderedList, tooltip } from '@atlaskit/editor-common/keymaps';
|
|
5
|
+
import { listMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { IconList, IconListNumber } from '@atlaskit/editor-common/quick-insert';
|
|
7
|
+
import { indentList, outdentList, toggleBulletList as toggleBulletListCommand, toggleOrderedList as toggleOrderedListCommand } from './commands';
|
|
8
|
+
import inputRulePlugin from './pm-plugins/input-rules';
|
|
9
|
+
import keymapPlugin from './pm-plugins/keymap';
|
|
10
|
+
import { createPlugin, pluginKey as listPluginKey } from './pm-plugins/main';
|
|
11
|
+
import { findRootParentListNode } from './utils/find';
|
|
12
|
+
import { isInsideListItem } from './utils/selection';
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
Toolbar buttons to bullet and ordered list can be found in
|
|
16
|
+
packages/editor/editor-core/src/plugins/toolbar-lists-indentation/ui/Toolbar.tsx
|
|
17
|
+
*/
|
|
18
|
+
export const listPlugin = (options, api) => {
|
|
19
|
+
var _api$dependencies$ana;
|
|
20
|
+
const featureFlags = (api === null || api === void 0 ? void 0 : api.dependencies.featureFlags.sharedState.currentState()) || {};
|
|
21
|
+
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$dependencies$ana = api.dependencies.analytics) === null || _api$dependencies$ana === void 0 ? void 0 : _api$dependencies$ana.actions;
|
|
22
|
+
return {
|
|
23
|
+
name: 'list',
|
|
24
|
+
actions: {
|
|
25
|
+
indentList: indentList(editorAnalyticsAPI),
|
|
26
|
+
outdentList: outdentList(editorAnalyticsAPI),
|
|
27
|
+
toggleOrderedList: toggleOrderedListCommand(editorAnalyticsAPI),
|
|
28
|
+
toggleBulletList: toggleBulletListCommand(editorAnalyticsAPI),
|
|
29
|
+
isInsideListItem,
|
|
30
|
+
findRootParentListNode
|
|
31
|
+
},
|
|
32
|
+
getSharedState: editorState => {
|
|
33
|
+
if (!editorState) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return listPluginKey.getState(editorState);
|
|
37
|
+
},
|
|
38
|
+
nodes() {
|
|
39
|
+
return [{
|
|
40
|
+
name: 'bulletList',
|
|
41
|
+
node: bulletList
|
|
42
|
+
}, {
|
|
43
|
+
name: 'orderedList',
|
|
44
|
+
node: options !== null && options !== void 0 && options.restartNumberedLists ? orderedListWithOrder : orderedList
|
|
45
|
+
}, {
|
|
46
|
+
name: 'listItem',
|
|
47
|
+
node: listItem
|
|
48
|
+
}];
|
|
49
|
+
},
|
|
50
|
+
pmPlugins() {
|
|
51
|
+
return [{
|
|
52
|
+
name: 'list',
|
|
53
|
+
plugin: ({
|
|
54
|
+
dispatch
|
|
55
|
+
}) => createPlugin(dispatch, featureFlags)
|
|
56
|
+
}, {
|
|
57
|
+
name: 'listInputRule',
|
|
58
|
+
plugin: ({
|
|
59
|
+
schema,
|
|
60
|
+
featureFlags
|
|
61
|
+
}) => {
|
|
62
|
+
var _api$dependencies$ana2;
|
|
63
|
+
return inputRulePlugin(schema, featureFlags, api === null || api === void 0 ? void 0 : (_api$dependencies$ana2 = api.dependencies.analytics) === null || _api$dependencies$ana2 === void 0 ? void 0 : _api$dependencies$ana2.actions);
|
|
64
|
+
}
|
|
65
|
+
}, {
|
|
66
|
+
name: 'listKeymap',
|
|
67
|
+
plugin: () => {
|
|
68
|
+
var _api$dependencies$ana3;
|
|
69
|
+
return keymapPlugin(featureFlags, api === null || api === void 0 ? void 0 : (_api$dependencies$ana3 = api.dependencies.analytics) === null || _api$dependencies$ana3 === void 0 ? void 0 : _api$dependencies$ana3.actions);
|
|
70
|
+
}
|
|
71
|
+
}];
|
|
72
|
+
},
|
|
73
|
+
pluginsOptions: {
|
|
74
|
+
quickInsert: ({
|
|
75
|
+
formatMessage
|
|
76
|
+
}) => [{
|
|
77
|
+
id: 'unorderedList',
|
|
78
|
+
title: formatMessage(messages.unorderedList),
|
|
79
|
+
description: formatMessage(messages.unorderedListDescription),
|
|
80
|
+
keywords: ['ul', 'unordered'],
|
|
81
|
+
priority: 1100,
|
|
82
|
+
keyshortcut: tooltip(toggleBulletList),
|
|
83
|
+
icon: () => /*#__PURE__*/React.createElement(IconList, null),
|
|
84
|
+
action(insert, state) {
|
|
85
|
+
const tr = insert(state.schema.nodes.bulletList.createChecked({}, state.schema.nodes.listItem.createChecked({}, state.schema.nodes.paragraph.createChecked())));
|
|
86
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
87
|
+
action: ACTION.INSERTED,
|
|
88
|
+
actionSubject: ACTION_SUBJECT.LIST,
|
|
89
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_LIST_BULLET,
|
|
90
|
+
eventType: EVENT_TYPE.TRACK,
|
|
91
|
+
attributes: {
|
|
92
|
+
inputMethod: INPUT_METHOD.QUICK_INSERT
|
|
93
|
+
}
|
|
94
|
+
})(tr);
|
|
95
|
+
return tr;
|
|
96
|
+
}
|
|
97
|
+
}, {
|
|
98
|
+
id: 'orderedList',
|
|
99
|
+
title: formatMessage(messages.orderedList),
|
|
100
|
+
description: formatMessage(messages.orderedListDescription),
|
|
101
|
+
keywords: ['ol', 'ordered'],
|
|
102
|
+
priority: 1200,
|
|
103
|
+
keyshortcut: tooltip(toggleOrderedList),
|
|
104
|
+
icon: () => /*#__PURE__*/React.createElement(IconListNumber, null),
|
|
105
|
+
action(insert, state) {
|
|
106
|
+
const tr = insert(state.schema.nodes.orderedList.createChecked({}, state.schema.nodes.listItem.createChecked({}, state.schema.nodes.paragraph.createChecked())));
|
|
107
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
108
|
+
action: ACTION.INSERTED,
|
|
109
|
+
actionSubject: ACTION_SUBJECT.LIST,
|
|
110
|
+
actionSubjectId: ACTION_SUBJECT_ID.FORMAT_LIST_NUMBER,
|
|
111
|
+
eventType: EVENT_TYPE.TRACK,
|
|
112
|
+
attributes: {
|
|
113
|
+
inputMethod: INPUT_METHOD.QUICK_INSERT
|
|
114
|
+
}
|
|
115
|
+
})(tr);
|
|
116
|
+
return tr;
|
|
117
|
+
}
|
|
118
|
+
}]
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { inputRuleWithAnalytics as ruleWithAnalytics } from '@atlaskit/editor-common/utils';
|
|
3
|
+
import { createWrappingJoinRule } from './wrapping-join-rule';
|
|
4
|
+
const getOrder = matchResult => Number(matchResult[1]);
|
|
5
|
+
export function createRuleForListType({
|
|
6
|
+
listType,
|
|
7
|
+
expression,
|
|
8
|
+
featureFlags,
|
|
9
|
+
editorAnalyticsApi
|
|
10
|
+
}) {
|
|
11
|
+
let joinScenario = JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST.NO_JOIN;
|
|
12
|
+
const isBulletList = listType.name === 'bulletList';
|
|
13
|
+
const actionSubjectId = isBulletList ? ACTION_SUBJECT_ID.FORMAT_LIST_BULLET : ACTION_SUBJECT_ID.FORMAT_LIST_NUMBER;
|
|
14
|
+
const getAnalyticsPayload = (state, matchResult) => {
|
|
15
|
+
const analyticsPayload = {
|
|
16
|
+
action: ACTION.INSERTED,
|
|
17
|
+
actionSubject: ACTION_SUBJECT.LIST,
|
|
18
|
+
actionSubjectId,
|
|
19
|
+
eventType: EVENT_TYPE.TRACK,
|
|
20
|
+
attributes: {
|
|
21
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
if (featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists && listType === state.schema.nodes.orderedList && analyticsPayload.attributes) {
|
|
25
|
+
analyticsPayload.attributes.listStartNumber = getOrder(matchResult);
|
|
26
|
+
analyticsPayload.attributes.joinScenario = joinScenario;
|
|
27
|
+
// we reset the tracked joinScenario after storing it in the event payload
|
|
28
|
+
joinScenario = JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST.NO_JOIN;
|
|
29
|
+
}
|
|
30
|
+
return analyticsPayload;
|
|
31
|
+
};
|
|
32
|
+
const joinToNeighbourIfSameListType = (_, node, scenario) => {
|
|
33
|
+
const shouldJoin = node.type === listType;
|
|
34
|
+
if (shouldJoin) {
|
|
35
|
+
joinScenario = scenario;
|
|
36
|
+
}
|
|
37
|
+
return shouldJoin;
|
|
38
|
+
};
|
|
39
|
+
let getAttrs = {};
|
|
40
|
+
if (featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists) {
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
42
|
+
getAttrs = matchResult => {
|
|
43
|
+
return {
|
|
44
|
+
order: getOrder(matchResult)
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const inputRule = createWrappingJoinRule({
|
|
49
|
+
featureFlags,
|
|
50
|
+
match: expression,
|
|
51
|
+
nodeType: listType,
|
|
52
|
+
getAttrs,
|
|
53
|
+
joinPredicate: joinToNeighbourIfSameListType
|
|
54
|
+
});
|
|
55
|
+
return ruleWithAnalytics(getAnalyticsPayload, editorAnalyticsApi)(inputRule);
|
|
56
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createPlugin } from '@atlaskit/prosemirror-input-rules';
|
|
2
|
+
import { createRuleForListType } from './create-list-input-rule';
|
|
3
|
+
export default function inputRulePlugin(schema, featureFlags, editorAnalyticsApi) {
|
|
4
|
+
const {
|
|
5
|
+
nodes: {
|
|
6
|
+
bulletList,
|
|
7
|
+
orderedList
|
|
8
|
+
}
|
|
9
|
+
} = schema;
|
|
10
|
+
const rules = [];
|
|
11
|
+
if (bulletList) {
|
|
12
|
+
rules.push(createRuleForListType({
|
|
13
|
+
// Using UTF instead of • character
|
|
14
|
+
// because of issue where product converted the
|
|
15
|
+
// character into an escaped version.
|
|
16
|
+
expression: /^\s*([\*\-\u2022]) $/,
|
|
17
|
+
listType: bulletList,
|
|
18
|
+
featureFlags,
|
|
19
|
+
editorAnalyticsApi
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
const expression = featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists ? /((^[1-9]{1}[0-9]{0,2})|^(0))[\.\)] $/ : /^(1)[\.\)] $/;
|
|
23
|
+
if (orderedList) {
|
|
24
|
+
rules.push(createRuleForListType({
|
|
25
|
+
expression,
|
|
26
|
+
listType: orderedList,
|
|
27
|
+
featureFlags,
|
|
28
|
+
editorAnalyticsApi
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
if (rules.length !== 0) {
|
|
32
|
+
return createPlugin('lists', rules);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { canJoin, findWrapping } from '@atlaskit/editor-prosemirror/transform';
|
|
3
|
+
import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
+
import { createRule } from '@atlaskit/prosemirror-input-rules';
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
|
|
8
|
+
export const createWrappingJoinRule = ({
|
|
9
|
+
match,
|
|
10
|
+
nodeType,
|
|
11
|
+
getAttrs,
|
|
12
|
+
joinPredicate,
|
|
13
|
+
featureFlags
|
|
14
|
+
}) => {
|
|
15
|
+
const handler = (state, match, start, end) => {
|
|
16
|
+
const attrs = (getAttrs instanceof Function ? getAttrs(match) : getAttrs) || {};
|
|
17
|
+
const tr = state.tr;
|
|
18
|
+
const fixedStart = Math.max(start, 1);
|
|
19
|
+
tr.delete(fixedStart, end);
|
|
20
|
+
const $start = tr.doc.resolve(fixedStart);
|
|
21
|
+
const range = $start.blockRange();
|
|
22
|
+
const wrapping = range && findWrapping(range, nodeType, attrs);
|
|
23
|
+
if (!wrapping || !range) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const parentNodePosMapped = tr.mapping.map(range.start);
|
|
27
|
+
const parentNode = tr.doc.nodeAt(parentNodePosMapped);
|
|
28
|
+
const lastWrap = wrapping[wrapping.length - 1];
|
|
29
|
+
if (parentNode && lastWrap) {
|
|
30
|
+
const allowedMarks = lastWrap.type.allowedMarks(parentNode.marks) || [];
|
|
31
|
+
tr.setNodeMarkup(parentNodePosMapped, parentNode.type, parentNode.attrs, allowedMarks);
|
|
32
|
+
}
|
|
33
|
+
tr.wrap(range, wrapping);
|
|
34
|
+
if (featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists && nodeType === state.schema.nodes.orderedList) {
|
|
35
|
+
// if an orderedList node would be inserted by the input rule match, and
|
|
36
|
+
// that orderedList node is being added directly before another orderedList
|
|
37
|
+
// node, then join those nodes
|
|
38
|
+
const $end = tr.doc.resolve(tr.mapping.map(end));
|
|
39
|
+
const node = findParentNodeOfTypeClosestToPos($end, nodeType);
|
|
40
|
+
if (node) {
|
|
41
|
+
const nodeEnd = node.pos + node.node.nodeSize;
|
|
42
|
+
const after = tr.doc.resolve(nodeEnd).nodeAfter;
|
|
43
|
+
if (after && after.type === nodeType && canJoin(tr.doc, nodeEnd) && (!joinPredicate || joinPredicate(match, after, JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST.JOINED_TO_LIST_BELOW))) {
|
|
44
|
+
tr.join(nodeEnd);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const before = tr.doc.resolve(fixedStart - 1).nodeBefore;
|
|
49
|
+
if (before && before.type === nodeType && canJoin(tr.doc, fixedStart - 1) && (!joinPredicate || joinPredicate(match, before, JOIN_SCENARIOS_WHEN_TYPING_TO_INSERT_LIST.JOINED_TO_LIST_ABOVE))) {
|
|
50
|
+
tr.join(fixedStart - 1);
|
|
51
|
+
}
|
|
52
|
+
return tr;
|
|
53
|
+
};
|
|
54
|
+
return createRule(match, handler);
|
|
55
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { backspace, bindKeymapWithCommand, deleteKey, enter, findKeyMapForBrowser, findShortcutByKeymap, forwardDelete, indentList, outdentList, toggleBulletList, toggleOrderedList } from '@atlaskit/editor-common/keymaps';
|
|
3
|
+
import { keymap } from '@atlaskit/editor-prosemirror/keymap';
|
|
4
|
+
import { backspaceKeyCommand, deleteKeyCommand, enterKeyCommand, indentList as indentListCommand, outdentList as outdentListCommand, toggleList } from '../commands';
|
|
5
|
+
export function keymapPlugin(featureFlags, editorAnalyticsAPI) {
|
|
6
|
+
const list = {};
|
|
7
|
+
bindKeymapWithCommand(findShortcutByKeymap(toggleOrderedList), toggleList(editorAnalyticsAPI)(INPUT_METHOD.KEYBOARD, 'orderedList'), list);
|
|
8
|
+
bindKeymapWithCommand(findShortcutByKeymap(toggleBulletList), toggleList(editorAnalyticsAPI)(INPUT_METHOD.KEYBOARD, 'bulletList'), list);
|
|
9
|
+
bindKeymapWithCommand(indentList.common, indentListCommand(editorAnalyticsAPI)(INPUT_METHOD.KEYBOARD), list);
|
|
10
|
+
bindKeymapWithCommand(outdentList.common, outdentListCommand(editorAnalyticsAPI)(INPUT_METHOD.KEYBOARD, featureFlags), list);
|
|
11
|
+
bindKeymapWithCommand(enter.common, enterKeyCommand(editorAnalyticsAPI)(featureFlags), list);
|
|
12
|
+
bindKeymapWithCommand(backspace.common, backspaceKeyCommand(editorAnalyticsAPI)(featureFlags), list);
|
|
13
|
+
bindKeymapWithCommand(deleteKey.common, deleteKeyCommand(editorAnalyticsAPI), list);
|
|
14
|
+
|
|
15
|
+
// This shortcut is Mac only
|
|
16
|
+
bindKeymapWithCommand(findKeyMapForBrowser(forwardDelete), deleteKeyCommand(editorAnalyticsAPI), list);
|
|
17
|
+
return keymap(list);
|
|
18
|
+
}
|
|
19
|
+
export default keymapPlugin;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
|
+
import { setGapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
3
|
+
import { CodeBlockSharedCssClassName, getOrderedListInlineStyles, listItemCounterPadding } from '@atlaskit/editor-common/styles';
|
|
4
|
+
import { getItemCounterDigitsSize, isListNode, pluginFactory } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
7
|
+
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
8
|
+
import { isWrappingPossible } from '../utils/selection';
|
|
9
|
+
const listPluginKey = new PluginKey('listPlugin');
|
|
10
|
+
export const pluginKey = listPluginKey;
|
|
11
|
+
const initialState = {
|
|
12
|
+
bulletListActive: false,
|
|
13
|
+
bulletListDisabled: false,
|
|
14
|
+
orderedListActive: false,
|
|
15
|
+
orderedListDisabled: false,
|
|
16
|
+
decorationSet: DecorationSet.empty
|
|
17
|
+
};
|
|
18
|
+
export const getDecorations = (doc, state, featureFlags) => {
|
|
19
|
+
const decorations = [];
|
|
20
|
+
|
|
21
|
+
// this stack keeps track of each (nested) list to calculate the indentation level
|
|
22
|
+
const processedListsStack = [];
|
|
23
|
+
doc.nodesBetween(0, doc.content.size, (node, currentNodeStartPos) => {
|
|
24
|
+
if (processedListsStack.length > 0) {
|
|
25
|
+
let isOutsideLastList = true;
|
|
26
|
+
while (isOutsideLastList && processedListsStack.length > 0) {
|
|
27
|
+
const lastList = processedListsStack[processedListsStack.length - 1];
|
|
28
|
+
const lastListEndPos = lastList.startPos + lastList.node.nodeSize;
|
|
29
|
+
isOutsideLastList = currentNodeStartPos >= lastListEndPos;
|
|
30
|
+
// once we finish iterating over each innermost list, pop the stack to
|
|
31
|
+
// decrease the indent level attribute accordingly
|
|
32
|
+
if (isOutsideLastList) {
|
|
33
|
+
processedListsStack.pop();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (isListNode(node)) {
|
|
38
|
+
processedListsStack.push({
|
|
39
|
+
node,
|
|
40
|
+
startPos: currentNodeStartPos
|
|
41
|
+
});
|
|
42
|
+
const from = currentNodeStartPos;
|
|
43
|
+
const to = currentNodeStartPos + node.nodeSize;
|
|
44
|
+
const depth = processedListsStack.length;
|
|
45
|
+
decorations.push(Decoration.node(from, to, {
|
|
46
|
+
'data-indent-level': `${depth}`
|
|
47
|
+
}));
|
|
48
|
+
if (featureFlags !== null && featureFlags !== void 0 && featureFlags.restartNumberedLists) {
|
|
49
|
+
var _node$attrs;
|
|
50
|
+
// If a numbered list has item counters numbering >= 100, we'll need to add special
|
|
51
|
+
// spacing to account for the extra digit chars
|
|
52
|
+
const digitsSize = getItemCounterDigitsSize({
|
|
53
|
+
itemsCount: node === null || node === void 0 ? void 0 : node.childCount,
|
|
54
|
+
order: node === null || node === void 0 ? void 0 : (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order
|
|
55
|
+
});
|
|
56
|
+
if (digitsSize) {
|
|
57
|
+
decorations.push(Decoration.node(from, to, {
|
|
58
|
+
style: getOrderedListInlineStyles(digitsSize, 'string')
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
if (node.childCount >= 100) {
|
|
63
|
+
decorations.push(Decoration.node(from, to, {
|
|
64
|
+
'data-child-count': '100+'
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return DecorationSet.empty.add(doc, decorations);
|
|
71
|
+
};
|
|
72
|
+
const handleDocChanged = featureFlags => (tr, pluginState, editorState) => {
|
|
73
|
+
const nextPluginState = handleSelectionChanged(tr, pluginState);
|
|
74
|
+
const decorationSet = getDecorations(tr.doc, editorState, featureFlags);
|
|
75
|
+
return {
|
|
76
|
+
...nextPluginState,
|
|
77
|
+
decorationSet
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const handleSelectionChanged = (tr, pluginState) => {
|
|
81
|
+
const {
|
|
82
|
+
bulletList,
|
|
83
|
+
orderedList
|
|
84
|
+
} = tr.doc.type.schema.nodes;
|
|
85
|
+
const listParent = findParentNodeOfType([bulletList, orderedList])(tr.selection);
|
|
86
|
+
const bulletListActive = !!listParent && listParent.node.type === bulletList;
|
|
87
|
+
const orderedListActive = !!listParent && listParent.node.type === orderedList;
|
|
88
|
+
const bulletListDisabled = !(bulletListActive || orderedListActive || isWrappingPossible(bulletList, tr.selection));
|
|
89
|
+
const orderedListDisabled = !(bulletListActive || orderedListActive || isWrappingPossible(orderedList, tr.selection));
|
|
90
|
+
if (bulletListActive !== pluginState.bulletListActive || orderedListActive !== pluginState.orderedListActive || bulletListDisabled !== pluginState.bulletListDisabled || orderedListDisabled !== pluginState.orderedListDisabled) {
|
|
91
|
+
const nextPluginState = {
|
|
92
|
+
...pluginState,
|
|
93
|
+
bulletListActive,
|
|
94
|
+
orderedListActive,
|
|
95
|
+
bulletListDisabled,
|
|
96
|
+
orderedListDisabled
|
|
97
|
+
};
|
|
98
|
+
return nextPluginState;
|
|
99
|
+
}
|
|
100
|
+
return pluginState;
|
|
101
|
+
};
|
|
102
|
+
const reducer = () => state => {
|
|
103
|
+
return state;
|
|
104
|
+
};
|
|
105
|
+
const createInitialState = featureFlags => state => {
|
|
106
|
+
return {
|
|
107
|
+
...initialState,
|
|
108
|
+
decorationSet: getDecorations(state.doc, state, featureFlags)
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
export const createPlugin = (eventDispatch, featureFlags) => {
|
|
112
|
+
const {
|
|
113
|
+
getPluginState,
|
|
114
|
+
createPluginState
|
|
115
|
+
} = pluginFactory(listPluginKey, reducer(), {
|
|
116
|
+
onDocChanged: handleDocChanged(featureFlags),
|
|
117
|
+
onSelectionChanged: handleSelectionChanged
|
|
118
|
+
});
|
|
119
|
+
return new SafePlugin({
|
|
120
|
+
state: createPluginState(eventDispatch, createInitialState(featureFlags)),
|
|
121
|
+
key: listPluginKey,
|
|
122
|
+
props: {
|
|
123
|
+
decorations(state) {
|
|
124
|
+
const {
|
|
125
|
+
decorationSet
|
|
126
|
+
} = getPluginState(state);
|
|
127
|
+
return decorationSet;
|
|
128
|
+
},
|
|
129
|
+
handleClick: (view, pos, event) => {
|
|
130
|
+
const {
|
|
131
|
+
state
|
|
132
|
+
} = view;
|
|
133
|
+
if (['LI', 'UL'].includes((event === null || event === void 0 ? void 0 : event.target).tagName)) {
|
|
134
|
+
var _nodeAtPos$firstChild;
|
|
135
|
+
const nodeAtPos = state.tr.doc.nodeAt(pos);
|
|
136
|
+
const {
|
|
137
|
+
listItem,
|
|
138
|
+
codeBlock
|
|
139
|
+
} = view.state.schema.nodes;
|
|
140
|
+
if ((nodeAtPos === null || nodeAtPos === void 0 ? void 0 : nodeAtPos.type) === listItem && (nodeAtPos === null || nodeAtPos === void 0 ? void 0 : (_nodeAtPos$firstChild = nodeAtPos.firstChild) === null || _nodeAtPos$firstChild === void 0 ? void 0 : _nodeAtPos$firstChild.type) === codeBlock) {
|
|
141
|
+
var _document, _document$elementFrom;
|
|
142
|
+
const bufferPx = 50;
|
|
143
|
+
const isCodeBlockNextToListMarker = Boolean((_document = document) === null || _document === void 0 ? void 0 : (_document$elementFrom = _document.elementFromPoint(event.clientX + (listItemCounterPadding + bufferPx), event.clientY)) === null || _document$elementFrom === void 0 ? void 0 : _document$elementFrom.closest(`.${CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER}`));
|
|
144
|
+
if (isCodeBlockNextToListMarker) {
|
|
145
|
+
// +1 needed to put cursor inside li
|
|
146
|
+
// otherwise gap cursor markup will be injected as immediate child of ul resulting in invalid html
|
|
147
|
+
setGapCursorSelection(view, pos + 1, Side.LEFT);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Fragment, NodeRange, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import { liftTarget, ReplaceAroundStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
import { getListLiftTarget } from './utils/indentation';
|
|
5
|
+
function liftListItem(selection, tr) {
|
|
6
|
+
let {
|
|
7
|
+
$from,
|
|
8
|
+
$to
|
|
9
|
+
} = selection;
|
|
10
|
+
const nodeType = tr.doc.type.schema.nodes.listItem;
|
|
11
|
+
let range = $from.blockRange($to, node => !!node.childCount && !!node.firstChild && node.firstChild.type === nodeType);
|
|
12
|
+
if (!range || range.depth < 2 || $from.node(range.depth - 1).type !== nodeType) {
|
|
13
|
+
return tr;
|
|
14
|
+
}
|
|
15
|
+
let end = range.end;
|
|
16
|
+
let endOfList = $to.end(range.depth);
|
|
17
|
+
if (end < endOfList) {
|
|
18
|
+
tr.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList, new Slice(Fragment.from(nodeType.create(undefined, range.parent.copy())), 1, 0), 1, true));
|
|
19
|
+
range = new NodeRange(tr.doc.resolve($from.pos), tr.doc.resolve(endOfList), range.depth);
|
|
20
|
+
}
|
|
21
|
+
return tr.lift(range, liftTarget(range)).scrollIntoView();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Function will lift list item following selection to level-1.
|
|
25
|
+
export function liftFollowingList(from, to, rootListDepth, tr) {
|
|
26
|
+
const {
|
|
27
|
+
listItem
|
|
28
|
+
} = tr.doc.type.schema.nodes;
|
|
29
|
+
let lifted = false;
|
|
30
|
+
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
31
|
+
if (!lifted && node.type === listItem && pos > from) {
|
|
32
|
+
lifted = true;
|
|
33
|
+
let listDepth = rootListDepth + 3;
|
|
34
|
+
while (listDepth > rootListDepth + 2) {
|
|
35
|
+
const start = tr.doc.resolve(tr.mapping.map(pos));
|
|
36
|
+
listDepth = start.depth;
|
|
37
|
+
const end = tr.doc.resolve(tr.mapping.map(pos + node.textContent.length));
|
|
38
|
+
const sel = new TextSelection(start, end);
|
|
39
|
+
tr = liftListItem(sel, tr);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return tr;
|
|
44
|
+
}
|
|
45
|
+
export function liftNodeSelectionList(selection, tr) {
|
|
46
|
+
const {
|
|
47
|
+
from
|
|
48
|
+
} = selection;
|
|
49
|
+
const {
|
|
50
|
+
listItem
|
|
51
|
+
} = tr.doc.type.schema.nodes;
|
|
52
|
+
const mappedPosition = tr.mapping.map(from);
|
|
53
|
+
const nodeAtPos = tr.doc.nodeAt(mappedPosition);
|
|
54
|
+
const start = tr.doc.resolve(mappedPosition);
|
|
55
|
+
if ((start === null || start === void 0 ? void 0 : start.parent.type) !== listItem) {
|
|
56
|
+
return tr;
|
|
57
|
+
}
|
|
58
|
+
const end = tr.doc.resolve(mappedPosition + ((nodeAtPos === null || nodeAtPos === void 0 ? void 0 : nodeAtPos.nodeSize) || 1));
|
|
59
|
+
const range = start.blockRange(end);
|
|
60
|
+
if (range) {
|
|
61
|
+
const liftTarget = getListLiftTarget(start);
|
|
62
|
+
tr.lift(range, liftTarget);
|
|
63
|
+
}
|
|
64
|
+
return tr;
|
|
65
|
+
}
|
|
66
|
+
// The function will list paragraphs in selection out to level 1 below root list.
|
|
67
|
+
export function liftTextSelectionList(selection, tr) {
|
|
68
|
+
const {
|
|
69
|
+
from,
|
|
70
|
+
to
|
|
71
|
+
} = selection;
|
|
72
|
+
const {
|
|
73
|
+
paragraph
|
|
74
|
+
} = tr.doc.type.schema.nodes;
|
|
75
|
+
const listCol = [];
|
|
76
|
+
tr.doc.nodesBetween(from, to, (node, pos) => {
|
|
77
|
+
if (node.type === paragraph) {
|
|
78
|
+
listCol.push({
|
|
79
|
+
node,
|
|
80
|
+
pos
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
for (let i = listCol.length - 1; i >= 0; i--) {
|
|
85
|
+
const paragraph = listCol[i];
|
|
86
|
+
const start = tr.doc.resolve(tr.mapping.map(paragraph.pos));
|
|
87
|
+
if (start.depth > 0) {
|
|
88
|
+
let end;
|
|
89
|
+
if (paragraph.node.textContent && paragraph.node.textContent.length > 0) {
|
|
90
|
+
end = tr.doc.resolve(tr.mapping.map(paragraph.pos + paragraph.node.textContent.length));
|
|
91
|
+
} else {
|
|
92
|
+
end = tr.doc.resolve(tr.mapping.map(paragraph.pos + 1));
|
|
93
|
+
}
|
|
94
|
+
const range = start.blockRange(end);
|
|
95
|
+
if (range) {
|
|
96
|
+
tr.lift(range, getListLiftTarget(start));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return tr;
|
|
101
|
+
}
|
package/dist/es2019/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const MAX_NESTED_LIST_INDENTATION = 6;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const RESTART_LISTS_ANALYTICS_KEY = 'restartListsAnalytics';
|
|
2
|
+
export const getRestartListsAttributes = tr => {
|
|
3
|
+
var _tr$getMeta;
|
|
4
|
+
return (_tr$getMeta = tr.getMeta(RESTART_LISTS_ANALYTICS_KEY)) !== null && _tr$getMeta !== void 0 ? _tr$getMeta : {};
|
|
5
|
+
};
|
|
6
|
+
export const storeRestartListsAttributes = (tr, attributes) => {
|
|
7
|
+
const meta = getRestartListsAttributes(tr);
|
|
8
|
+
tr.setMeta(RESTART_LISTS_ANALYTICS_KEY, {
|
|
9
|
+
...meta,
|
|
10
|
+
...attributes
|
|
11
|
+
});
|
|
12
|
+
};
|