@atlaskit/editor-core 189.3.29 → 189.3.31
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 +13 -0
- package/dist/cjs/plugins/index.js +0 -7
- package/dist/cjs/presets/universal.js +2 -1
- package/dist/cjs/utils/document.js +0 -6
- package/dist/cjs/utils/index.js +0 -6
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/plugins/index.js +0 -1
- package/dist/es2019/presets/universal.js +2 -1
- package/dist/es2019/utils/document.js +1 -1
- package/dist/es2019/utils/index.js +1 -1
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/plugins/index.js +0 -1
- package/dist/esm/presets/universal.js +2 -1
- package/dist/esm/utils/document.js +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/plugins/index.d.ts +0 -1
- package/dist/types/plugins/insert-block/types.d.ts +2 -2
- package/dist/types/plugins/toolbar-lists-indentation/index.d.ts +2 -2
- package/dist/types/utils/document.d.ts +1 -1
- package/dist/types/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/index.d.ts +0 -1
- package/dist/types-ts4.5/plugins/insert-block/types.d.ts +2 -2
- package/dist/types-ts4.5/plugins/toolbar-lists-indentation/index.d.ts +2 -2
- package/dist/types-ts4.5/utils/document.d.ts +1 -1
- package/dist/types-ts4.5/utils/index.d.ts +1 -1
- package/package.json +4 -4
- package/dist/cjs/plugins/tasks-and-decisions/commands.js +0 -288
- package/dist/cjs/plugins/tasks-and-decisions/index.js +0 -166
- package/dist/cjs/plugins/tasks-and-decisions/nodeviews/decisionItem.js +0 -117
- package/dist/cjs/plugins/tasks-and-decisions/nodeviews/hooks/use-show-placeholder.js +0 -40
- package/dist/cjs/plugins/tasks-and-decisions/nodeviews/taskItem.js +0 -211
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/commands.js +0 -96
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/helpers.js +0 -299
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/input-rules.js +0 -94
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/keymaps.js +0 -376
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/main.js +0 -263
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/plugin-key.js +0 -8
- package/dist/cjs/plugins/tasks-and-decisions/pm-plugins/types.js +0 -11
- package/dist/cjs/plugins/tasks-and-decisions/types.js +0 -5
- package/dist/cjs/plugins/tasks-and-decisions/ui/Decision/index.js +0 -51
- package/dist/cjs/plugins/tasks-and-decisions/ui/Task/index.js +0 -80
- package/dist/cjs/plugins/tasks-and-decisions/ui/Task/task-item-with-providers.js +0 -137
- package/dist/cjs/plugins/tasks-and-decisions/ui/ToolbarDecision/index.js +0 -76
- package/dist/cjs/plugins/tasks-and-decisions/ui/ToolbarTask/index.js +0 -75
- package/dist/cjs/plugins/tasks-and-decisions/utils.js +0 -41
- package/dist/es2019/plugins/tasks-and-decisions/commands.js +0 -279
- package/dist/es2019/plugins/tasks-and-decisions/index.js +0 -155
- package/dist/es2019/plugins/tasks-and-decisions/nodeviews/decisionItem.js +0 -76
- package/dist/es2019/plugins/tasks-and-decisions/nodeviews/hooks/use-show-placeholder.js +0 -36
- package/dist/es2019/plugins/tasks-and-decisions/nodeviews/taskItem.js +0 -173
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/commands.js +0 -94
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/helpers.js +0 -316
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/input-rules.js +0 -91
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/keymaps.js +0 -370
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/main.js +0 -262
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/plugin-key.js +0 -2
- package/dist/es2019/plugins/tasks-and-decisions/pm-plugins/types.js +0 -5
- package/dist/es2019/plugins/tasks-and-decisions/types.js +0 -1
- package/dist/es2019/plugins/tasks-and-decisions/ui/Decision/index.js +0 -30
- package/dist/es2019/plugins/tasks-and-decisions/ui/Task/index.js +0 -54
- package/dist/es2019/plugins/tasks-and-decisions/ui/Task/task-item-with-providers.js +0 -71
- package/dist/es2019/plugins/tasks-and-decisions/ui/ToolbarDecision/index.js +0 -52
- package/dist/es2019/plugins/tasks-and-decisions/ui/ToolbarTask/index.js +0 -51
- package/dist/es2019/plugins/tasks-and-decisions/utils.js +0 -32
- package/dist/esm/plugins/tasks-and-decisions/commands.js +0 -281
- package/dist/esm/plugins/tasks-and-decisions/index.js +0 -156
- package/dist/esm/plugins/tasks-and-decisions/nodeviews/decisionItem.js +0 -110
- package/dist/esm/plugins/tasks-and-decisions/nodeviews/hooks/use-show-placeholder.js +0 -34
- package/dist/esm/plugins/tasks-and-decisions/nodeviews/taskItem.js +0 -204
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/commands.js +0 -90
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/helpers.js +0 -285
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/input-rules.js +0 -87
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/keymaps.js +0 -368
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/main.js +0 -256
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/plugin-key.js +0 -2
- package/dist/esm/plugins/tasks-and-decisions/pm-plugins/types.js +0 -5
- package/dist/esm/plugins/tasks-and-decisions/types.js +0 -1
- package/dist/esm/plugins/tasks-and-decisions/ui/Decision/index.js +0 -44
- package/dist/esm/plugins/tasks-and-decisions/ui/Task/index.js +0 -70
- package/dist/esm/plugins/tasks-and-decisions/ui/Task/task-item-with-providers.js +0 -128
- package/dist/esm/plugins/tasks-and-decisions/ui/ToolbarDecision/index.js +0 -66
- package/dist/esm/plugins/tasks-and-decisions/ui/ToolbarTask/index.js +0 -65
- package/dist/esm/plugins/tasks-and-decisions/utils.js +0 -30
- package/dist/types/plugins/tasks-and-decisions/commands.d.ts +0 -16
- package/dist/types/plugins/tasks-and-decisions/index.d.ts +0 -3
- package/dist/types/plugins/tasks-and-decisions/nodeviews/decisionItem.d.ts +0 -10
- package/dist/types/plugins/tasks-and-decisions/nodeviews/hooks/use-show-placeholder.d.ts +0 -11
- package/dist/types/plugins/tasks-and-decisions/nodeviews/taskItem.d.ts +0 -14
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/commands.d.ts +0 -15
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/helpers.d.ts +0 -76
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/input-rules.d.ts +0 -6
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/keymaps.d.ts +0 -11
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/main.d.ts +0 -7
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/plugin-key.d.ts +0 -2
- package/dist/types/plugins/tasks-and-decisions/pm-plugins/types.d.ts +0 -8
- package/dist/types/plugins/tasks-and-decisions/types.d.ts +0 -49
- package/dist/types/plugins/tasks-and-decisions/ui/Decision/index.d.ts +0 -14
- package/dist/types/plugins/tasks-and-decisions/ui/Task/index.d.ts +0 -28
- package/dist/types/plugins/tasks-and-decisions/ui/Task/task-item-with-providers.d.ts +0 -29
- package/dist/types/plugins/tasks-and-decisions/ui/ToolbarDecision/index.d.ts +0 -23
- package/dist/types/plugins/tasks-and-decisions/ui/ToolbarTask/index.d.ts +0 -23
- package/dist/types/plugins/tasks-and-decisions/utils.d.ts +0 -4
- package/dist/types-ts4.5/plugins/tasks-and-decisions/commands.d.ts +0 -16
- package/dist/types-ts4.5/plugins/tasks-and-decisions/index.d.ts +0 -3
- package/dist/types-ts4.5/plugins/tasks-and-decisions/nodeviews/decisionItem.d.ts +0 -10
- package/dist/types-ts4.5/plugins/tasks-and-decisions/nodeviews/hooks/use-show-placeholder.d.ts +0 -11
- package/dist/types-ts4.5/plugins/tasks-and-decisions/nodeviews/taskItem.d.ts +0 -14
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/commands.d.ts +0 -15
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/helpers.d.ts +0 -76
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/input-rules.d.ts +0 -6
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/keymaps.d.ts +0 -11
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/main.d.ts +0 -7
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/plugin-key.d.ts +0 -2
- package/dist/types-ts4.5/plugins/tasks-and-decisions/pm-plugins/types.d.ts +0 -8
- package/dist/types-ts4.5/plugins/tasks-and-decisions/types.d.ts +0 -49
- package/dist/types-ts4.5/plugins/tasks-and-decisions/ui/Decision/index.d.ts +0 -14
- package/dist/types-ts4.5/plugins/tasks-and-decisions/ui/Task/index.d.ts +0 -28
- package/dist/types-ts4.5/plugins/tasks-and-decisions/ui/Task/task-item-with-providers.d.ts +0 -29
- package/dist/types-ts4.5/plugins/tasks-and-decisions/ui/ToolbarDecision/index.d.ts +0 -23
- package/dist/types-ts4.5/plugins/tasks-and-decisions/ui/ToolbarTask/index.d.ts +0 -23
- package/dist/types-ts4.5/plugins/tasks-and-decisions/utils.d.ts +0 -4
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { AnalyticsListener } from '@atlaskit/analytics-next';
|
|
4
|
-
import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
5
|
-
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
6
|
-
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
7
|
-
import { useShowPlaceholder } from './hooks/use-show-placeholder';
|
|
8
|
-
import TaskItem from '../ui/Task';
|
|
9
|
-
const TaskItemWrapper = ({
|
|
10
|
-
localId,
|
|
11
|
-
forwardRef,
|
|
12
|
-
isDone,
|
|
13
|
-
onChange,
|
|
14
|
-
providerFactory,
|
|
15
|
-
isContentNodeEmpty,
|
|
16
|
-
api,
|
|
17
|
-
getPos,
|
|
18
|
-
editorView
|
|
19
|
-
}) => {
|
|
20
|
-
const {
|
|
21
|
-
taskDecisionState
|
|
22
|
-
} = useSharedPluginState(api, ['taskDecision']);
|
|
23
|
-
const isFocused = Boolean((taskDecisionState === null || taskDecisionState === void 0 ? void 0 : taskDecisionState.focusedTaskItemLocalId) === localId);
|
|
24
|
-
const showPlaceholder = useShowPlaceholder({
|
|
25
|
-
editorView,
|
|
26
|
-
isContentNodeEmpty,
|
|
27
|
-
getPos,
|
|
28
|
-
api
|
|
29
|
-
});
|
|
30
|
-
return /*#__PURE__*/React.createElement(TaskItem, {
|
|
31
|
-
taskId: localId,
|
|
32
|
-
contentRef: forwardRef,
|
|
33
|
-
isDone: isDone,
|
|
34
|
-
onChange: onChange,
|
|
35
|
-
isFocused: isFocused,
|
|
36
|
-
showPlaceholder: showPlaceholder,
|
|
37
|
-
providers: providerFactory
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
class Task extends ReactNodeView {
|
|
41
|
-
constructor(...args) {
|
|
42
|
-
super(...args);
|
|
43
|
-
_defineProperty(this, "handleOnChange", (taskId, isChecked) => {
|
|
44
|
-
const {
|
|
45
|
-
tr
|
|
46
|
-
} = this.view.state;
|
|
47
|
-
const nodePos = this.getPos();
|
|
48
|
-
if (typeof nodePos !== 'number') {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// SetAttrsStep should be used to prevent task updates from being dropped when mapping task ticks
|
|
53
|
-
// from a previous version of the document, such as a published page.
|
|
54
|
-
tr.step(new SetAttrsStep(nodePos, {
|
|
55
|
-
state: isChecked ? 'DONE' : 'TODO',
|
|
56
|
-
localId: taskId
|
|
57
|
-
}));
|
|
58
|
-
tr.setMeta('scrollIntoView', false);
|
|
59
|
-
this.view.dispatch(tr);
|
|
60
|
-
});
|
|
61
|
-
/**
|
|
62
|
-
* Dynamically generates analytics data relating to the parent list.
|
|
63
|
-
*
|
|
64
|
-
* Required to be dynamic, as list (in prosemirror model) may have
|
|
65
|
-
* changed (e.g. item movements, or additional items in list).
|
|
66
|
-
* This node view will have not rerendered for those changes, so
|
|
67
|
-
* cannot render the position and listSize into the
|
|
68
|
-
* AnalyticsContext at initial render time.
|
|
69
|
-
*/
|
|
70
|
-
_defineProperty(this, "addListAnalyticsData", event => {
|
|
71
|
-
try {
|
|
72
|
-
const nodePos = this.getPos();
|
|
73
|
-
if (typeof nodePos !== 'number') {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
const resolvedPos = this.view.state.doc.resolve(nodePos);
|
|
77
|
-
const position = resolvedPos.index();
|
|
78
|
-
const listSize = resolvedPos.parent.childCount;
|
|
79
|
-
const listLocalId = resolvedPos.parent.attrs.localId;
|
|
80
|
-
event.update(payload => {
|
|
81
|
-
const {
|
|
82
|
-
attributes = {},
|
|
83
|
-
actionSubject
|
|
84
|
-
} = payload;
|
|
85
|
-
if (actionSubject !== 'action') {
|
|
86
|
-
// Not action related, ignore
|
|
87
|
-
return payload;
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
...payload,
|
|
91
|
-
attributes: {
|
|
92
|
-
...attributes,
|
|
93
|
-
position,
|
|
94
|
-
listSize,
|
|
95
|
-
listLocalId
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
});
|
|
99
|
-
} catch (e) {
|
|
100
|
-
// This can occur if pos is NaN (seen it in some test cases)
|
|
101
|
-
// Act defensively here, and lose some analytics data rather than
|
|
102
|
-
// cause any user facing error.
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
initWithAPI(api) {
|
|
107
|
-
this.api = api;
|
|
108
|
-
this.init();
|
|
109
|
-
return this;
|
|
110
|
-
}
|
|
111
|
-
isContentEmpty(node) {
|
|
112
|
-
return node.content.childCount === 0;
|
|
113
|
-
}
|
|
114
|
-
createDomRef() {
|
|
115
|
-
const domRef = document.createElement('div');
|
|
116
|
-
domRef.style['list-style-type'] = 'none';
|
|
117
|
-
return domRef;
|
|
118
|
-
}
|
|
119
|
-
getContentDOM() {
|
|
120
|
-
const dom = document.createElement('div');
|
|
121
|
-
// setting a className prevents PM/Chrome mutation observer from
|
|
122
|
-
// incorrectly deleting nodes
|
|
123
|
-
dom.className = 'task-item';
|
|
124
|
-
return {
|
|
125
|
-
dom
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
render(props, forwardRef) {
|
|
129
|
-
const {
|
|
130
|
-
localId,
|
|
131
|
-
state
|
|
132
|
-
} = this.node.attrs;
|
|
133
|
-
const isContentNodeEmpty = this.isContentEmpty(this.node);
|
|
134
|
-
return /*#__PURE__*/React.createElement(AnalyticsListener, {
|
|
135
|
-
channel: "fabric-elements",
|
|
136
|
-
onEvent: this.addListAnalyticsData
|
|
137
|
-
}, /*#__PURE__*/React.createElement(TaskItemWrapper, {
|
|
138
|
-
localId: localId,
|
|
139
|
-
forwardRef: forwardRef,
|
|
140
|
-
isDone: state === 'DONE',
|
|
141
|
-
onChange: this.handleOnChange,
|
|
142
|
-
isContentNodeEmpty: isContentNodeEmpty,
|
|
143
|
-
providerFactory: props.providerFactory
|
|
144
|
-
// The getPosHandler type is wrong, there is no `boolean` in the real implementation
|
|
145
|
-
// @ts-expect-error 2322: Type 'getPosHandler' is not assignable to type '() => number | undefined'.
|
|
146
|
-
,
|
|
147
|
-
getPos: this.getPos,
|
|
148
|
-
editorView: this.view,
|
|
149
|
-
api: this.api
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
viewShouldUpdate(nextNode) {
|
|
153
|
-
/**
|
|
154
|
-
* To ensure the placeholder is correctly toggled we need to allow react to re-render
|
|
155
|
-
* on first character insertion.
|
|
156
|
-
* Note: last character deletion is handled externally and automatically re-renders.
|
|
157
|
-
*/
|
|
158
|
-
return this.isContentEmpty(this.node) && !!nextNode.content.childCount;
|
|
159
|
-
}
|
|
160
|
-
update(node, decorations) {
|
|
161
|
-
return super.update(node, decorations, undefined, (currentNode, newNode) =>
|
|
162
|
-
// Toggle the placeholder based on whether user input exists
|
|
163
|
-
!this.isContentEmpty(newNode) && !!(currentNode.attrs.state === newNode.attrs.state));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
export function taskItemNodeViewFactory(portalProviderAPI, eventDispatcher, providerFactory, api) {
|
|
167
|
-
return (node, view, getPos) => {
|
|
168
|
-
const hasIntlContext = true;
|
|
169
|
-
return new Task(node, view, getPos, portalProviderAPI, eventDispatcher, {
|
|
170
|
-
providerFactory
|
|
171
|
-
}, undefined, undefined, undefined, hasIntlContext).initWithAPI(api);
|
|
172
|
-
};
|
|
173
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { findWrapping, ReplaceAroundStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
-
import { findCutBefore } from '@atlaskit/editor-common/commands';
|
|
3
|
-
import { getBlockRange, isActionOrDecisionItem, isActionOrDecisionList, liftBlock, subtreeHeight } from './helpers';
|
|
4
|
-
import { normalizeTaskItemsSelection } from '../utils';
|
|
5
|
-
export const liftSelection = (state, dispatch) => {
|
|
6
|
-
const normalizedSelection = normalizeTaskItemsSelection(state.selection);
|
|
7
|
-
const {
|
|
8
|
-
$from,
|
|
9
|
-
$to
|
|
10
|
-
} = normalizedSelection;
|
|
11
|
-
const tr = liftBlock(state.tr, $from, $to);
|
|
12
|
-
if (dispatch && tr) {
|
|
13
|
-
dispatch(tr);
|
|
14
|
-
}
|
|
15
|
-
return !!tr;
|
|
16
|
-
};
|
|
17
|
-
export const wrapSelectionInTaskList = (state, dispatch) => {
|
|
18
|
-
const {
|
|
19
|
-
$from,
|
|
20
|
-
$to
|
|
21
|
-
} = normalizeTaskItemsSelection(state.selection);
|
|
22
|
-
|
|
23
|
-
// limit ui indentation to 6 levels
|
|
24
|
-
const {
|
|
25
|
-
taskList,
|
|
26
|
-
taskItem
|
|
27
|
-
} = state.schema.nodes;
|
|
28
|
-
const maxDepth = subtreeHeight($from, $to, [taskList, taskItem]);
|
|
29
|
-
if (maxDepth >= 6) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
const blockRange = getBlockRange($from, $to);
|
|
33
|
-
if (!blockRange) {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
const wrapping = findWrapping(blockRange, state.schema.nodes.taskList);
|
|
37
|
-
if (!wrapping) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
if (dispatch) {
|
|
41
|
-
dispatch(state.tr.wrap(blockRange, wrapping).scrollIntoView());
|
|
42
|
-
}
|
|
43
|
-
return true;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Tries to move the paragraph content near the given position into the taskItem or decisionItem
|
|
48
|
-
* before it.
|
|
49
|
-
*
|
|
50
|
-
* Looks backwards from the given position to find the "cut point" between the last taskItem and the
|
|
51
|
-
* following paragraph. Then tries to move the content from that paragraph into the taskItem.
|
|
52
|
-
*
|
|
53
|
-
* @param $pos Position at the end of, or anywhere in paragraph following, the last taskItem
|
|
54
|
-
* @see {joinToPreviousListItem}
|
|
55
|
-
*/
|
|
56
|
-
export const joinAtCut = $pos => (state, dispatch) => {
|
|
57
|
-
const $cut = findCutBefore($pos);
|
|
58
|
-
if (!$cut) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
const {
|
|
62
|
-
paragraph
|
|
63
|
-
} = $cut.doc.type.schema.nodes;
|
|
64
|
-
|
|
65
|
-
// find the boundary between the taskList and paragraph
|
|
66
|
-
if ($cut.nodeBefore && isActionOrDecisionList($cut.nodeBefore) && $cut.nodeAfter && $cut.nodeAfter.type === paragraph) {
|
|
67
|
-
// we'll find the boundary of a taskList
|
|
68
|
-
// so resolve -1 to find the inside end of the last taskItem
|
|
69
|
-
let $lastNode = $cut.doc.resolve($cut.pos - 1);
|
|
70
|
-
|
|
71
|
-
// might have deeply nested taskList, keep trying to find it
|
|
72
|
-
while (!isActionOrDecisionItem($lastNode.parent)) {
|
|
73
|
-
$lastNode = state.doc.resolve($lastNode.pos - 1);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// grab the structure between the taskItem and the paragraph
|
|
77
|
-
// note: structure = true in ReplaceAroundStep
|
|
78
|
-
const slice = state.tr.doc.slice($lastNode.pos, $cut.pos);
|
|
79
|
-
|
|
80
|
-
// collapse the range between end of last taskItem and after the paragraph
|
|
81
|
-
// with the gap being the paragraph's content (i.e. take that content)
|
|
82
|
-
//
|
|
83
|
-
// we pass the structure we found earlier to join the p and taskItem nodes
|
|
84
|
-
//
|
|
85
|
-
// see https://prosemirror.net/docs/ref/#transform.ReplaceStep.constructor
|
|
86
|
-
// see https://prosemirror.net/docs/ref/#transform.ReplaceAroundStep.constructor
|
|
87
|
-
const tr = state.tr.step(new ReplaceAroundStep($lastNode.pos, $cut.pos + $cut.nodeAfter.nodeSize, $cut.pos + 1, $cut.pos + $cut.nodeAfter.nodeSize - 1, slice, 0, true));
|
|
88
|
-
if (dispatch) {
|
|
89
|
-
dispatch(tr);
|
|
90
|
-
}
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
return false;
|
|
94
|
-
};
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
-
import { liftTarget } from '@atlaskit/editor-prosemirror/transform';
|
|
3
|
-
import { findParentNodeClosestToPos, hasParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
-
import { findFarthestParentNode } from '../../../utils';
|
|
5
|
-
import { stateKey } from './plugin-key';
|
|
6
|
-
import { ACTIONS } from './types';
|
|
7
|
-
export const isInsideTaskOrDecisionItem = state => {
|
|
8
|
-
const {
|
|
9
|
-
decisionItem,
|
|
10
|
-
taskItem
|
|
11
|
-
} = state.schema.nodes;
|
|
12
|
-
return hasParentNodeOfType([decisionItem, taskItem])(state.selection);
|
|
13
|
-
};
|
|
14
|
-
export const isActionOrDecisionList = node => {
|
|
15
|
-
const {
|
|
16
|
-
taskList,
|
|
17
|
-
decisionList
|
|
18
|
-
} = node.type.schema.nodes;
|
|
19
|
-
return [taskList, decisionList].indexOf(node.type) > -1;
|
|
20
|
-
};
|
|
21
|
-
export const isActionOrDecisionItem = node => {
|
|
22
|
-
const {
|
|
23
|
-
taskItem,
|
|
24
|
-
decisionItem
|
|
25
|
-
} = node.type.schema.nodes;
|
|
26
|
-
return [taskItem, decisionItem].indexOf(node.type) > -1;
|
|
27
|
-
};
|
|
28
|
-
export const isInsideTask = state => {
|
|
29
|
-
const {
|
|
30
|
-
taskItem
|
|
31
|
-
} = state.schema.nodes;
|
|
32
|
-
return hasParentNodeOfType([taskItem])(state.selection);
|
|
33
|
-
};
|
|
34
|
-
export const isInsideDecision = state => {
|
|
35
|
-
const {
|
|
36
|
-
decisionItem
|
|
37
|
-
} = state.schema.nodes;
|
|
38
|
-
return hasParentNodeOfType([decisionItem])(state.selection);
|
|
39
|
-
};
|
|
40
|
-
export const isTable = node => {
|
|
41
|
-
if (!node) {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
const {
|
|
45
|
-
table,
|
|
46
|
-
tableHeader,
|
|
47
|
-
tableCell,
|
|
48
|
-
tableRow
|
|
49
|
-
} = node.type.schema.nodes;
|
|
50
|
-
return [table, tableHeader, tableCell, tableRow].includes(node.type);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Creates a NodeRange around the given taskItem and the following
|
|
55
|
-
* ("nested") taskList, if one exists.
|
|
56
|
-
*/
|
|
57
|
-
export const getBlockRange = ($from, $to) => {
|
|
58
|
-
const {
|
|
59
|
-
taskList
|
|
60
|
-
} = $from.doc.type.schema.nodes;
|
|
61
|
-
let end = $to.end();
|
|
62
|
-
const $after = $to.doc.resolve(end + 1);
|
|
63
|
-
const after = $after.nodeAfter;
|
|
64
|
-
|
|
65
|
-
// ensure the node after is actually just a sibling
|
|
66
|
-
// $to will be inside the text, so subtract one to get the taskItem it contains in
|
|
67
|
-
if (after && after.type === taskList && $after.depth === $to.depth - 1) {
|
|
68
|
-
// it was! include it in our blockRange
|
|
69
|
-
end += after.nodeSize;
|
|
70
|
-
}
|
|
71
|
-
return $from.blockRange($to.doc.resolve(end));
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Finds the distance between the current $from and the root of the taskList.
|
|
76
|
-
*/
|
|
77
|
-
export const getCurrentIndentLevel = selection => {
|
|
78
|
-
const {
|
|
79
|
-
$from
|
|
80
|
-
} = selection;
|
|
81
|
-
const {
|
|
82
|
-
taskList
|
|
83
|
-
} = $from.doc.type.schema.nodes;
|
|
84
|
-
const furthestParent = findFarthestParentNode(node => node.type === taskList)($from);
|
|
85
|
-
if (!furthestParent) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
return $from.depth - furthestParent.depth;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Finds the index of the current task item in relation to the closest taskList
|
|
93
|
-
*/
|
|
94
|
-
export const getTaskItemIndex = state => {
|
|
95
|
-
const $pos = state.selection.$from;
|
|
96
|
-
const isTaskList = node => (node === null || node === void 0 ? void 0 : node.type.name) === 'taskList';
|
|
97
|
-
const itemAtPos = findParentNodeClosestToPos($pos, isTaskList);
|
|
98
|
-
return $pos.index(itemAtPos ? itemAtPos.depth : undefined);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Walk outwards from a position until we encounter the (inside) start of
|
|
103
|
-
* the next node, or reach the end of the document.
|
|
104
|
-
*
|
|
105
|
-
* @param $startPos Position to start walking from.
|
|
106
|
-
*/
|
|
107
|
-
export const walkOut = $startPos => {
|
|
108
|
-
let $pos = $startPos;
|
|
109
|
-
|
|
110
|
-
// invariant 1: don't walk past the end of the document
|
|
111
|
-
// invariant 2: we haven't walked to the start of *any* node
|
|
112
|
-
// parentOffset includes textOffset.
|
|
113
|
-
while ($pos.pos < $pos.doc.nodeSize - 2 && $pos.parentOffset > 0) {
|
|
114
|
-
$pos = $pos.doc.resolve($pos.pos + 1);
|
|
115
|
-
}
|
|
116
|
-
return $pos;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Finds the height of a tree-like structure, given any position inside it.
|
|
121
|
-
*
|
|
122
|
-
* Traverses from the top of the tree to all leaf nodes, and returns the length
|
|
123
|
-
* of the longest path.
|
|
124
|
-
*
|
|
125
|
-
* This means you can use it with things like taskList, which
|
|
126
|
-
* do not nest themselves inside taskItems but rather as adjacent children.
|
|
127
|
-
*
|
|
128
|
-
* @param $pos Any position inside the tree.
|
|
129
|
-
* @param types The node types to consider traversable
|
|
130
|
-
*/
|
|
131
|
-
export const subtreeHeight = ($from, $to, types) => {
|
|
132
|
-
const root = findFarthestParentNode(node => types.indexOf(node.type) > -1)($from);
|
|
133
|
-
if (!root) {
|
|
134
|
-
return -1;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// get the height between the root and the current position
|
|
138
|
-
const distToParent = $from.depth - root.depth;
|
|
139
|
-
|
|
140
|
-
// include any following taskList since nested lists appear
|
|
141
|
-
// as siblings
|
|
142
|
-
//
|
|
143
|
-
// this is unlike regular bullet lists where the orderedList
|
|
144
|
-
// appears as descendent of listItem
|
|
145
|
-
const blockRange = getBlockRange($from, $to);
|
|
146
|
-
if (!blockRange) {
|
|
147
|
-
return -1;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// and get the max height from the current position to the
|
|
151
|
-
// deepest leaf node
|
|
152
|
-
let maxChildDepth = $from.depth;
|
|
153
|
-
$from.doc.nodesBetween(blockRange.start, blockRange.end, (descendent, relPos, parent) => {
|
|
154
|
-
maxChildDepth = Math.max($from.doc.resolve(relPos).depth, maxChildDepth);
|
|
155
|
-
|
|
156
|
-
// keep descending down the tree if we can
|
|
157
|
-
if (types.indexOf(descendent.type) > -1) {
|
|
158
|
-
return true;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
return distToParent + (maxChildDepth - $from.depth);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Returns `true` if the taskItem or decisionItem has no text.
|
|
166
|
-
*/
|
|
167
|
-
export const isEmptyTaskDecision = state => {
|
|
168
|
-
const {
|
|
169
|
-
selection,
|
|
170
|
-
schema
|
|
171
|
-
} = state;
|
|
172
|
-
const {
|
|
173
|
-
$from
|
|
174
|
-
} = selection;
|
|
175
|
-
const node = $from.node($from.depth);
|
|
176
|
-
return node && (node.type === schema.nodes.taskItem || node.type === schema.nodes.decisionItem) && node.content.size === 0;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Lifts a taskItem and any directly following taskList
|
|
181
|
-
* (taskItem and its "nested children") out one level.
|
|
182
|
-
*
|
|
183
|
-
* @param tr Transaction to base steps on
|
|
184
|
-
* @param $from Start of range you want to lift
|
|
185
|
-
* @param $to End of range you want to lift (can be same as `$from`)
|
|
186
|
-
*/
|
|
187
|
-
export const liftBlock = (tr, $from, $to) => {
|
|
188
|
-
const blockRange = getBlockRange($from, $to);
|
|
189
|
-
if (!blockRange) {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// ensure we can actually lift
|
|
194
|
-
const target = liftTarget(blockRange);
|
|
195
|
-
if (typeof target !== 'number') {
|
|
196
|
-
return null;
|
|
197
|
-
}
|
|
198
|
-
return tr.lift(blockRange, target).scrollIntoView();
|
|
199
|
-
};
|
|
200
|
-
export function getTaskItemDataAtPos(view) {
|
|
201
|
-
const {
|
|
202
|
-
state
|
|
203
|
-
} = view;
|
|
204
|
-
const {
|
|
205
|
-
selection,
|
|
206
|
-
schema
|
|
207
|
-
} = state;
|
|
208
|
-
const {
|
|
209
|
-
$from
|
|
210
|
-
} = selection;
|
|
211
|
-
const isInTaskItem = $from.node().type === schema.nodes.taskItem;
|
|
212
|
-
|
|
213
|
-
// current selection has to be inside taskitem
|
|
214
|
-
if (isInTaskItem) {
|
|
215
|
-
const taskItemPos = $from.before();
|
|
216
|
-
return {
|
|
217
|
-
pos: taskItemPos,
|
|
218
|
-
localId: $from.node().attrs.localId
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
export function getAllTaskItemsDataInRootTaskList(view) {
|
|
223
|
-
const {
|
|
224
|
-
state
|
|
225
|
-
} = view;
|
|
226
|
-
const {
|
|
227
|
-
schema
|
|
228
|
-
} = state;
|
|
229
|
-
const $fromPos = state.selection.$from;
|
|
230
|
-
const isInTaskItem = $fromPos.node().type === schema.nodes.taskItem;
|
|
231
|
-
// if not inside task item then return undefined;
|
|
232
|
-
if (!isInTaskItem) {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const {
|
|
236
|
-
taskList,
|
|
237
|
-
taskItem
|
|
238
|
-
} = schema.nodes;
|
|
239
|
-
const rootTaskListData = findFarthestParentNode(node => node.type === taskList)($fromPos);
|
|
240
|
-
if (rootTaskListData) {
|
|
241
|
-
const rootTaskList = rootTaskListData.node;
|
|
242
|
-
const rootTaskListStartPos = rootTaskListData.start;
|
|
243
|
-
const allTaskItems = [];
|
|
244
|
-
rootTaskList.descendants((node, pos, parent, index) => {
|
|
245
|
-
if (node.type === taskItem) {
|
|
246
|
-
allTaskItems.push({
|
|
247
|
-
node,
|
|
248
|
-
pos: pos + rootTaskListStartPos,
|
|
249
|
-
index
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
return allTaskItems;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
export function getCurrentTaskItemIndex(view, allTaskItems) {
|
|
257
|
-
const {
|
|
258
|
-
state
|
|
259
|
-
} = view;
|
|
260
|
-
const $fromPos = state.selection.$from;
|
|
261
|
-
const allTaskItemNodes = allTaskItems.map(nodeData => nodeData.node);
|
|
262
|
-
const currentTaskItem = $fromPos.node($fromPos.depth);
|
|
263
|
-
const currentTaskItemIndex = allTaskItemNodes.indexOf(currentTaskItem);
|
|
264
|
-
return currentTaskItemIndex;
|
|
265
|
-
}
|
|
266
|
-
export function getTaskItemDataToFocus(view, direction) {
|
|
267
|
-
const allTaskItems = getAllTaskItemsDataInRootTaskList(view);
|
|
268
|
-
// if not inside task item then allTaskItems will be undefined;
|
|
269
|
-
if (!allTaskItems) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const currentTaskItemIndex = getCurrentTaskItemIndex(view, allTaskItems);
|
|
273
|
-
if (direction === 'next' ? currentTaskItemIndex === allTaskItems.length - 1 : currentTaskItemIndex === 0) {
|
|
274
|
-
// checkbox of first or last task item is already focused based on direction.
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
const indexOfTaskItemToFocus = direction === 'next' ? currentTaskItemIndex + 1 : currentTaskItemIndex - 1;
|
|
278
|
-
const taskItemToFocus = allTaskItems[indexOfTaskItemToFocus];
|
|
279
|
-
return {
|
|
280
|
-
pos: taskItemToFocus.pos,
|
|
281
|
-
localId: taskItemToFocus.node.attrs.localId
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
export function focusCheckboxAndUpdateSelection(view, taskItemData) {
|
|
285
|
-
const {
|
|
286
|
-
pos,
|
|
287
|
-
localId
|
|
288
|
-
} = taskItemData;
|
|
289
|
-
const {
|
|
290
|
-
state,
|
|
291
|
-
dispatch
|
|
292
|
-
} = view;
|
|
293
|
-
const {
|
|
294
|
-
doc,
|
|
295
|
-
tr
|
|
296
|
-
} = state;
|
|
297
|
-
tr.setSelection(new TextSelection(doc.resolve(pos + 1)));
|
|
298
|
-
tr.setMeta(stateKey, {
|
|
299
|
-
action: ACTIONS.FOCUS_BY_LOCALID,
|
|
300
|
-
data: localId
|
|
301
|
-
});
|
|
302
|
-
dispatch(tr);
|
|
303
|
-
}
|
|
304
|
-
export function removeCheckboxFocus(view) {
|
|
305
|
-
const {
|
|
306
|
-
state,
|
|
307
|
-
dispatch
|
|
308
|
-
} = view;
|
|
309
|
-
const {
|
|
310
|
-
tr
|
|
311
|
-
} = state;
|
|
312
|
-
view.focus();
|
|
313
|
-
dispatch(tr.setMeta(stateKey, {
|
|
314
|
-
action: ACTIONS.FOCUS_BY_LOCALID
|
|
315
|
-
}));
|
|
316
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
-
import { canInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
-
import { createRule, createPlugin, leafNodeReplacementCharacter } from '@atlaskit/prosemirror-input-rules';
|
|
4
|
-
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
|
-
import { changeInDepth, insertTaskDecisionAction, getListTypes } from '../commands';
|
|
6
|
-
const createListRule = editorAnalyticsAPI => (regex, listType, itemAttrs) => {
|
|
7
|
-
return createRule(regex, (state, _match, start, end) => {
|
|
8
|
-
const {
|
|
9
|
-
paragraph
|
|
10
|
-
} = state.schema.nodes;
|
|
11
|
-
const {
|
|
12
|
-
list
|
|
13
|
-
} = getListTypes(listType, state.schema);
|
|
14
|
-
const $end = state.doc.resolve(end);
|
|
15
|
-
const $endOfParent = state.doc.resolve($end.after());
|
|
16
|
-
// Only allow creating list in nodes that support them.
|
|
17
|
-
// Parent must be a paragraph as we don't want this applying to headings
|
|
18
|
-
if ($end.parent.type !== paragraph || !canInsert($endOfParent, list.createAndFill())) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
const insertTr = insertTaskDecisionAction(editorAnalyticsAPI)(state, listType, INPUT_METHOD.FORMATTING, addItem(start, end), undefined, undefined, itemAttrs);
|
|
22
|
-
return insertTr;
|
|
23
|
-
});
|
|
24
|
-
};
|
|
25
|
-
const addItem = (start, end) => ({
|
|
26
|
-
tr,
|
|
27
|
-
state,
|
|
28
|
-
list,
|
|
29
|
-
item,
|
|
30
|
-
listLocalId,
|
|
31
|
-
itemLocalId,
|
|
32
|
-
itemAttrs
|
|
33
|
-
}) => {
|
|
34
|
-
const {
|
|
35
|
-
selection: {
|
|
36
|
-
$from
|
|
37
|
-
},
|
|
38
|
-
schema
|
|
39
|
-
} = state;
|
|
40
|
-
const {
|
|
41
|
-
hardBreak
|
|
42
|
-
} = schema.nodes;
|
|
43
|
-
const content = $from.node($from.depth).content;
|
|
44
|
-
let shouldBreakNode = false;
|
|
45
|
-
content.forEach((node, offset) => {
|
|
46
|
-
if (node.type === hardBreak && offset < start) {
|
|
47
|
-
shouldBreakNode = true;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
if (!shouldBreakNode) {
|
|
51
|
-
tr.replaceRangeWith($from.before(), $from.after(), list.create({
|
|
52
|
-
localId: listLocalId
|
|
53
|
-
}, [item.create({
|
|
54
|
-
localId: itemLocalId,
|
|
55
|
-
...itemAttrs
|
|
56
|
-
}, content)])).delete(start + 1, end + 1).setSelection(new TextSelection(tr.doc.resolve(start + 1)));
|
|
57
|
-
} else {
|
|
58
|
-
const depthAdjustment = changeInDepth($from, tr.selection.$from);
|
|
59
|
-
tr.split($from.pos).setSelection(new NodeSelection(tr.doc.resolve($from.pos + 1))).replaceSelectionWith(list.create({
|
|
60
|
-
localId: listLocalId
|
|
61
|
-
}, [item.create({
|
|
62
|
-
localId: itemLocalId,
|
|
63
|
-
...itemAttrs
|
|
64
|
-
},
|
|
65
|
-
// TODO: [ts30] handle void and null properly
|
|
66
|
-
tr.doc.nodeAt($from.pos + 1).content)])).setSelection(new TextSelection(tr.doc.resolve($from.pos + depthAdjustment))).delete(start, end + 1);
|
|
67
|
-
}
|
|
68
|
-
return tr;
|
|
69
|
-
};
|
|
70
|
-
export const inputRulePlugin = editorAnalyticsAPI => (schema, featureFlags) => {
|
|
71
|
-
const rules = [];
|
|
72
|
-
const {
|
|
73
|
-
decisionList,
|
|
74
|
-
decisionItem,
|
|
75
|
-
taskList,
|
|
76
|
-
taskItem
|
|
77
|
-
} = schema.nodes;
|
|
78
|
-
if (decisionList && decisionItem) {
|
|
79
|
-
rules.push(createListRule(editorAnalyticsAPI)(new RegExp(`(^|${leafNodeReplacementCharacter})\\<\\>\\s$`), 'decisionList'));
|
|
80
|
-
}
|
|
81
|
-
if (taskList && taskItem) {
|
|
82
|
-
rules.push(createListRule(editorAnalyticsAPI)(new RegExp(`(^|${leafNodeReplacementCharacter})\\[\\]\\s$`), 'taskList'));
|
|
83
|
-
rules.push(createListRule(editorAnalyticsAPI)(new RegExp(`(^|${leafNodeReplacementCharacter})\\[x\\]\\s$`), 'taskList', {
|
|
84
|
-
state: 'DONE'
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
return createPlugin('tasks-and-decisions', rules, {
|
|
88
|
-
isBlockNodeRule: true
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
export default inputRulePlugin;
|