@atlaskit/editor-plugin-expand 1.3.5 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/legacyExpand/nodeviews/index.js +20 -8
- package/dist/cjs/singlePlayerExpand/commands.js +47 -6
- package/dist/cjs/singlePlayerExpand/node-views/index.js +80 -32
- package/dist/cjs/singlePlayerExpand/pm-plugins/keymap.js +8 -4
- package/dist/cjs/singlePlayerExpand/ui/NodeView.js +11 -6
- package/dist/es2019/legacyExpand/nodeviews/index.js +20 -8
- package/dist/es2019/singlePlayerExpand/commands.js +44 -2
- package/dist/es2019/singlePlayerExpand/node-views/index.js +67 -20
- package/dist/es2019/singlePlayerExpand/pm-plugins/keymap.js +8 -4
- package/dist/es2019/singlePlayerExpand/ui/NodeView.js +40 -35
- package/dist/esm/legacyExpand/nodeviews/index.js +20 -8
- package/dist/esm/singlePlayerExpand/commands.js +47 -6
- package/dist/esm/singlePlayerExpand/node-views/index.js +82 -34
- package/dist/esm/singlePlayerExpand/pm-plugins/keymap.js +8 -4
- package/dist/esm/singlePlayerExpand/ui/NodeView.js +11 -7
- package/dist/types/legacyExpand/nodeviews/index.d.ts +2 -0
- package/dist/types/singlePlayerExpand/commands.d.ts +5 -0
- package/dist/types/singlePlayerExpand/node-views/index.d.ts +4 -0
- package/dist/types/singlePlayerExpand/ui/NodeView.d.ts +1 -1
- package/dist/types/types.d.ts +3 -1
- package/dist/types-ts4.5/legacyExpand/nodeviews/index.d.ts +2 -0
- package/dist/types-ts4.5/singlePlayerExpand/commands.d.ts +5 -0
- package/dist/types-ts4.5/singlePlayerExpand/node-views/index.d.ts +4 -0
- package/dist/types-ts4.5/singlePlayerExpand/ui/NodeView.d.ts +1 -1
- package/dist/types-ts4.5/types.d.ts +3 -1
- package/package.json +3 -2
|
@@ -51,6 +51,7 @@ export class ExpandNodeView {
|
|
|
51
51
|
_defineProperty(this, "isMobile", false);
|
|
52
52
|
_defineProperty(this, "focusTitle", () => {
|
|
53
53
|
if (this.input) {
|
|
54
|
+
var _this$api, _this$api$selectionMa, _this$api$selectionMa2;
|
|
54
55
|
const {
|
|
55
56
|
state,
|
|
56
57
|
dispatch
|
|
@@ -67,6 +68,7 @@ export class ExpandNodeView {
|
|
|
67
68
|
if (typeof pos === 'number') {
|
|
68
69
|
setSelectionInsideExpand(pos)(state, dispatch, this.view);
|
|
69
70
|
}
|
|
71
|
+
this.decorationCleanup = (_this$api = this.api) === null || _this$api === void 0 ? void 0 : (_this$api$selectionMa = _this$api.selectionMarker) === null || _this$api$selectionMa === void 0 ? void 0 : (_this$api$selectionMa2 = _this$api$selectionMa.actions) === null || _this$api$selectionMa2 === void 0 ? void 0 : _this$api$selectionMa2.hideDecoration();
|
|
70
72
|
this.input.focus();
|
|
71
73
|
}
|
|
72
74
|
});
|
|
@@ -93,7 +95,7 @@ export class ExpandNodeView {
|
|
|
93
95
|
dispatch
|
|
94
96
|
} = this.view;
|
|
95
97
|
if (closestElement(target, `.${expandClassNames.icon}`)) {
|
|
96
|
-
var _this$
|
|
98
|
+
var _this$api2, _this$api2$analytics;
|
|
97
99
|
if (!this.allowInteractiveExpand) {
|
|
98
100
|
return;
|
|
99
101
|
}
|
|
@@ -105,7 +107,7 @@ export class ExpandNodeView {
|
|
|
105
107
|
this.view.dom.blur();
|
|
106
108
|
}
|
|
107
109
|
toggleExpandExpanded({
|
|
108
|
-
editorAnalyticsAPI: (_this$
|
|
110
|
+
editorAnalyticsAPI: (_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : (_this$api2$analytics = _this$api2.analytics) === null || _this$api2$analytics === void 0 ? void 0 : _this$api2$analytics.actions,
|
|
109
111
|
pos,
|
|
110
112
|
nodeType: this.node.type,
|
|
111
113
|
__livePage: this.__livePage
|
|
@@ -141,6 +143,10 @@ export class ExpandNodeView {
|
|
|
141
143
|
_defineProperty(this, "handleFocus", event => {
|
|
142
144
|
event.stopImmediatePropagation();
|
|
143
145
|
});
|
|
146
|
+
_defineProperty(this, "handleBlur", event => {
|
|
147
|
+
var _this$decorationClean;
|
|
148
|
+
(_this$decorationClean = this.decorationCleanup) === null || _this$decorationClean === void 0 ? void 0 : _this$decorationClean.call(this);
|
|
149
|
+
});
|
|
144
150
|
_defineProperty(this, "handleTitleKeydown", event => {
|
|
145
151
|
switch (keyName(event)) {
|
|
146
152
|
case 'Enter':
|
|
@@ -184,8 +190,8 @@ export class ExpandNodeView {
|
|
|
184
190
|
} = this.view;
|
|
185
191
|
const expandNode = this.node;
|
|
186
192
|
if (expandNode && isEmptyNode(state.schema)(expandNode)) {
|
|
187
|
-
var _this$
|
|
188
|
-
deleteExpandAtPos((_this$
|
|
193
|
+
var _this$api3, _this$api3$analytics;
|
|
194
|
+
deleteExpandAtPos((_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$analytics = _this$api3.analytics) === null || _this$api3$analytics === void 0 ? void 0 : _this$api3$analytics.actions)(pos, expandNode)(state, this.view.dispatch);
|
|
189
195
|
}
|
|
190
196
|
});
|
|
191
197
|
_defineProperty(this, "toggleExpand", () => {
|
|
@@ -194,13 +200,13 @@ export class ExpandNodeView {
|
|
|
194
200
|
return;
|
|
195
201
|
}
|
|
196
202
|
if (this.allowInteractiveExpand) {
|
|
197
|
-
var _this$
|
|
203
|
+
var _this$api4, _this$api4$analytics;
|
|
198
204
|
const {
|
|
199
205
|
state,
|
|
200
206
|
dispatch
|
|
201
207
|
} = this.view;
|
|
202
208
|
toggleExpandExpanded({
|
|
203
|
-
editorAnalyticsAPI: (_this$
|
|
209
|
+
editorAnalyticsAPI: (_this$api4 = this.api) === null || _this$api4 === void 0 ? void 0 : (_this$api4$analytics = _this$api4.analytics) === null || _this$api4$analytics === void 0 ? void 0 : _this$api4$analytics.actions,
|
|
204
210
|
pos,
|
|
205
211
|
nodeType: this.node.type,
|
|
206
212
|
__livePage: this.__livePage
|
|
@@ -329,14 +335,14 @@ export class ExpandNodeView {
|
|
|
329
335
|
selectionEnd
|
|
330
336
|
} = this.input;
|
|
331
337
|
if (selectionStart === selectionEnd && selectionStart === 0) {
|
|
332
|
-
var _this$
|
|
338
|
+
var _this$api5, _this$api5$selection;
|
|
333
339
|
event.preventDefault();
|
|
334
340
|
const {
|
|
335
341
|
state,
|
|
336
342
|
dispatch
|
|
337
343
|
} = this.view;
|
|
338
344
|
this.view.focus();
|
|
339
|
-
const selectionSharedState = ((_this$
|
|
345
|
+
const selectionSharedState = ((_this$api5 = this.api) === null || _this$api5 === void 0 ? void 0 : (_this$api5$selection = _this$api5.selection) === null || _this$api5$selection === void 0 ? void 0 : _this$api5$selection.sharedState.currentState()) || {};
|
|
340
346
|
// selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
|
|
341
347
|
// This is a special case where we want to bypass node selection and jump straight to gap cursor
|
|
342
348
|
if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
|
|
@@ -390,6 +396,8 @@ export class ExpandNodeView {
|
|
|
390
396
|
if (this.input) {
|
|
391
397
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
392
398
|
this.input.addEventListener('keydown', this.handleTitleKeydown);
|
|
399
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
400
|
+
this.input.addEventListener('blur', this.handleBlur);
|
|
393
401
|
}
|
|
394
402
|
if (this.titleContainer) {
|
|
395
403
|
// If the user interacts in our title bar (either toggle or input)
|
|
@@ -459,6 +467,7 @@ export class ExpandNodeView {
|
|
|
459
467
|
return false;
|
|
460
468
|
}
|
|
461
469
|
destroy() {
|
|
470
|
+
var _this$decorationClean2;
|
|
462
471
|
if (this.dom) {
|
|
463
472
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
464
473
|
this.dom.removeEventListener('click', this.handleClick);
|
|
@@ -468,6 +477,8 @@ export class ExpandNodeView {
|
|
|
468
477
|
if (this.input) {
|
|
469
478
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
470
479
|
this.input.removeEventListener('keydown', this.handleTitleKeydown);
|
|
480
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
481
|
+
this.input.removeEventListener('blur', this.handleBlur);
|
|
471
482
|
}
|
|
472
483
|
if (this.titleContainer) {
|
|
473
484
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
@@ -478,6 +489,7 @@ export class ExpandNodeView {
|
|
|
478
489
|
this.icon.removeEventListener('keydown', this.handleIconKeyDown);
|
|
479
490
|
ReactDOM.unmountComponentAtNode(this.icon);
|
|
480
491
|
}
|
|
492
|
+
(_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 ? void 0 : _this$decorationClean2.call(this);
|
|
481
493
|
|
|
482
494
|
// @ts-ignore - [unblock prosemirror bump] reset non optional prop to undefined to clear reference
|
|
483
495
|
this.dom = undefined;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
2
|
-
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { expandedState } from '@atlaskit/editor-common/expand';
|
|
4
|
+
import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
|
|
3
5
|
import { findExpand } from '@atlaskit/editor-common/transforms';
|
|
4
6
|
import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
|
|
5
7
|
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
@@ -13,7 +15,9 @@ export const createExpandNode = state => {
|
|
|
13
15
|
nestedExpand
|
|
14
16
|
} = state.schema.nodes;
|
|
15
17
|
const expandType = findTable(state.selection) ? nestedExpand : expand;
|
|
16
|
-
|
|
18
|
+
const expandNode = expandType.createAndFill({});
|
|
19
|
+
expandedState.set(expandNode, true);
|
|
20
|
+
return expandNode;
|
|
17
21
|
};
|
|
18
22
|
export const insertExpand = editorAnalyticsAPI => (state, dispatch) => {
|
|
19
23
|
const expandNode = createExpandNode(state);
|
|
@@ -83,6 +87,44 @@ export const setSelectionInsideExpand = expandPos => (state, dispatch, editorVie
|
|
|
83
87
|
}
|
|
84
88
|
return false;
|
|
85
89
|
};
|
|
90
|
+
export const toggleExpandExpanded = ({
|
|
91
|
+
editorAnalyticsAPI,
|
|
92
|
+
pos,
|
|
93
|
+
node
|
|
94
|
+
}) => (state, dispatch) => {
|
|
95
|
+
if (node && dispatch) {
|
|
96
|
+
var _expandedState$get;
|
|
97
|
+
const {
|
|
98
|
+
tr
|
|
99
|
+
} = state;
|
|
100
|
+
const expanded = (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false;
|
|
101
|
+
const isExpandedNext = !expanded;
|
|
102
|
+
expandedState.set(node, isExpandedNext);
|
|
103
|
+
|
|
104
|
+
// If we're going to collapse the expand and our cursor is currently inside
|
|
105
|
+
// Move to a right gap cursor, if the toolbar is interacted (or an API),
|
|
106
|
+
// it will insert below rather than inside (which will be invisible).
|
|
107
|
+
if (isExpandedNext === true) {
|
|
108
|
+
tr.setSelection(new GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), Side.RIGHT));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// log when people open/close expands
|
|
112
|
+
// TODO: ED-8523 make platform/mode global attributes?
|
|
113
|
+
const payload = {
|
|
114
|
+
action: ACTION.TOGGLE_EXPAND,
|
|
115
|
+
actionSubject: node.type === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
|
|
116
|
+
attributes: {
|
|
117
|
+
platform: PLATFORMS.WEB,
|
|
118
|
+
mode: MODE.EDITOR,
|
|
119
|
+
expanded: isExpandedNext
|
|
120
|
+
},
|
|
121
|
+
eventType: EVENT_TYPE.TRACK
|
|
122
|
+
};
|
|
123
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
|
|
124
|
+
dispatch(tr);
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
};
|
|
86
128
|
export const updateExpandTitle = ({
|
|
87
129
|
title,
|
|
88
130
|
nodeType,
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import { keyName } from 'w3c-keyname';
|
|
4
|
+
import { expandedState } from '@atlaskit/editor-common/expand';
|
|
4
5
|
import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
|
|
5
6
|
import { expandClassNames } from '@atlaskit/editor-common/styles';
|
|
6
7
|
import { closestElement, isEmptyNode } from '@atlaskit/editor-common/utils';
|
|
7
8
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
8
9
|
import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
9
|
-
import { deleteExpand, setSelectionInsideExpand, updateExpandTitle } from '../commands';
|
|
10
|
-
import { renderIcon, toDOM } from '../ui/NodeView';
|
|
10
|
+
import { deleteExpand, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
|
|
11
|
+
import { buildExpandClassName, renderIcon, toDOM } from '../ui/NodeView';
|
|
11
12
|
export class ExpandNodeView {
|
|
12
13
|
constructor(node, view, getPos, getIntl, isMobile, selectNearNode, api, allowInteractiveExpand = true, __livePage = false) {
|
|
13
14
|
_defineProperty(this, "allowInteractiveExpand", true);
|
|
14
15
|
_defineProperty(this, "isMobile", false);
|
|
15
16
|
_defineProperty(this, "focusTitle", () => {
|
|
16
17
|
if (this.input) {
|
|
18
|
+
var _this$api, _this$api$selectionMa, _this$api$selectionMa2;
|
|
17
19
|
const {
|
|
18
20
|
state,
|
|
19
21
|
dispatch
|
|
@@ -30,6 +32,7 @@ export class ExpandNodeView {
|
|
|
30
32
|
if (typeof pos === 'number') {
|
|
31
33
|
setSelectionInsideExpand(pos)(state, dispatch, this.view);
|
|
32
34
|
}
|
|
35
|
+
this.decorationCleanup = (_this$api = this.api) === null || _this$api === void 0 ? void 0 : (_this$api$selectionMa = _this$api.selectionMarker) === null || _this$api$selectionMa === void 0 ? void 0 : (_this$api$selectionMa2 = _this$api$selectionMa.actions) === null || _this$api$selectionMa2 === void 0 ? void 0 : _this$api$selectionMa2.hideDecoration();
|
|
33
36
|
this.input.focus();
|
|
34
37
|
}
|
|
35
38
|
});
|
|
@@ -52,6 +55,7 @@ export class ExpandNodeView {
|
|
|
52
55
|
}
|
|
53
56
|
const target = event.target;
|
|
54
57
|
if (closestElement(target, `.${expandClassNames.icon}`)) {
|
|
58
|
+
var _this$api2, _this$api2$analytics;
|
|
55
59
|
if (!this.allowInteractiveExpand) {
|
|
56
60
|
return;
|
|
57
61
|
}
|
|
@@ -62,10 +66,12 @@ export class ExpandNodeView {
|
|
|
62
66
|
if (this.view.dom instanceof HTMLElement) {
|
|
63
67
|
this.view.dom.blur();
|
|
64
68
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
toggleExpandExpanded({
|
|
70
|
+
editorAnalyticsAPI: (_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : (_this$api2$analytics = _this$api2.analytics) === null || _this$api2$analytics === void 0 ? void 0 : _this$api2$analytics.actions,
|
|
71
|
+
pos,
|
|
72
|
+
node: this.node
|
|
73
|
+
})(this.view.state, this.view.dispatch);
|
|
74
|
+
this.updateExpandClassName();
|
|
69
75
|
return;
|
|
70
76
|
}
|
|
71
77
|
if (target === this.input) {
|
|
@@ -96,10 +102,14 @@ export class ExpandNodeView {
|
|
|
96
102
|
_defineProperty(this, "handleFocus", event => {
|
|
97
103
|
event.stopImmediatePropagation();
|
|
98
104
|
});
|
|
105
|
+
_defineProperty(this, "handleBlur", event => {
|
|
106
|
+
var _this$decorationClean;
|
|
107
|
+
(_this$decorationClean = this.decorationCleanup) === null || _this$decorationClean === void 0 ? void 0 : _this$decorationClean.call(this);
|
|
108
|
+
});
|
|
99
109
|
_defineProperty(this, "handleTitleKeydown", event => {
|
|
100
110
|
switch (keyName(event)) {
|
|
101
111
|
case 'Enter':
|
|
102
|
-
|
|
112
|
+
this.toggleExpand();
|
|
103
113
|
break;
|
|
104
114
|
case 'Tab':
|
|
105
115
|
case 'ArrowDown':
|
|
@@ -135,8 +145,27 @@ export class ExpandNodeView {
|
|
|
135
145
|
return;
|
|
136
146
|
}
|
|
137
147
|
if (expandNode && isEmptyNode(state.schema)(expandNode)) {
|
|
138
|
-
var _this$
|
|
139
|
-
deleteExpand((_this$
|
|
148
|
+
var _this$api3, _this$api3$analytics;
|
|
149
|
+
deleteExpand((_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$analytics = _this$api3.analytics) === null || _this$api3$analytics === void 0 ? void 0 : _this$api3$analytics.actions)(state, this.view.dispatch);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
_defineProperty(this, "toggleExpand", () => {
|
|
153
|
+
const pos = this.getPos();
|
|
154
|
+
if (typeof pos !== 'number') {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (this.allowInteractiveExpand) {
|
|
158
|
+
var _this$api4, _this$api4$analytics;
|
|
159
|
+
const {
|
|
160
|
+
state,
|
|
161
|
+
dispatch
|
|
162
|
+
} = this.view;
|
|
163
|
+
toggleExpandExpanded({
|
|
164
|
+
editorAnalyticsAPI: (_this$api4 = this.api) === null || _this$api4 === void 0 ? void 0 : (_this$api4$analytics = _this$api4.analytics) === null || _this$api4$analytics === void 0 ? void 0 : _this$api4$analytics.actions,
|
|
165
|
+
pos,
|
|
166
|
+
node: this.node
|
|
167
|
+
})(state, dispatch);
|
|
168
|
+
this.updateExpandClassName();
|
|
140
169
|
}
|
|
141
170
|
});
|
|
142
171
|
_defineProperty(this, "moveToOutsideOfTitle", event => {
|
|
@@ -168,9 +197,8 @@ export class ExpandNodeView {
|
|
|
168
197
|
dispatch(state.tr.setSelection(sel));
|
|
169
198
|
}
|
|
170
199
|
});
|
|
171
|
-
// TODO: https://product-fabric.atlassian.net/browse/ED-22841
|
|
172
200
|
_defineProperty(this, "isCollapsed", () => {
|
|
173
|
-
return
|
|
201
|
+
return !expandedState.get(this.node);
|
|
174
202
|
});
|
|
175
203
|
_defineProperty(this, "setRightGapCursor", event => {
|
|
176
204
|
if (!this.input) {
|
|
@@ -259,14 +287,14 @@ export class ExpandNodeView {
|
|
|
259
287
|
selectionEnd
|
|
260
288
|
} = this.input;
|
|
261
289
|
if (selectionStart === selectionEnd && selectionStart === 0) {
|
|
262
|
-
var _this$
|
|
290
|
+
var _this$api5, _this$api5$selection;
|
|
263
291
|
event.preventDefault();
|
|
264
292
|
const {
|
|
265
293
|
state,
|
|
266
294
|
dispatch
|
|
267
295
|
} = this.view;
|
|
268
296
|
this.view.focus();
|
|
269
|
-
const selectionSharedState = ((_this$
|
|
297
|
+
const selectionSharedState = ((_this$api5 = this.api) === null || _this$api5 === void 0 ? void 0 : (_this$api5$selection = _this$api5.selection) === null || _this$api5$selection === void 0 ? void 0 : _this$api5$selection.sharedState.currentState()) || {};
|
|
270
298
|
// selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
|
|
271
299
|
// This is a special case where we want to bypass node selection and jump straight to gap cursor
|
|
272
300
|
if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
|
|
@@ -291,14 +319,14 @@ export class ExpandNodeView {
|
|
|
291
319
|
this.selectNearNode = selectNearNode;
|
|
292
320
|
this.__livePage = __livePage;
|
|
293
321
|
this.intl = getIntl();
|
|
294
|
-
const {
|
|
295
|
-
dom,
|
|
296
|
-
contentDOM
|
|
297
|
-
} = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl));
|
|
298
322
|
this.allowInteractiveExpand = allowInteractiveExpand;
|
|
299
323
|
this.getPos = getPos;
|
|
300
324
|
this.view = view;
|
|
301
325
|
this.node = node;
|
|
326
|
+
const {
|
|
327
|
+
dom,
|
|
328
|
+
contentDOM
|
|
329
|
+
} = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl));
|
|
302
330
|
this.dom = dom;
|
|
303
331
|
this.contentDOM = contentDOM;
|
|
304
332
|
this.isMobile = isMobile;
|
|
@@ -307,6 +335,9 @@ export class ExpandNodeView {
|
|
|
307
335
|
this.input = this.dom.querySelector(`.${expandClassNames.titleInput}`);
|
|
308
336
|
this.titleContainer = this.dom.querySelector(`.${expandClassNames.titleContainer}`);
|
|
309
337
|
renderIcon(this.icon, this.allowInteractiveExpand, this.intl);
|
|
338
|
+
if (!expandedState.has(this.node)) {
|
|
339
|
+
expandedState.set(this.node, false);
|
|
340
|
+
}
|
|
310
341
|
if (!this.input || !this.titleContainer || !this.icon) {
|
|
311
342
|
return;
|
|
312
343
|
}
|
|
@@ -316,6 +347,7 @@ export class ExpandNodeView {
|
|
|
316
347
|
this.dom.addEventListener('click', this.handleClick);
|
|
317
348
|
this.dom.addEventListener('input', this.handleInput);
|
|
318
349
|
this.input.addEventListener('keydown', this.handleTitleKeydown);
|
|
350
|
+
this.input.addEventListener('blur', this.handleBlur);
|
|
319
351
|
// If the user interacts in our title bar (either toggle or input)
|
|
320
352
|
// Prevent ProseMirror from getting a focus event (causes weird selection issues).
|
|
321
353
|
this.titleContainer.addEventListener('focus', this.handleFocus);
|
|
@@ -338,9 +370,6 @@ export class ExpandNodeView {
|
|
|
338
370
|
}
|
|
339
371
|
update(node, _decorations) {
|
|
340
372
|
if (this.node.type === node.type) {
|
|
341
|
-
// TODO: https://product-fabric.atlassian.net/browse/ED-22841
|
|
342
|
-
// Handle toggling of the expand on update here
|
|
343
|
-
|
|
344
373
|
// During a collab session the title doesn't sync with other users
|
|
345
374
|
// since we're intentionally being less aggressive about re-rendering.
|
|
346
375
|
// We also apply a rAF to avoid abrupt continuous replacement of the title.
|
|
@@ -349,21 +378,39 @@ export class ExpandNodeView {
|
|
|
349
378
|
this.input.value = this.node.attrs.title;
|
|
350
379
|
}
|
|
351
380
|
});
|
|
381
|
+
if (this.node !== node) {
|
|
382
|
+
let previousExpandedState = expandedState.get(this.node);
|
|
383
|
+
if (previousExpandedState === undefined) {
|
|
384
|
+
previousExpandedState = true;
|
|
385
|
+
}
|
|
386
|
+
expandedState.set(node, previousExpandedState);
|
|
387
|
+
expandedState.delete(this.node);
|
|
388
|
+
}
|
|
352
389
|
this.node = node;
|
|
353
390
|
return true;
|
|
354
391
|
}
|
|
355
392
|
return false;
|
|
356
393
|
}
|
|
394
|
+
updateExpandClassName() {
|
|
395
|
+
const expanded = expandedState.get(this.node) ? expandedState.get(this.node) : false;
|
|
396
|
+
if (this.dom && expanded !== undefined) {
|
|
397
|
+
this.dom.className = buildExpandClassName(this.node.type.name, expanded);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
357
400
|
destroy() {
|
|
401
|
+
var _this$decorationClean2;
|
|
358
402
|
if (!this.dom || !this.input || !this.titleContainer || !this.icon) {
|
|
359
403
|
return;
|
|
360
404
|
}
|
|
361
405
|
this.dom.removeEventListener('click', this.handleClick);
|
|
362
406
|
this.dom.removeEventListener('input', this.handleInput);
|
|
363
407
|
this.input.removeEventListener('keydown', this.handleTitleKeydown);
|
|
408
|
+
this.input.removeEventListener('blur', this.handleBlur);
|
|
364
409
|
this.titleContainer.removeEventListener('focus', this.handleFocus);
|
|
365
410
|
this.icon.removeEventListener('keydown', this.handleIconKeyDown);
|
|
411
|
+
(_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 ? void 0 : _this$decorationClean2.call(this);
|
|
366
412
|
ReactDOM.unmountComponentAtNode(this.icon);
|
|
413
|
+
expandedState.delete(this.node);
|
|
367
414
|
}
|
|
368
415
|
}
|
|
369
416
|
export default function ({
|
|
@@ -22,7 +22,8 @@ export function expandKeymap(api, options) {
|
|
|
22
22
|
nodeBefore
|
|
23
23
|
} = selection.$from;
|
|
24
24
|
if (selection instanceof GapCursorSelection && selection.side === Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand)
|
|
25
|
-
//
|
|
25
|
+
// https://product-fabric.atlassian.net/browse/ED-22991
|
|
26
|
+
// TODO: add back in expanded logic
|
|
26
27
|
) {
|
|
27
28
|
const {
|
|
28
29
|
$from
|
|
@@ -52,7 +53,8 @@ export function expandKeymap(api, options) {
|
|
|
52
53
|
if (sel && expandBefore) {
|
|
53
54
|
// moving cursor from outside of an expand to the title when it is collapsed
|
|
54
55
|
|
|
55
|
-
//
|
|
56
|
+
// https://product-fabric.atlassian.net/browse/ED-22991
|
|
57
|
+
// TODO: add back in expanded logic
|
|
56
58
|
return focusTitle(expandBefore.start)(state, dispatch, editorView);
|
|
57
59
|
}
|
|
58
60
|
}
|
|
@@ -73,7 +75,8 @@ export function expandKeymap(api, options) {
|
|
|
73
75
|
nodeAfter
|
|
74
76
|
} = selection.$from;
|
|
75
77
|
if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand)
|
|
76
|
-
//
|
|
78
|
+
// https://product-fabric.atlassian.net/browse/ED-22991
|
|
79
|
+
// TODO: add back in expanded logic
|
|
77
80
|
) {
|
|
78
81
|
const {
|
|
79
82
|
$from
|
|
@@ -114,7 +117,8 @@ export function expandKeymap(api, options) {
|
|
|
114
117
|
const sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
|
|
115
118
|
const expandBefore = findExpand(state, sel);
|
|
116
119
|
if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand)
|
|
117
|
-
//
|
|
120
|
+
// https://product-fabric.atlassian.net/browse/ED-22991
|
|
121
|
+
// TODO: add back in expanded logic
|
|
118
122
|
) {
|
|
119
123
|
return focusTitle(expandBefore.start)(state, dispatch, editorView);
|
|
120
124
|
}
|
|
@@ -1,52 +1,57 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
|
+
import { expandedState } from '@atlaskit/editor-common/expand';
|
|
3
4
|
import { expandClassNames } from '@atlaskit/editor-common/styles';
|
|
4
5
|
import { expandMessages } from '@atlaskit/editor-common/ui';
|
|
5
6
|
import { ExpandButton } from '../ui/ExpandButton';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export const buildExpandClassName = type => {
|
|
9
|
-
return `${expandClassNames.prefix} ${expandClassNames.type(type)}
|
|
10
|
-
${expandClassNames.expanded}`;
|
|
7
|
+
export const buildExpandClassName = (type, expanded) => {
|
|
8
|
+
return `${expandClassNames.prefix} ${expandClassNames.type(type)} ${expanded ? expandClassNames.expanded : ''}`;
|
|
11
9
|
};
|
|
12
|
-
export const toDOM = (node, __livePage, intl) =>
|
|
10
|
+
export const toDOM = (node, __livePage, intl) => {
|
|
11
|
+
var _expandedState$get;
|
|
12
|
+
return ['div', {
|
|
13
|
+
// prettier-ignore
|
|
14
|
+
'class': buildExpandClassName(node.type.name, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false),
|
|
15
|
+
'data-node-type': node.type.name,
|
|
16
|
+
'data-title': node.attrs.title
|
|
17
|
+
}, ['div', {
|
|
18
|
+
// prettier-ignore
|
|
19
|
+
'class': expandClassNames.titleContainer,
|
|
20
|
+
contenteditable: 'false',
|
|
21
|
+
// Element gains access to focus events.
|
|
22
|
+
// This is needed to prevent PM gaining access
|
|
23
|
+
// on interacting with our controls.
|
|
24
|
+
tabindex: '-1'
|
|
25
|
+
},
|
|
13
26
|
// prettier-ignore
|
|
14
|
-
'
|
|
15
|
-
|
|
16
|
-
'
|
|
17
|
-
|
|
27
|
+
['div', {
|
|
28
|
+
'class': expandClassNames.icon
|
|
29
|
+
}], ['div', {
|
|
30
|
+
// prettier-ignore
|
|
31
|
+
'class': expandClassNames.inputContainer
|
|
32
|
+
}, ['input', {
|
|
33
|
+
// prettier-ignore
|
|
34
|
+
'class': expandClassNames.titleInput,
|
|
35
|
+
value: node.attrs.title,
|
|
36
|
+
placeholder: intl && typeof intl.formatMessage === 'function' && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
|
|
37
|
+
type: 'text'
|
|
38
|
+
}]]],
|
|
18
39
|
// prettier-ignore
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// on interacting with our controls.
|
|
24
|
-
tabindex: '-1'
|
|
25
|
-
},
|
|
26
|
-
// prettier-ignore
|
|
27
|
-
['div', {
|
|
28
|
-
'class': expandClassNames.icon
|
|
29
|
-
}], ['div', {
|
|
30
|
-
// prettier-ignore
|
|
31
|
-
'class': expandClassNames.inputContainer
|
|
32
|
-
}, ['input', {
|
|
33
|
-
// prettier-ignore
|
|
34
|
-
'class': expandClassNames.titleInput,
|
|
35
|
-
value: node.attrs.title,
|
|
36
|
-
placeholder: intl && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
|
|
37
|
-
type: 'text'
|
|
38
|
-
}]]],
|
|
39
|
-
// prettier-ignore
|
|
40
|
-
['div', {
|
|
41
|
-
'class': expandClassNames.content
|
|
42
|
-
}, 0]];
|
|
40
|
+
['div', {
|
|
41
|
+
'class': expandClassNames.content
|
|
42
|
+
}, 0]];
|
|
43
|
+
};
|
|
43
44
|
export const renderIcon = (icon, allowInteractiveExpand, intl, node) => {
|
|
44
45
|
if (!icon) {
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
48
|
+
let expanded = node ? expandedState.get(node) : true;
|
|
49
|
+
if (expanded === undefined) {
|
|
50
|
+
expanded = false;
|
|
51
|
+
}
|
|
47
52
|
ReactDOM.render( /*#__PURE__*/React.createElement(ExpandButton, {
|
|
48
53
|
intl: intl,
|
|
49
54
|
allowInteractiveExpand: allowInteractiveExpand,
|
|
50
|
-
expanded:
|
|
55
|
+
expanded: expanded
|
|
51
56
|
}), icon);
|
|
52
57
|
};
|
|
@@ -59,6 +59,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
59
59
|
_defineProperty(this, "isMobile", false);
|
|
60
60
|
_defineProperty(this, "focusTitle", function () {
|
|
61
61
|
if (_this.input) {
|
|
62
|
+
var _this$api;
|
|
62
63
|
var _this$view = _this.view,
|
|
63
64
|
state = _this$view.state,
|
|
64
65
|
dispatch = _this$view.dispatch;
|
|
@@ -74,6 +75,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
74
75
|
if (typeof pos === 'number') {
|
|
75
76
|
setSelectionInsideExpand(pos)(state, dispatch, _this.view);
|
|
76
77
|
}
|
|
78
|
+
_this.decorationCleanup = (_this$api = _this.api) === null || _this$api === void 0 || (_this$api = _this$api.selectionMarker) === null || _this$api === void 0 || (_this$api = _this$api.actions) === null || _this$api === void 0 ? void 0 : _this$api.hideDecoration();
|
|
77
79
|
_this.input.focus();
|
|
78
80
|
}
|
|
79
81
|
});
|
|
@@ -99,7 +101,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
99
101
|
state = _this$view2.state,
|
|
100
102
|
dispatch = _this$view2.dispatch;
|
|
101
103
|
if (closestElement(target, ".".concat(expandClassNames.icon))) {
|
|
102
|
-
var _this$
|
|
104
|
+
var _this$api2;
|
|
103
105
|
if (!_this.allowInteractiveExpand) {
|
|
104
106
|
return;
|
|
105
107
|
}
|
|
@@ -111,7 +113,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
111
113
|
_this.view.dom.blur();
|
|
112
114
|
}
|
|
113
115
|
toggleExpandExpanded({
|
|
114
|
-
editorAnalyticsAPI: (_this$
|
|
116
|
+
editorAnalyticsAPI: (_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.analytics) === null || _this$api2 === void 0 ? void 0 : _this$api2.actions,
|
|
115
117
|
pos: pos,
|
|
116
118
|
nodeType: _this.node.type,
|
|
117
119
|
__livePage: _this.__livePage
|
|
@@ -146,6 +148,10 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
146
148
|
_defineProperty(this, "handleFocus", function (event) {
|
|
147
149
|
event.stopImmediatePropagation();
|
|
148
150
|
});
|
|
151
|
+
_defineProperty(this, "handleBlur", function (event) {
|
|
152
|
+
var _this$decorationClean;
|
|
153
|
+
(_this$decorationClean = _this.decorationCleanup) === null || _this$decorationClean === void 0 || _this$decorationClean.call(_this);
|
|
154
|
+
});
|
|
149
155
|
_defineProperty(this, "handleTitleKeydown", function (event) {
|
|
150
156
|
switch (keyName(event)) {
|
|
151
157
|
case 'Enter':
|
|
@@ -186,8 +192,8 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
186
192
|
var state = _this.view.state;
|
|
187
193
|
var expandNode = _this.node;
|
|
188
194
|
if (expandNode && isEmptyNode(state.schema)(expandNode)) {
|
|
189
|
-
var _this$
|
|
190
|
-
deleteExpandAtPos((_this$
|
|
195
|
+
var _this$api3;
|
|
196
|
+
deleteExpandAtPos((_this$api3 = _this.api) === null || _this$api3 === void 0 || (_this$api3 = _this$api3.analytics) === null || _this$api3 === void 0 ? void 0 : _this$api3.actions)(pos, expandNode)(state, _this.view.dispatch);
|
|
191
197
|
}
|
|
192
198
|
});
|
|
193
199
|
_defineProperty(this, "toggleExpand", function () {
|
|
@@ -196,12 +202,12 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
196
202
|
return;
|
|
197
203
|
}
|
|
198
204
|
if (_this.allowInteractiveExpand) {
|
|
199
|
-
var _this$
|
|
205
|
+
var _this$api4;
|
|
200
206
|
var _this$view4 = _this.view,
|
|
201
207
|
state = _this$view4.state,
|
|
202
208
|
dispatch = _this$view4.dispatch;
|
|
203
209
|
toggleExpandExpanded({
|
|
204
|
-
editorAnalyticsAPI: (_this$
|
|
210
|
+
editorAnalyticsAPI: (_this$api4 = _this.api) === null || _this$api4 === void 0 || (_this$api4 = _this$api4.analytics) === null || _this$api4 === void 0 ? void 0 : _this$api4.actions,
|
|
205
211
|
pos: pos,
|
|
206
212
|
nodeType: _this.node.type,
|
|
207
213
|
__livePage: _this.__livePage
|
|
@@ -322,13 +328,13 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
322
328
|
selectionStart = _this$input5.selectionStart,
|
|
323
329
|
selectionEnd = _this$input5.selectionEnd;
|
|
324
330
|
if (selectionStart === selectionEnd && selectionStart === 0) {
|
|
325
|
-
var _this$
|
|
331
|
+
var _this$api5;
|
|
326
332
|
event.preventDefault();
|
|
327
333
|
var _this$view9 = _this.view,
|
|
328
334
|
state = _this$view9.state,
|
|
329
335
|
dispatch = _this$view9.dispatch;
|
|
330
336
|
_this.view.focus();
|
|
331
|
-
var selectionSharedState = ((_this$
|
|
337
|
+
var selectionSharedState = ((_this$api5 = _this.api) === null || _this$api5 === void 0 || (_this$api5 = _this$api5.selection) === null || _this$api5 === void 0 ? void 0 : _this$api5.sharedState.currentState()) || {};
|
|
332
338
|
// selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
|
|
333
339
|
// This is a special case where we want to bypass node selection and jump straight to gap cursor
|
|
334
340
|
if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
|
|
@@ -383,6 +389,8 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
383
389
|
if (this.input) {
|
|
384
390
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
385
391
|
this.input.addEventListener('keydown', this.handleTitleKeydown);
|
|
392
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
393
|
+
this.input.addEventListener('blur', this.handleBlur);
|
|
386
394
|
}
|
|
387
395
|
if (this.titleContainer) {
|
|
388
396
|
// If the user interacts in our title bar (either toggle or input)
|
|
@@ -462,6 +470,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
462
470
|
}, {
|
|
463
471
|
key: "destroy",
|
|
464
472
|
value: function destroy() {
|
|
473
|
+
var _this$decorationClean2;
|
|
465
474
|
if (this.dom) {
|
|
466
475
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
467
476
|
this.dom.removeEventListener('click', this.handleClick);
|
|
@@ -471,6 +480,8 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
471
480
|
if (this.input) {
|
|
472
481
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
473
482
|
this.input.removeEventListener('keydown', this.handleTitleKeydown);
|
|
483
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
484
|
+
this.input.removeEventListener('blur', this.handleBlur);
|
|
474
485
|
}
|
|
475
486
|
if (this.titleContainer) {
|
|
476
487
|
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
@@ -481,6 +492,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
|
|
|
481
492
|
this.icon.removeEventListener('keydown', this.handleIconKeyDown);
|
|
482
493
|
ReactDOM.unmountComponentAtNode(this.icon);
|
|
483
494
|
}
|
|
495
|
+
(_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 || _this$decorationClean2.call(this);
|
|
484
496
|
|
|
485
497
|
// @ts-ignore - [unblock prosemirror bump] reset non optional prop to undefined to clear reference
|
|
486
498
|
this.dom = undefined;
|