@atlaskit/editor-plugin-expand 0.1.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE.md +13 -0
  3. package/README.md +30 -0
  4. package/dist/cjs/commands.js +184 -0
  5. package/dist/cjs/index.js +12 -0
  6. package/dist/cjs/nodeviews/index.js +494 -0
  7. package/dist/cjs/plugin.js +101 -0
  8. package/dist/cjs/pm-plugins/keymap.js +170 -0
  9. package/dist/cjs/pm-plugins/main.js +85 -0
  10. package/dist/cjs/pm-plugins/plugin-factory.js +15 -0
  11. package/dist/cjs/reducer.js +20 -0
  12. package/dist/cjs/toolbar.js +59 -0
  13. package/dist/cjs/types.js +5 -0
  14. package/dist/cjs/ui/ExpandIconButton.js +107 -0
  15. package/dist/cjs/utils.js +24 -0
  16. package/dist/es2019/commands.js +161 -0
  17. package/dist/es2019/index.js +1 -0
  18. package/dist/es2019/nodeviews/index.js +484 -0
  19. package/dist/es2019/plugin.js +86 -0
  20. package/dist/es2019/pm-plugins/keymap.js +197 -0
  21. package/dist/es2019/pm-plugins/main.js +73 -0
  22. package/dist/es2019/pm-plugins/plugin-factory.js +9 -0
  23. package/dist/es2019/reducer.js +11 -0
  24. package/dist/es2019/toolbar.js +52 -0
  25. package/dist/es2019/types.js +1 -0
  26. package/dist/es2019/ui/ExpandIconButton.js +88 -0
  27. package/dist/es2019/utils.js +1 -0
  28. package/dist/esm/commands.js +177 -0
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/nodeviews/index.js +486 -0
  31. package/dist/esm/plugin.js +88 -0
  32. package/dist/esm/pm-plugins/keymap.js +165 -0
  33. package/dist/esm/pm-plugins/main.js +77 -0
  34. package/dist/esm/pm-plugins/plugin-factory.js +9 -0
  35. package/dist/esm/reducer.js +13 -0
  36. package/dist/esm/toolbar.js +52 -0
  37. package/dist/esm/types.js +1 -0
  38. package/dist/esm/ui/ExpandIconButton.js +98 -0
  39. package/dist/esm/utils.js +1 -0
  40. package/dist/types/commands.d.ts +13 -0
  41. package/dist/types/index.d.ts +3 -0
  42. package/dist/types/nodeviews/index.d.ts +55 -0
  43. package/dist/types/plugin.d.ts +24 -0
  44. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  45. package/dist/types/pm-plugins/main.d.ts +7 -0
  46. package/dist/types/pm-plugins/plugin-factory.d.ts +3 -0
  47. package/dist/types/reducer.d.ts +3 -0
  48. package/dist/types/toolbar.d.ts +3 -0
  49. package/dist/types/types.d.ts +31 -0
  50. package/dist/types/ui/ExpandIconButton.d.ts +43 -0
  51. package/dist/types/utils.d.ts +1 -0
  52. package/dist/types-ts4.5/commands.d.ts +13 -0
  53. package/dist/types-ts4.5/index.d.ts +3 -0
  54. package/dist/types-ts4.5/nodeviews/index.d.ts +55 -0
  55. package/dist/types-ts4.5/plugin.d.ts +24 -0
  56. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  57. package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
  58. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +3 -0
  59. package/dist/types-ts4.5/reducer.d.ts +3 -0
  60. package/dist/types-ts4.5/toolbar.d.ts +3 -0
  61. package/dist/types-ts4.5/types.d.ts +31 -0
  62. package/dist/types-ts4.5/ui/ExpandIconButton.d.ts +43 -0
  63. package/dist/types-ts4.5/utils.d.ts +1 -0
  64. package/package.json +104 -0
  65. package/report.api.md +93 -0
  66. package/tmp/api-report-tmp.d.ts +62 -0
@@ -0,0 +1,197 @@
1
+ import { backspace, bindKeymapWithCommand, moveDown, moveLeft, moveRight, moveUp, tab } from '@atlaskit/editor-common/keymaps';
2
+ import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
3
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
4
+ import { isPositionNearTableRow } from '@atlaskit/editor-common/utils';
5
+ import { isEmptyNode } from '@atlaskit/editor-common/utils';
6
+ import { keymap } from '@atlaskit/editor-prosemirror/keymap';
7
+ import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
8
+ import { deleteExpand, focusTitle } from '../commands';
9
+ import { findExpand } from '../utils';
10
+ const isExpandNode = node => {
11
+ return (node === null || node === void 0 ? void 0 : node.type.name) === 'expand' || (node === null || node === void 0 ? void 0 : node.type.name) === 'nestedExpand';
12
+ };
13
+ const isExpandSelected = selection => selection instanceof NodeSelection && isExpandNode(selection.node);
14
+ export function expandKeymap(api) {
15
+ const list = {};
16
+ bindKeymapWithCommand(moveRight.common, (state, dispatch, editorView) => {
17
+ if (!editorView) {
18
+ return false;
19
+ }
20
+ const {
21
+ selection
22
+ } = state;
23
+ const selectionSharedState = (api === null || api === void 0 ? void 0 : api.selection.sharedState.currentState()) || {};
24
+ const {
25
+ selectionRelativeToNode
26
+ } = selectionSharedState;
27
+ if (isExpandSelected(selection) && selectionRelativeToNode === RelativeSelectionPos.Start) {
28
+ return focusTitle(selection.from + 1)(state, dispatch, editorView);
29
+ }
30
+ return false;
31
+ }, list);
32
+ bindKeymapWithCommand(moveLeft.common, (state, dispatch, editorView) => {
33
+ if (!editorView) {
34
+ return false;
35
+ }
36
+ const {
37
+ selection
38
+ } = state;
39
+ const selectionSharedState = (api === null || api === void 0 ? void 0 : api.selection.sharedState.currentState()) || {};
40
+ const {
41
+ selectionRelativeToNode
42
+ } = selectionSharedState;
43
+ if (isExpandSelected(selection) && (selectionRelativeToNode === undefined || selectionRelativeToNode === RelativeSelectionPos.End)) {
44
+ return focusTitle(selection.from + 1)(state, dispatch, editorView);
45
+ }
46
+ return false;
47
+ }, list);
48
+ bindKeymapWithCommand(tab.common, (state, dispatch, editorView) => {
49
+ if (state.selection instanceof NodeSelection && state.selection.node.type === state.schema.nodes.expand && editorView && editorView.dom instanceof HTMLElement) {
50
+ const {
51
+ from
52
+ } = state.selection;
53
+ const expand = editorView.nodeDOM(from);
54
+ if (!expand || !(expand instanceof HTMLElement)) {
55
+ return false;
56
+ }
57
+ const iconContainer = expand.querySelector(`.${expandClassNames.iconContainer}`);
58
+ if (iconContainer && iconContainer.focus) {
59
+ const {
60
+ tr
61
+ } = state;
62
+ const pos = state.selection.from;
63
+ tr.setSelection(new TextSelection(tr.doc.resolve(pos)));
64
+ if (dispatch) {
65
+ dispatch(tr);
66
+ }
67
+ editorView.dom.blur();
68
+ iconContainer.focus();
69
+ }
70
+ return true;
71
+ }
72
+ return false;
73
+ }, list);
74
+ bindKeymapWithCommand(moveUp.common, (state, dispatch, editorView) => {
75
+ if (!editorView) {
76
+ return false;
77
+ }
78
+ const {
79
+ selection,
80
+ schema
81
+ } = state;
82
+ const {
83
+ nodeBefore
84
+ } = selection.$from;
85
+ if (selection instanceof GapCursorSelection && selection.side === Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand) && !nodeBefore.attrs.__expanded) {
86
+ const {
87
+ $from
88
+ } = selection;
89
+ return focusTitle(Math.max($from.pos - 1, 0))(state, dispatch, editorView);
90
+ }
91
+ const {
92
+ $from
93
+ } = state.selection;
94
+ if (editorView.endOfTextblock('up')) {
95
+ const expand = findExpand(state);
96
+
97
+ // Moving UP in a table should move the cursor to the row above
98
+ // however when an expand is in a table cell to the left of the
99
+ // current table cell, arrow UP moves the cursor to the left
100
+ // see ED-15425
101
+ if (isPositionNearTableRow($from, schema, 'before') && !expand) {
102
+ return false;
103
+ }
104
+ const prevCursorPos = Math.max($from.pos - $from.parentOffset - 1, 0);
105
+ // move cursor from expand's content to its title
106
+ if (expand && expand.start === prevCursorPos) {
107
+ return focusTitle(expand.start)(state, dispatch, editorView);
108
+ }
109
+ const sel = Selection.findFrom(state.doc.resolve(prevCursorPos), -1);
110
+ const expandBefore = findExpand(state, sel);
111
+ if (sel && expandBefore) {
112
+ // moving cursor from outside of an expand to the title when it is collapsed
113
+ if (!expandBefore.node.attrs.__expanded) {
114
+ return focusTitle(expandBefore.start)(state, dispatch, editorView);
115
+ }
116
+ // moving cursor from outside of an expand to the content when it is expanded
117
+ else if (dispatch) {
118
+ dispatch(state.tr.setSelection(sel));
119
+ }
120
+ return true;
121
+ }
122
+ }
123
+ return false;
124
+ }, list);
125
+ bindKeymapWithCommand(moveDown.common, (state, dispatch, editorView) => {
126
+ if (!editorView) {
127
+ return false;
128
+ }
129
+ const {
130
+ expand,
131
+ nestedExpand
132
+ } = state.schema.nodes;
133
+ const {
134
+ selection
135
+ } = state;
136
+ const {
137
+ nodeAfter
138
+ } = selection.$from;
139
+ if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand) && !nodeAfter.attrs.__expanded) {
140
+ const {
141
+ $from
142
+ } = selection;
143
+ return focusTitle($from.pos + 1)(state, dispatch, editorView);
144
+ }
145
+ if (editorView.endOfTextblock('down')) {
146
+ const {
147
+ $from
148
+ } = state.selection;
149
+ if ($from.depth === 0) {
150
+ return false;
151
+ }
152
+ const $after = state.doc.resolve($from.after());
153
+ if ($after.nodeAfter && ($after.nodeAfter.type === expand || $after.nodeAfter.type === nestedExpand)) {
154
+ return focusTitle($after.pos + 1)(state, dispatch, editorView);
155
+ }
156
+ }
157
+ return false;
158
+ }, list);
159
+ bindKeymapWithCommand(backspace.common, (state, dispatch, editorView) => {
160
+ const {
161
+ selection
162
+ } = state;
163
+ const {
164
+ $from
165
+ } = selection;
166
+ if (!editorView || !selection.empty) {
167
+ return false;
168
+ }
169
+ const {
170
+ expand,
171
+ nestedExpand
172
+ } = state.schema.nodes;
173
+ const expandNode = findExpand(state);
174
+ if (!expandNode) {
175
+ // @see ED-7977
176
+ const sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
177
+ const expandBefore = findExpand(state, sel);
178
+ if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand) && !expandBefore.node.attrs.__expanded) {
179
+ return focusTitle(expandBefore.start)(state, dispatch, editorView);
180
+ }
181
+ return false;
182
+ }
183
+ const parentNode = state.doc.nodeAt($from.before(Math.max($from.depth - 1, 1)));
184
+ // ED-10012 catch cases where the expand has another node nested within it and
185
+ // the backspace should be applied only to the inner node instead of the expand
186
+ if (parentNode && !isExpandNode(parentNode)) {
187
+ return false;
188
+ }
189
+ const textSel = Selection.findFrom(state.doc.resolve(expandNode.pos), 1, true);
190
+ if (textSel && selection.$from.pos === textSel.$from.pos && isEmptyNode(state.schema)(expandNode.node) && dispatch) {
191
+ var _api$analytics;
192
+ return deleteExpand(api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)(state, dispatch);
193
+ }
194
+ return false;
195
+ }, list);
196
+ return keymap(list);
197
+ }
@@ -0,0 +1,73 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
3
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
4
+ import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
5
+ import { setExpandRef } from '../commands';
6
+ import ExpandNodeView from '../nodeviews';
7
+ import { findExpand } from '../utils';
8
+ import { createPluginState, getPluginState, pluginKey } from './plugin-factory';
9
+ export function containsClass(element, className) {
10
+ var _element$classList;
11
+ return Boolean(element === null || element === void 0 ? void 0 : (_element$classList = element.classList) === null || _element$classList === void 0 ? void 0 : _element$classList.contains(className));
12
+ }
13
+ export const createPlugin = (dispatch, getIntl, appearance = 'full-page', useLongPressSelection = false, featureFlags, api) => {
14
+ const state = createPluginState(dispatch, {});
15
+ const isMobile = appearance === 'mobile';
16
+ return new SafePlugin({
17
+ state: state,
18
+ key: pluginKey,
19
+ props: {
20
+ nodeViews: {
21
+ expand: ExpandNodeView({
22
+ getIntl,
23
+ isMobile,
24
+ featureFlags,
25
+ api
26
+ }),
27
+ nestedExpand: ExpandNodeView({
28
+ getIntl,
29
+ isMobile,
30
+ featureFlags,
31
+ api
32
+ })
33
+ },
34
+ handleKeyDown(_view, event) {
35
+ return containsClass(event.target, expandClassNames.titleContainer);
36
+ },
37
+ handleKeyPress(_view, event) {
38
+ return containsClass(event.target, expandClassNames.titleContainer);
39
+ },
40
+ handleScrollToSelection() {
41
+ return containsClass(document.activeElement, expandClassNames.titleInput);
42
+ },
43
+ handleClickOn: createSelectionClickHandler(['expand', 'nestedExpand'], target => target.classList.contains(expandClassNames.prefix), {
44
+ useLongPressSelection
45
+ })
46
+ },
47
+ // @see ED-8027 to follow up on this work-around
48
+ filterTransaction(tr) {
49
+ if (containsClass(document.activeElement, expandClassNames.titleInput) && tr.selectionSet && (!tr.steps.length || tr.isGeneric)) {
50
+ return false;
51
+ }
52
+ return true;
53
+ },
54
+ view: editorView => {
55
+ const domAtPos = editorView.domAtPos.bind(editorView);
56
+ return {
57
+ update: view => {
58
+ const {
59
+ state,
60
+ dispatch
61
+ } = view;
62
+ const node = findExpand(state);
63
+ if (node) {
64
+ const expandRef = findDomRefAtPos(node.pos, domAtPos);
65
+ if (getPluginState(state).expandRef !== expandRef) {
66
+ setExpandRef(expandRef)(state, dispatch);
67
+ }
68
+ }
69
+ }
70
+ };
71
+ }
72
+ });
73
+ };
@@ -0,0 +1,9 @@
1
+ import { pluginFactory } from '@atlaskit/editor-common/utils';
2
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import reducer from '../reducer';
4
+ export const pluginKey = new PluginKey('expandPlugin');
5
+ export const {
6
+ createPluginState,
7
+ createCommand,
8
+ getPluginState
9
+ } = pluginFactory(pluginKey, reducer);
@@ -0,0 +1,11 @@
1
+ export default ((pluginState, action) => {
2
+ switch (action.type) {
3
+ case 'SET_EXPAND_REF':
4
+ return {
5
+ ...pluginState,
6
+ expandRef: action.data.ref
7
+ };
8
+ default:
9
+ return pluginState;
10
+ }
11
+ });
@@ -0,0 +1,52 @@
1
+ import commonMessages from '@atlaskit/editor-common/messages';
2
+ import RemoveIcon from '@atlaskit/icon/glyph/editor/remove';
3
+ import { deleteExpand } from './commands';
4
+ import { getPluginState } from './pm-plugins/plugin-factory';
5
+ export const getToolbarConfig = api => (state, {
6
+ formatMessage
7
+ }) => {
8
+ var _api$decorations$acti, _api$decorations, _api$analytics;
9
+ const {
10
+ hoverDecoration
11
+ } = (_api$decorations$acti = api === null || api === void 0 ? void 0 : (_api$decorations = api.decorations) === null || _api$decorations === void 0 ? void 0 : _api$decorations.actions) !== null && _api$decorations$acti !== void 0 ? _api$decorations$acti : {};
12
+ const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
13
+ const {
14
+ expandRef
15
+ } = getPluginState(state);
16
+ if (expandRef) {
17
+ const {
18
+ nestedExpand,
19
+ expand
20
+ } = state.schema.nodes;
21
+ return {
22
+ title: 'Expand toolbar',
23
+ getDomRef: () => expandRef,
24
+ nodeType: [nestedExpand, expand],
25
+ offset: [0, 6],
26
+ items: [{
27
+ type: 'copy-button',
28
+ items: [{
29
+ state,
30
+ formatMessage,
31
+ nodeType: [nestedExpand, expand]
32
+ }, {
33
+ type: 'separator'
34
+ }]
35
+ }, {
36
+ id: 'editor.expand.delete',
37
+ type: 'button',
38
+ appearance: 'danger',
39
+ focusEditoronEnter: true,
40
+ icon: RemoveIcon,
41
+ onClick: deleteExpand(editorAnalyticsAPI),
42
+ onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], true),
43
+ onMouseLeave: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], false),
44
+ onFocus: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], true),
45
+ onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration([nestedExpand, expand], false),
46
+ title: formatMessage(commonMessages.remove),
47
+ tabIndex: null
48
+ }]
49
+ };
50
+ }
51
+ return;
52
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,88 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ /** @jsx jsx */
3
+ import React, { useCallback } from 'react';
4
+ import { jsx } from '@emotion/react';
5
+ import Button from '@atlaskit/button/custom-theme-button';
6
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
7
+ import { expandLayoutWrapperStyle, ExpandLayoutWrapperWithRef, expandMessages } from '@atlaskit/editor-common/ui';
8
+ import { akEditorSwoopCubicBezier } from '@atlaskit/editor-shared-styles';
9
+ import ChevronRightIcon from '@atlaskit/icon/glyph/chevron-right';
10
+ import Tooltip from '@atlaskit/tooltip';
11
+ export const withTooltip = WrapperComponent => {
12
+ return class WithSortableColumn extends React.Component {
13
+ constructor(props) {
14
+ super(props);
15
+ }
16
+ render() {
17
+ const {
18
+ label
19
+ } = this.props;
20
+ return jsx(Tooltip, {
21
+ content: label,
22
+ position: "top",
23
+ tag: ExpandLayoutWrapperWithRef
24
+ }, jsx(WrapperComponent, this.props));
25
+ }
26
+ };
27
+ };
28
+ export const CustomButton = props => {
29
+ const {
30
+ label,
31
+ allowInteractiveExpand
32
+ } = props;
33
+ const useTheme = useCallback((currentTheme, themeProps) => {
34
+ const {
35
+ buttonStyles,
36
+ ...rest
37
+ } = currentTheme(themeProps);
38
+ return {
39
+ buttonStyles: {
40
+ ...buttonStyles,
41
+ height: '100%',
42
+ '& svg': {
43
+ transform: props.expanded ? 'transform: rotate(90deg);' : 'transform: rotate(0deg);',
44
+ transition: `transform 0.2s ${akEditorSwoopCubicBezier};`
45
+ }
46
+ },
47
+ ...rest
48
+ };
49
+ }, [props]);
50
+ return jsx(Button, {
51
+ appearance: "subtle",
52
+ className: expandClassNames.iconContainer,
53
+ iconBefore: jsx(ChevronRightIcon, {
54
+ label: label
55
+ }),
56
+ shouldFitContainer: true,
57
+ theme: useTheme,
58
+ isDisabled: !allowInteractiveExpand
59
+ });
60
+ };
61
+ const ButtonWithTooltip = withTooltip(CustomButton);
62
+ const ButtonWithoutTooltip = CustomButton;
63
+ export const ExpandIconButton = props => {
64
+ const {
65
+ expanded,
66
+ intl
67
+ } = props;
68
+ const message = expanded ? expandMessages.collapseNode : expandMessages.expandNode;
69
+ const label = intl && intl.formatMessage(message) || message.defaultMessage;
70
+ // check to ensure device supports any-hover
71
+ const supportsAnyHover = !!window.matchMedia ? window.matchMedia('(any-hover: hover)').matches !== window.matchMedia('(any-hover: none)').matches : false;
72
+ const hoverEventCheck = supportsAnyHover ? window.matchMedia('(any-hover: hover)').matches : true;
73
+
74
+ // hoverEventCheck is to disable tooltips for mobile to prevent incorrect hover state causing issues on iOS
75
+ if (props.allowInteractiveExpand && hoverEventCheck) {
76
+ return jsx(ButtonWithTooltip, _extends({
77
+ label: label
78
+ }, props));
79
+ }
80
+ return (
81
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
82
+ jsx("div", {
83
+ css: expandLayoutWrapperStyle
84
+ }, jsx(ButtonWithoutTooltip, _extends({
85
+ label: label
86
+ }, props)))
87
+ );
88
+ };
@@ -0,0 +1 @@
1
+ export { findExpand, transformSliceToRemoveOpenExpand, transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
@@ -0,0 +1,177 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ 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; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
5
+ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
6
+ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
7
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
8
+ import { safeInsert } from '@atlaskit/editor-prosemirror/utils';
9
+ import { findTable } from '@atlaskit/editor-tables/utils';
10
+ import { createCommand } from './pm-plugins/plugin-factory';
11
+ import { findExpand } from './utils';
12
+ export var setExpandRef = function setExpandRef(ref) {
13
+ return createCommand({
14
+ type: 'SET_EXPAND_REF',
15
+ data: {
16
+ ref: ref
17
+ }
18
+ }, function (tr) {
19
+ return tr.setMeta('addToHistory', false);
20
+ });
21
+ };
22
+ export var deleteExpandAtPos = function deleteExpandAtPos(editorAnalyticsAPI) {
23
+ return function (expandNodePos, expandNode) {
24
+ return function (state, dispatch) {
25
+ if (!expandNode || isNaN(expandNodePos)) {
26
+ return false;
27
+ }
28
+ var payload = {
29
+ action: ACTION.DELETED,
30
+ actionSubject: expandNode.type === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
31
+ attributes: {
32
+ inputMethod: INPUT_METHOD.TOOLBAR
33
+ },
34
+ eventType: EVENT_TYPE.TRACK
35
+ };
36
+ if (expandNode && dispatch) {
37
+ var tr = state.tr;
38
+ tr.delete(expandNodePos, expandNodePos + expandNode.nodeSize);
39
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
40
+ dispatch(tr);
41
+ }
42
+ return true;
43
+ };
44
+ };
45
+ };
46
+ export var deleteExpand = function deleteExpand(editorAnalyticsAPI) {
47
+ return function (state, dispatch) {
48
+ var expandNode = findExpand(state);
49
+ if (!expandNode) {
50
+ return false;
51
+ }
52
+ return deleteExpandAtPos(editorAnalyticsAPI)(expandNode.pos, expandNode.node)(state, dispatch);
53
+ };
54
+ };
55
+ export var updateExpandTitle = function updateExpandTitle(title, pos, nodeType) {
56
+ return function (state, dispatch) {
57
+ var node = state.doc.nodeAt(pos);
58
+ if (node && node.type === nodeType && dispatch) {
59
+ var tr = state.tr;
60
+ tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
61
+ title: title
62
+ }), node.marks);
63
+ dispatch(tr);
64
+ }
65
+ return true;
66
+ };
67
+ };
68
+ export var toggleExpandExpanded = function toggleExpandExpanded(editorAnalyticsAPI) {
69
+ return function (pos, nodeType) {
70
+ return function (state, dispatch) {
71
+ var node = state.doc.nodeAt(pos);
72
+ if (node && node.type === nodeType && dispatch) {
73
+ var tr = state.tr;
74
+ var isExpandedNext = !node.attrs.__expanded;
75
+ tr.setNodeMarkup(pos, node.type, _objectSpread(_objectSpread({}, node.attrs), {}, {
76
+ __expanded: isExpandedNext
77
+ }), node.marks);
78
+
79
+ // If we're going to collapse the expand and our cursor is currently inside
80
+ // Move to a right gap cursor, if the toolbar is interacted (or an API),
81
+ // it will insert below rather than inside (which will be invisible).
82
+ if (isExpandedNext === false && findExpand(state)) {
83
+ tr.setSelection(new GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), Side.RIGHT));
84
+ }
85
+
86
+ // log when people open/close expands
87
+ // TODO: ED-8523 make platform/mode global attributes?
88
+ var payload = {
89
+ action: ACTION.TOGGLE_EXPAND,
90
+ actionSubject: nodeType === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
91
+ attributes: {
92
+ platform: PLATFORMS.WEB,
93
+ mode: MODE.EDITOR,
94
+ expanded: isExpandedNext
95
+ },
96
+ eventType: EVENT_TYPE.TRACK
97
+ };
98
+
99
+ // `isRemote` meta prevents this step from being
100
+ // sync'd between sessions in collab edit
101
+ tr.setMeta('isRemote', true);
102
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
103
+ dispatch(tr);
104
+ }
105
+ return true;
106
+ };
107
+ };
108
+ };
109
+
110
+ // Creates either an expand or a nestedExpand node based on the current selection
111
+ export var createExpandNode = function createExpandNode(state) {
112
+ var _state$schema$nodes = state.schema.nodes,
113
+ expand = _state$schema$nodes.expand,
114
+ nestedExpand = _state$schema$nodes.nestedExpand;
115
+ var expandType = findTable(state.selection) ? nestedExpand : expand;
116
+ return expandType.createAndFill({});
117
+ };
118
+ export var insertExpand = function insertExpand(editorAnalyticsAPI) {
119
+ return function (state, dispatch) {
120
+ var expandNode = createExpandNode(state);
121
+ if (!expandNode) {
122
+ return false;
123
+ }
124
+ var tr = state.selection.empty ? safeInsert(expandNode)(state.tr).scrollIntoView() : createWrapSelectionTransaction({
125
+ state: state,
126
+ type: expandNode.type
127
+ });
128
+ var payload = {
129
+ action: ACTION.INSERTED,
130
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
131
+ actionSubjectId: (expandNode === null || expandNode === void 0 ? void 0 : expandNode.type) === state.schema.nodes.expand ? ACTION_SUBJECT_ID.EXPAND : ACTION_SUBJECT_ID.NESTED_EXPAND,
132
+ attributes: {
133
+ inputMethod: INPUT_METHOD.INSERT_MENU
134
+ },
135
+ eventType: EVENT_TYPE.TRACK
136
+ };
137
+ if (dispatch && expandNode) {
138
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
139
+ dispatch(tr);
140
+ }
141
+ return true;
142
+ };
143
+ };
144
+ export var focusTitle = function focusTitle(pos) {
145
+ return function (state, dispatch, editorView) {
146
+ if (editorView) {
147
+ var dom = editorView.domAtPos(pos);
148
+ var expandWrapper = dom.node.parentElement;
149
+ if (expandWrapper) {
150
+ setSelectionInsideExpand(pos)(state, dispatch, editorView);
151
+ var input = expandWrapper.querySelector('input');
152
+ if (input) {
153
+ input.focus();
154
+ return true;
155
+ }
156
+ }
157
+ }
158
+ return false;
159
+ };
160
+ };
161
+
162
+ // Used to clear any node or cell selection when expand title is focused
163
+ export var setSelectionInsideExpand = function setSelectionInsideExpand(expandPos) {
164
+ return function (state, dispatch, editorView) {
165
+ if (editorView) {
166
+ if (!editorView.hasFocus()) {
167
+ editorView.focus();
168
+ }
169
+ var sel = Selection.findFrom(editorView.state.doc.resolve(expandPos), 1, true);
170
+ if (sel && dispatch) {
171
+ dispatch(editorView.state.tr.setSelection(sel));
172
+ }
173
+ return true;
174
+ }
175
+ return false;
176
+ };
177
+ };
@@ -0,0 +1 @@
1
+ export { expandPlugin } from './plugin';