@atlaskit/editor-plugin-block-controls 2.4.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/cjs/commands/move-node.js +7 -6
- package/dist/cjs/commands/show-drag-handle.js +2 -1
- package/dist/cjs/pm-plugins/decorations.js +93 -32
- package/dist/cjs/pm-plugins/keymap.js +5 -2
- package/dist/cjs/pm-plugins/main.js +349 -203
- package/dist/cjs/ui/drag-handle.js +4 -6
- package/dist/cjs/ui/drop-target-v2.js +32 -6
- package/dist/cjs/ui/drop-target.js +2 -0
- package/dist/cjs/ui/global-styles.js +1 -7
- package/dist/cjs/utils/transactions.js +63 -0
- package/dist/cjs/utils/validation.js +17 -0
- package/dist/es2019/commands/move-node.js +7 -6
- package/dist/es2019/commands/show-drag-handle.js +2 -1
- package/dist/es2019/pm-plugins/decorations.js +86 -31
- package/dist/es2019/pm-plugins/keymap.js +5 -2
- package/dist/es2019/pm-plugins/main.js +332 -179
- package/dist/es2019/ui/drag-handle.js +4 -8
- package/dist/es2019/ui/drop-target-v2.js +32 -6
- package/dist/es2019/ui/drop-target.js +2 -0
- package/dist/es2019/ui/global-styles.js +1 -7
- package/dist/es2019/utils/transactions.js +57 -0
- package/dist/es2019/utils/validation.js +17 -0
- package/dist/esm/commands/move-node.js +7 -6
- package/dist/esm/commands/show-drag-handle.js +2 -1
- package/dist/esm/pm-plugins/decorations.js +92 -31
- package/dist/esm/pm-plugins/keymap.js +5 -2
- package/dist/esm/pm-plugins/main.js +350 -204
- package/dist/esm/ui/drag-handle.js +4 -6
- package/dist/esm/ui/drop-target-v2.js +32 -6
- package/dist/esm/ui/drop-target.js +2 -0
- package/dist/esm/ui/global-styles.js +1 -7
- package/dist/esm/utils/transactions.js +57 -0
- package/dist/esm/utils/validation.js +17 -0
- package/dist/types/pm-plugins/decorations.d.ts +24 -4
- package/dist/types/pm-plugins/main.d.ts +32 -0
- package/dist/types/ui/drag-handle.d.ts +5 -14
- package/dist/types/ui/drop-target-v2.d.ts +1 -1
- package/dist/types/ui/drop-target.d.ts +2 -0
- package/dist/types/utils/transactions.d.ts +29 -0
- package/dist/types-ts4.5/pm-plugins/decorations.d.ts +24 -4
- package/dist/types-ts4.5/pm-plugins/main.d.ts +32 -0
- package/dist/types-ts4.5/ui/drag-handle.d.ts +5 -14
- package/dist/types-ts4.5/ui/drop-target-v2.d.ts +1 -1
- package/dist/types-ts4.5/ui/drop-target.d.ts +2 -0
- package/dist/types-ts4.5/utils/transactions.d.ts +29 -0
- package/package.json +5 -8
|
@@ -3,7 +3,7 @@ import { AnalyticsStep } from '@atlaskit/adf-schema/steps';
|
|
|
3
3
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { browser } from '@atlaskit/editor-common/browser';
|
|
5
5
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
|
-
import { isTextInput } from '@atlaskit/editor-common/utils';
|
|
6
|
+
import { isEmptyDocument, isTextInput } from '@atlaskit/editor-common/utils';
|
|
7
7
|
import { NodeSelection, PluginKey, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
8
8
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -13,7 +13,8 @@ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/ad
|
|
|
13
13
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
14
14
|
import { AnchorHeightsCache, isAnchorSupported } from '../utils/anchor-utils';
|
|
15
15
|
import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
|
|
16
|
-
import {
|
|
16
|
+
import { getTrMetadata } from '../utils/transactions';
|
|
17
|
+
import { dragHandleDecoration, dropTargetDecorations, emptyParagraphNodeDecorations, findDropTargetDecs, findHandleDec, findNodeDecs, nodeDecorations } from './decorations';
|
|
17
18
|
import { handleMouseOver } from './handle-mouse-over';
|
|
18
19
|
import { boundKeydownHandler } from './keymap';
|
|
19
20
|
export const key = new PluginKey('blockControls');
|
|
@@ -88,6 +89,313 @@ const initialState = {
|
|
|
88
89
|
isDocSizeLimitEnabled: null,
|
|
89
90
|
isPMDragging: false
|
|
90
91
|
};
|
|
92
|
+
export const newApply = (api, formatMessage, tr, currentState, newState, flags, anchorHeightsCache) => {
|
|
93
|
+
var _meta$activeNode, _activeNode, _activeNode2, _meta$activeNode$hand, _meta$isDragging, _meta$isDragging2, _meta$editorHeight, _meta$editorWidthLeft, _meta$editorWidthRigh, _meta$isPMDragging;
|
|
94
|
+
const {
|
|
95
|
+
isTitleEnterImprovementEnabled
|
|
96
|
+
} = flags;
|
|
97
|
+
let {
|
|
98
|
+
activeNode,
|
|
99
|
+
decorations,
|
|
100
|
+
editorHeight,
|
|
101
|
+
editorWidthLeft,
|
|
102
|
+
editorWidthRight,
|
|
103
|
+
isDragging,
|
|
104
|
+
isMenuOpen,
|
|
105
|
+
// NOT USED
|
|
106
|
+
isPMDragging,
|
|
107
|
+
// NOT USED
|
|
108
|
+
isResizerResizing
|
|
109
|
+
} = currentState;
|
|
110
|
+
let isActiveNodeDeleted = false;
|
|
111
|
+
|
|
112
|
+
// Remap existing decorations and activeNode when steps exist
|
|
113
|
+
if (tr.docChanged) {
|
|
114
|
+
decorations = decorations.map(tr.mapping, tr.doc);
|
|
115
|
+
if (activeNode) {
|
|
116
|
+
const mappedPos = tr.mapping.mapResult(activeNode.pos);
|
|
117
|
+
isActiveNodeDeleted = mappedPos.deleted;
|
|
118
|
+
activeNode = {
|
|
119
|
+
pos: mappedPos.pos,
|
|
120
|
+
anchorName: activeNode.anchorName,
|
|
121
|
+
nodeType: activeNode.nodeType
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const meta = tr.getMeta(key);
|
|
126
|
+
const resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
127
|
+
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
128
|
+
const {
|
|
129
|
+
from,
|
|
130
|
+
to,
|
|
131
|
+
numReplaceSteps,
|
|
132
|
+
isAllText
|
|
133
|
+
} = getTrMetadata(tr);
|
|
134
|
+
const maybeNodeCountChanged = !isAllText && numReplaceSteps > 0;
|
|
135
|
+
const latestActiveNode = (_meta$activeNode = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode !== void 0 ? _meta$activeNode : activeNode;
|
|
136
|
+
|
|
137
|
+
// Re-create node decorations
|
|
138
|
+
const isDecSetEmpty = decorations === DecorationSet.empty;
|
|
139
|
+
const isNodeDecsMissing = isDecSetEmpty || maybeNodeCountChanged;
|
|
140
|
+
const shouldRedrawNodeDecs = !isResizerResizing && isNodeDecsMissing;
|
|
141
|
+
let isActiveNodeModified = false;
|
|
142
|
+
if (api && shouldRedrawNodeDecs) {
|
|
143
|
+
const oldNodeDecs = findNodeDecs(decorations, from, to);
|
|
144
|
+
decorations = decorations.remove(oldNodeDecs);
|
|
145
|
+
const newNodeDecs = nodeDecorations(newState, isDecSetEmpty ? undefined : from, isDecSetEmpty ? undefined : to);
|
|
146
|
+
decorations = decorations.add(newState.doc, newNodeDecs);
|
|
147
|
+
if (latestActiveNode && !isActiveNodeDeleted) {
|
|
148
|
+
// Find the newly minted node decs that touch the active node
|
|
149
|
+
const findNewNodeDecs = findNodeDecs(decorations, latestActiveNode.pos - 1, to);
|
|
150
|
+
|
|
151
|
+
// Find the specific dec that the active node corresponds to
|
|
152
|
+
const nodeDecsAtActivePos = findNewNodeDecs.filter(dec => (dec === null || dec === void 0 ? void 0 : dec.from) === latestActiveNode.pos);
|
|
153
|
+
|
|
154
|
+
// If multiple decorations at the active node pos, we want the last one
|
|
155
|
+
const nodeDecAtActivePos = nodeDecsAtActivePos.pop();
|
|
156
|
+
|
|
157
|
+
// Update the active node anchor-name and type for accurate positioning
|
|
158
|
+
if (nodeDecAtActivePos) {
|
|
159
|
+
isActiveNodeModified = true;
|
|
160
|
+
latestActiveNode.anchorName = nodeDecAtActivePos.spec.anchorName;
|
|
161
|
+
latestActiveNode.nodeType = nodeDecAtActivePos.spec.nodeType;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Check if editor dimensions have changed
|
|
167
|
+
const editorSizeChanged = (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight;
|
|
168
|
+
|
|
169
|
+
// Check if there's a new active node, and it differs from the last
|
|
170
|
+
const activeNodeChanged = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== ((_activeNode = activeNode) === null || _activeNode === void 0 ? void 0 : _activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== ((_activeNode2 = activeNode) === null || _activeNode2 === void 0 ? void 0 : _activeNode2.anchorName) || (meta === null || meta === void 0 ? void 0 : (_meta$activeNode$hand = meta.activeNode.handleOptions) === null || _meta$activeNode$hand === void 0 ? void 0 : _meta$activeNode$hand.isFocused));
|
|
171
|
+
|
|
172
|
+
// Some browsers don't support anchor positioning, meaning we need to replace the handle when nodes change
|
|
173
|
+
const handleNeedsRedraw = shouldRedrawNodeDecs && !isAnchorSupported();
|
|
174
|
+
|
|
175
|
+
// Create/recreate handle dec when the active node is missing/changes, or the editor viewport has changed (non-anchor pos workaround)
|
|
176
|
+
const shouldRecreateHandle = latestActiveNode && (activeNodeChanged || isActiveNodeModified || editorSizeChanged || handleNeedsRedraw);
|
|
177
|
+
|
|
178
|
+
// Remove handle dec when explicitly hidden, a node is resizing, activeNode pos was deleted, or DnD moved a node
|
|
179
|
+
const shouldRemoveHandle = latestActiveNode && ((meta === null || meta === void 0 ? void 0 : meta.hideDragHandle) && isTitleEnterImprovementEnabled || isResizerResizing || isActiveNodeDeleted || (meta === null || meta === void 0 ? void 0 : meta.nodeMoved));
|
|
180
|
+
if (shouldRemoveHandle) {
|
|
181
|
+
var _activeNode3, _activeNode4;
|
|
182
|
+
const oldHandle = findHandleDec(decorations, (_activeNode3 = activeNode) === null || _activeNode3 === void 0 ? void 0 : _activeNode3.pos, (_activeNode4 = activeNode) === null || _activeNode4 === void 0 ? void 0 : _activeNode4.pos);
|
|
183
|
+
decorations = decorations.remove(oldHandle);
|
|
184
|
+
} else if (api && shouldRecreateHandle) {
|
|
185
|
+
var _activeNode5, _activeNode6;
|
|
186
|
+
const oldHandle = findHandleDec(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
|
|
187
|
+
decorations = decorations.remove(oldHandle);
|
|
188
|
+
const handleDec = dragHandleDecoration(api, formatMessage, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.anchorName, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.nodeType, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.handleOptions);
|
|
189
|
+
decorations = decorations.add(newState.doc, [handleDec]);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Drop targets may be missing when the node count is being changed during a drag
|
|
193
|
+
const isDropTargetsMissing = ((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
|
|
194
|
+
|
|
195
|
+
// Remove drop target decorations when dragging stops or they need to be redrawn
|
|
196
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || isDropTargetsMissing) {
|
|
197
|
+
const dropTargetDecs = findDropTargetDecs(decorations);
|
|
198
|
+
decorations = decorations.remove(dropTargetDecs);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Add drop targets when dragging starts or some are missing
|
|
202
|
+
if (api) {
|
|
203
|
+
if (meta !== null && meta !== void 0 && meta.isDragging || isDropTargetsMissing || isBlocksDragTargetDebug()) {
|
|
204
|
+
const decs = dropTargetDecorations(newState, api, formatMessage, latestActiveNode, anchorHeightsCache);
|
|
205
|
+
decorations = decorations.add(newState.doc, decs);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const isEmptyDoc = isEmptyDocument(newState.doc);
|
|
209
|
+
if (isEmptyDoc) {
|
|
210
|
+
const hasNodeDecoration = !!findNodeDecs(decorations).length;
|
|
211
|
+
if (!hasNodeDecoration) {
|
|
212
|
+
decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos, latestActiveNode === null || latestActiveNode === void 0 ? void 0 : latestActiveNode.pos).length === 0 ? null : latestActiveNode;
|
|
216
|
+
return {
|
|
217
|
+
decorations,
|
|
218
|
+
activeNode: newActiveNode,
|
|
219
|
+
isDragging: (_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging,
|
|
220
|
+
isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
|
|
221
|
+
editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : editorHeight,
|
|
222
|
+
editorWidthLeft: (_meta$editorWidthLeft = meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== null && _meta$editorWidthLeft !== void 0 ? _meta$editorWidthLeft : editorWidthLeft,
|
|
223
|
+
editorWidthRight: (_meta$editorWidthRigh = meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== null && _meta$editorWidthRigh !== void 0 ? _meta$editorWidthRigh : editorWidthRight,
|
|
224
|
+
isResizerResizing: isResizerResizing,
|
|
225
|
+
isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled,
|
|
226
|
+
isPMDragging: (_meta$isPMDragging = meta === null || meta === void 0 ? void 0 : meta.isPMDragging) !== null && _meta$isPMDragging !== void 0 ? _meta$isPMDragging : isPMDragging
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
export const oldApply = (api, formatMessage, tr, currentState, oldState, newState, flags, anchorHeightsCache) => {
|
|
230
|
+
var _meta$activeNode2, _meta$activeNode$hand2, _activeNodeWithNewNod, _meta$activeNode8, _meta$isDragging4, _meta$editorHeight2, _meta$editorWidthLeft2, _meta$editorWidthRigh2, _meta$isPMDragging2;
|
|
231
|
+
const {
|
|
232
|
+
isNestedEnabled,
|
|
233
|
+
isTitleEnterImprovementEnabled
|
|
234
|
+
} = flags;
|
|
235
|
+
let {
|
|
236
|
+
activeNode,
|
|
237
|
+
decorations,
|
|
238
|
+
isMenuOpen,
|
|
239
|
+
editorHeight,
|
|
240
|
+
editorWidthLeft,
|
|
241
|
+
editorWidthRight,
|
|
242
|
+
isResizerResizing,
|
|
243
|
+
isDragging,
|
|
244
|
+
isPMDragging
|
|
245
|
+
} = currentState;
|
|
246
|
+
|
|
247
|
+
// Remap existing decorations when steps exist
|
|
248
|
+
if (tr.docChanged) {
|
|
249
|
+
decorations = decorations.map(tr.mapping, tr.doc);
|
|
250
|
+
}
|
|
251
|
+
const meta = tr.getMeta(key);
|
|
252
|
+
const isPerformanceFix = isNestedEnabled || editorExperiment('dnd-input-performance-optimisation', true, {
|
|
253
|
+
exposure: true
|
|
254
|
+
});
|
|
255
|
+
let activeNodeWithNewNodeType = null;
|
|
256
|
+
|
|
257
|
+
// If tables or media are being resized, we want to hide the drag handle
|
|
258
|
+
const resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
259
|
+
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
260
|
+
const canIgnoreTr = () => !tr.steps.every(e => e instanceof AnalyticsStep);
|
|
261
|
+
const maybeNodeCountChanged = isNestedEnabled ? !isTextInput(tr) && tr.docChanged && canIgnoreTr() : oldState.doc.childCount !== newState.doc.childCount;
|
|
262
|
+
const shouldRemoveHandle = !tr.getMeta('isRemote');
|
|
263
|
+
|
|
264
|
+
// During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
|
|
265
|
+
// Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
|
|
266
|
+
// Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
|
|
267
|
+
if (meta !== null && meta !== void 0 && meta.hideDragHandle && isTitleEnterImprovementEnabled || isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
|
|
268
|
+
const oldHandle = decorations.find(undefined, undefined, spec => spec.type === 'drag-handle');
|
|
269
|
+
decorations = decorations.remove(oldHandle);
|
|
270
|
+
}
|
|
271
|
+
const decsLength = isNestedEnabled ? decorations.find(undefined, undefined, spec => spec.type === 'node-decoration').length : decorations.find().filter(({
|
|
272
|
+
spec
|
|
273
|
+
}) => spec.type !== 'drag-handle').length;
|
|
274
|
+
let isDecsMissing = false;
|
|
275
|
+
let isDropTargetsMissing = false;
|
|
276
|
+
if (isNestedEnabled) {
|
|
277
|
+
var _meta$isDragging3;
|
|
278
|
+
isDecsMissing = !(isDragging || meta !== null && meta !== void 0 && meta.isDragging) && maybeNodeCountChanged;
|
|
279
|
+
isDropTargetsMissing = ((_meta$isDragging3 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging3 !== void 0 ? _meta$isDragging3 : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
|
|
280
|
+
} else {
|
|
281
|
+
isDecsMissing = !(isDragging || meta !== null && meta !== void 0 && meta.isDragging) && decsLength !== newState.doc.childCount;
|
|
282
|
+
const dropTargetLen = decorations.find(undefined, undefined, spec => spec.type === 'drop-target-decoration').length;
|
|
283
|
+
isDropTargetsMissing = isDragging && (meta === null || meta === void 0 ? void 0 : meta.isDragging) !== false && dropTargetLen !== newState.doc.childCount + 1;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// This is not targeted enough - it's trying to catch events like expand being set to breakout
|
|
287
|
+
const maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && !maybeNodeCountChanged;
|
|
288
|
+
|
|
289
|
+
// This addresses scenarios such as undoing table resizing,
|
|
290
|
+
// where a keyboard shortcut triggers a width change, and
|
|
291
|
+
// the node's actual width is then updated in a separate renderering cycle.
|
|
292
|
+
// The tr.meta.activeNode is triggered by the showDragHandleAt function during the mouse entry event
|
|
293
|
+
// (when the table node rerenders)
|
|
294
|
+
// The activeNode is from the previous rendering cycle, and verify if they share the same anchor.
|
|
295
|
+
const maybeTableWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 ? void 0 : (_meta$activeNode2 = meta.activeNode) === null || _meta$activeNode2 === void 0 ? void 0 : _meta$activeNode2.nodeType) === 'table' && meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName);
|
|
296
|
+
const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || maybeNodeCountChanged || maybeTableWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
|
|
297
|
+
|
|
298
|
+
// Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
|
|
299
|
+
if (redrawDecorations && !isResizerResizing && api) {
|
|
300
|
+
const oldNodeDecs = decorations.find(undefined, undefined, spec => spec.type !== 'drop-target-decoration');
|
|
301
|
+
decorations = decorations.remove(oldNodeDecs);
|
|
302
|
+
const newNodeDecs = nodeDecorations(newState);
|
|
303
|
+
decorations = decorations.add(newState.doc, [...newNodeDecs]);
|
|
304
|
+
if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
|
|
305
|
+
let mappedPosisiton = tr.mapping.map(activeNode.pos);
|
|
306
|
+
const prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
|
|
307
|
+
|
|
308
|
+
// When a node type changed to be nested inside another node, the position of the active node is off by 1
|
|
309
|
+
// This is a workaround to fix the position of the active node when it is nested
|
|
310
|
+
if (tr.docChanged && !maybeNodeCountChanged && mappedPosisiton === prevMappedPos + 1) {
|
|
311
|
+
mappedPosisiton = prevMappedPos;
|
|
312
|
+
}
|
|
313
|
+
const newActiveNode = tr.doc.nodeAt(mappedPosisiton);
|
|
314
|
+
let draghandleDec;
|
|
315
|
+
if (isPerformanceFix) {
|
|
316
|
+
var _meta$activeNode$pos, _meta$activeNode3, _ref, _meta$activeNode$anch, _meta$activeNode4, _decAtPos$spec, _ref2, _meta$activeNode$node, _meta$activeNode5, _decAtPos$spec2, _meta$activeNode6;
|
|
317
|
+
if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
|
|
318
|
+
const oldHandle = decorations.find(undefined, undefined, spec => spec.type === 'drag-handle');
|
|
319
|
+
decorations = decorations.remove(oldHandle);
|
|
320
|
+
}
|
|
321
|
+
const decAtPos = newNodeDecs.find(dec => dec.from === mappedPosisiton);
|
|
322
|
+
draghandleDec = dragHandleDecoration(api, formatMessage, (_meta$activeNode$pos = meta === null || meta === void 0 ? void 0 : (_meta$activeNode3 = meta.activeNode) === null || _meta$activeNode3 === void 0 ? void 0 : _meta$activeNode3.pos) !== null && _meta$activeNode$pos !== void 0 ? _meta$activeNode$pos : mappedPosisiton, (_ref = (_meta$activeNode$anch = meta === null || meta === void 0 ? void 0 : (_meta$activeNode4 = meta.activeNode) === null || _meta$activeNode4 === void 0 ? void 0 : _meta$activeNode4.anchorName) !== null && _meta$activeNode$anch !== void 0 ? _meta$activeNode$anch : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec = decAtPos.spec) === null || _decAtPos$spec === void 0 ? void 0 : _decAtPos$spec.anchorName) !== null && _ref !== void 0 ? _ref : activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName, (_ref2 = (_meta$activeNode$node = meta === null || meta === void 0 ? void 0 : (_meta$activeNode5 = meta.activeNode) === null || _meta$activeNode5 === void 0 ? void 0 : _meta$activeNode5.nodeType) !== null && _meta$activeNode$node !== void 0 ? _meta$activeNode$node : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec2 = decAtPos.spec) === null || _decAtPos$spec2 === void 0 ? void 0 : _decAtPos$spec2.nodeType) !== null && _ref2 !== void 0 ? _ref2 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType, meta === null || meta === void 0 ? void 0 : (_meta$activeNode6 = meta.activeNode) === null || _meta$activeNode6 === void 0 ? void 0 : _meta$activeNode6.handleOptions);
|
|
323
|
+
} else {
|
|
324
|
+
let nodeType = activeNode.nodeType;
|
|
325
|
+
let anchorName = activeNode.anchorName;
|
|
326
|
+
if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
|
|
327
|
+
nodeType = newActiveNode.type.name;
|
|
328
|
+
anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
|
|
329
|
+
activeNodeWithNewNodeType = {
|
|
330
|
+
pos: prevMappedPos,
|
|
331
|
+
nodeType,
|
|
332
|
+
anchorName
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
draghandleDec = dragHandleDecoration(api, formatMessage, activeNode.pos, anchorName, nodeType);
|
|
336
|
+
}
|
|
337
|
+
decorations = decorations.add(newState.doc, [draghandleDec]);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Remove previous drag handle widget and draw new drag handle widget when activeNode changes
|
|
342
|
+
if (api && meta !== null && meta !== void 0 && meta.activeNode && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) || meta !== null && meta !== void 0 && (_meta$activeNode$hand2 = meta.activeNode.handleOptions) !== null && _meta$activeNode$hand2 !== void 0 && _meta$activeNode$hand2.isFocused)) {
|
|
343
|
+
const oldHandle = decorations.find(undefined, undefined, spec => spec.type === 'drag-handle');
|
|
344
|
+
decorations = decorations.remove(oldHandle);
|
|
345
|
+
const decs = dragHandleDecoration(api, formatMessage, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
|
|
346
|
+
decorations = decorations.add(newState.doc, [decs]);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Remove previous drag handle widget and draw new drag handle widget when node type changes
|
|
350
|
+
if (!isPerformanceFix && activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
|
|
351
|
+
const oldHandle = decorations.find(undefined, undefined, spec => spec.type === 'drag-handle');
|
|
352
|
+
decorations = decorations.remove(oldHandle);
|
|
353
|
+
const decs = dragHandleDecoration(api, formatMessage, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
|
|
354
|
+
decorations = decorations.add(newState.doc, [decs]);
|
|
355
|
+
}
|
|
356
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || isDropTargetsMissing) {
|
|
357
|
+
// Remove drop target decoration when dragging stops
|
|
358
|
+
const dropTargetDecs = decorations.find(undefined, undefined, spec => spec.type === 'drop-target-decoration');
|
|
359
|
+
decorations = decorations.remove(dropTargetDecs);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Map active node position when the document changes
|
|
363
|
+
const mappedActiveNodePos = tr.docChanged && activeNode ? !isPerformanceFix && activeNodeWithNewNodeType || {
|
|
364
|
+
pos: tr.mapping.map(activeNode.pos),
|
|
365
|
+
anchorName: activeNode.anchorName,
|
|
366
|
+
nodeType: activeNode.nodeType
|
|
367
|
+
} : activeNode;
|
|
368
|
+
const shouldCreateDropTargets = (meta === null || meta === void 0 ? void 0 : meta.isDragging) || isDropTargetsMissing;
|
|
369
|
+
if (api) {
|
|
370
|
+
// Add drop targets when node is being dragged
|
|
371
|
+
// if the transaction is only for analytics and user is dragging, continue to draw drop targets
|
|
372
|
+
if (shouldCreateDropTargets || isBlocksDragTargetDebug()) {
|
|
373
|
+
var _meta$activeNode7;
|
|
374
|
+
const decs = dropTargetDecorations(newState, api, formatMessage, isNestedEnabled ? (_meta$activeNode7 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode7 !== void 0 ? _meta$activeNode7 : mappedActiveNodePos : meta === null || meta === void 0 ? void 0 : meta.activeNode, anchorHeightsCache);
|
|
375
|
+
decorations = decorations.add(newState.doc, decs);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const isEmptyDoc = isNestedEnabled ? newState.doc.childCount === 1 && newState.doc.nodeSize <= 4 && (newState.doc.firstChild === null || newState.doc.firstChild.nodeSize <= 2) : newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
|
|
379
|
+
if (isEmptyDoc) {
|
|
380
|
+
const hasNodeDecoration = !!decorations.find(undefined, undefined, spec => spec.type === 'node-decoration').length;
|
|
381
|
+
if (!hasNodeDecoration) {
|
|
382
|
+
decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && decorations.find(undefined, undefined, spec => spec.type === 'drag-handle').length === 0 ? null : (_meta$activeNode8 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode8 !== void 0 ? _meta$activeNode8 : mappedActiveNodePos;
|
|
386
|
+
return {
|
|
387
|
+
decorations,
|
|
388
|
+
activeNode: newActiveNode,
|
|
389
|
+
isDragging: (_meta$isDragging4 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging4 !== void 0 ? _meta$isDragging4 : isDragging,
|
|
390
|
+
isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
|
|
391
|
+
editorHeight: (_meta$editorHeight2 = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight2 !== void 0 ? _meta$editorHeight2 : currentState.editorHeight,
|
|
392
|
+
editorWidthLeft: (_meta$editorWidthLeft2 = meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== null && _meta$editorWidthLeft2 !== void 0 ? _meta$editorWidthLeft2 : currentState.editorWidthLeft,
|
|
393
|
+
editorWidthRight: (_meta$editorWidthRigh2 = meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== null && _meta$editorWidthRigh2 !== void 0 ? _meta$editorWidthRigh2 : currentState.editorWidthRight,
|
|
394
|
+
isResizerResizing: isResizerResizing,
|
|
395
|
+
isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled,
|
|
396
|
+
isPMDragging: (_meta$isPMDragging2 = meta === null || meta === void 0 ? void 0 : meta.isPMDragging) !== null && _meta$isPMDragging2 !== void 0 ? _meta$isPMDragging2 : isPMDragging
|
|
397
|
+
};
|
|
398
|
+
};
|
|
91
399
|
export const createPlugin = (api, getIntl) => {
|
|
92
400
|
const {
|
|
93
401
|
formatMessage
|
|
@@ -95,6 +403,15 @@ export const createPlugin = (api, getIntl) => {
|
|
|
95
403
|
const isNestedEnabled = editorExperiment('nested-dnd', true, {
|
|
96
404
|
exposure: true
|
|
97
405
|
});
|
|
406
|
+
const isOptimisedApply = isNestedEnabled && editorExperiment('optimised-apply-dnd', true, {
|
|
407
|
+
exposure: true
|
|
408
|
+
});
|
|
409
|
+
const isTitleEnterImprovementEnabled = fg('confluence_frontend_page_title_enter_improvements');
|
|
410
|
+
const flags = {
|
|
411
|
+
isNestedEnabled,
|
|
412
|
+
isOptimisedApply,
|
|
413
|
+
isTitleEnterImprovementEnabled
|
|
414
|
+
};
|
|
98
415
|
if (fg('platform_editor_element_dnd_nested_fix_patch_2')) {
|
|
99
416
|
// TODO: Remove this once FG is used in code
|
|
100
417
|
}
|
|
@@ -109,170 +426,10 @@ export const createPlugin = (api, getIntl) => {
|
|
|
109
426
|
return initialState;
|
|
110
427
|
},
|
|
111
428
|
apply(tr, currentState, oldState, newState) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
activeNode,
|
|
115
|
-
decorations,
|
|
116
|
-
isMenuOpen,
|
|
117
|
-
editorHeight,
|
|
118
|
-
editorWidthLeft,
|
|
119
|
-
editorWidthRight,
|
|
120
|
-
isResizerResizing,
|
|
121
|
-
isDragging,
|
|
122
|
-
isPMDragging
|
|
123
|
-
} = currentState;
|
|
124
|
-
|
|
125
|
-
// Remap existing decorations when steps exist
|
|
126
|
-
if (tr.docChanged) {
|
|
127
|
-
decorations = decorations.map(tr.mapping, tr.doc);
|
|
128
|
-
}
|
|
129
|
-
const meta = tr.getMeta(key);
|
|
130
|
-
const isPerformanceFix = isNestedEnabled || editorExperiment('dnd-input-performance-optimisation', true, {
|
|
131
|
-
exposure: true
|
|
132
|
-
});
|
|
133
|
-
let activeNodeWithNewNodeType = null;
|
|
134
|
-
|
|
135
|
-
// If tables or media are being resized, we want to hide the drag handle
|
|
136
|
-
const resizerMeta = tr.getMeta('is-resizer-resizing');
|
|
137
|
-
isResizerResizing = resizerMeta !== null && resizerMeta !== void 0 ? resizerMeta : isResizerResizing;
|
|
138
|
-
const canIgnoreTr = () => !tr.steps.every(e => e instanceof AnalyticsStep);
|
|
139
|
-
const maybeNodeCountChanged = isNestedEnabled ? !isTextInput(tr) && tr.docChanged && canIgnoreTr() : oldState.doc.childCount !== newState.doc.childCount;
|
|
140
|
-
const shouldRemoveHandle = !tr.getMeta('isRemote');
|
|
141
|
-
|
|
142
|
-
// During resize, remove the drag handle widget so its dom positioning doesn't need to be maintained
|
|
143
|
-
// Also remove the handle when the node is moved or the node count changes. This helps prevent incorrect positioning
|
|
144
|
-
// Don't remove the handle if remote changes are changing the node count, its prosemirror position can be mapped instead
|
|
145
|
-
if (meta !== null && meta !== void 0 && meta.hideDragHandle && fg('confluence_frontend_page_title_enter_improvements') || isResizerResizing || maybeNodeCountChanged && shouldRemoveHandle || meta !== null && meta !== void 0 && meta.nodeMoved) {
|
|
146
|
-
const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
|
|
147
|
-
decorations = decorations.remove(oldHandle);
|
|
148
|
-
}
|
|
149
|
-
const decsLength = isNestedEnabled ? decorations.find(undefined, undefined, spec => spec.type === 'node-decoration').length : decorations.find().filter(({
|
|
150
|
-
spec
|
|
151
|
-
}) => spec.id !== 'drag-handle').length;
|
|
152
|
-
let isDecsMissing = false;
|
|
153
|
-
let isDropTargetsMissing = false;
|
|
154
|
-
if (isNestedEnabled) {
|
|
155
|
-
var _meta$isDragging;
|
|
156
|
-
isDecsMissing = !(isDragging || meta !== null && meta !== void 0 && meta.isDragging) && maybeNodeCountChanged;
|
|
157
|
-
isDropTargetsMissing = ((_meta$isDragging = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging !== void 0 ? _meta$isDragging : isDragging) && maybeNodeCountChanged && !(meta !== null && meta !== void 0 && meta.nodeMoved);
|
|
158
|
-
} else {
|
|
159
|
-
isDecsMissing = !(isDragging || meta !== null && meta !== void 0 && meta.isDragging) && decsLength !== newState.doc.childCount;
|
|
160
|
-
const dropTargetLen = decorations.find(undefined, undefined, spec => spec.type === 'drop-target-decoration').length;
|
|
161
|
-
isDropTargetsMissing = isDragging && (meta === null || meta === void 0 ? void 0 : meta.isDragging) !== false && dropTargetLen !== newState.doc.childCount + 1;
|
|
429
|
+
if (isOptimisedApply) {
|
|
430
|
+
return newApply(api, formatMessage, tr, currentState, newState, flags, anchorHeightsCache);
|
|
162
431
|
}
|
|
163
|
-
|
|
164
|
-
// This is not targeted enough - it's trying to catch events like expand being set to breakout
|
|
165
|
-
const maybeWidthUpdated = tr.docChanged && oldState.doc.nodeSize === newState.doc.nodeSize && !maybeNodeCountChanged;
|
|
166
|
-
|
|
167
|
-
// This addresses scenarios such as undoing table resizing,
|
|
168
|
-
// where a keyboard shortcut triggers a width change, and
|
|
169
|
-
// the node's actual width is then updated in a separate renderering cycle.
|
|
170
|
-
// The tr.meta.activeNode is triggered by the showDragHandleAt function during the mouse entry event
|
|
171
|
-
// (when the table node rerenders)
|
|
172
|
-
// The activeNode is from the previous rendering cycle, and verify if they share the same anchor.
|
|
173
|
-
const maybeTableWidthUpdated = (meta === null || meta === void 0 ? void 0 : meta.activeNode) && (meta === null || meta === void 0 ? void 0 : (_meta$activeNode = meta.activeNode) === null || _meta$activeNode === void 0 ? void 0 : _meta$activeNode.nodeType) === 'table' && meta.activeNode.anchorName === (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName);
|
|
174
|
-
const redrawDecorations = decorations === DecorationSet.empty || (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== editorHeight || (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== editorWidthLeft || (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== undefined && (meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== editorWidthRight || maybeWidthUpdated || maybeNodeCountChanged || maybeTableWidthUpdated || resizerMeta === false || isDecsMissing || !!(meta !== null && meta !== void 0 && meta.nodeMoved) && tr.docChanged;
|
|
175
|
-
|
|
176
|
-
// Draw node and mouseWrapper decorations at top level node if decorations is empty, editor height changes or node is moved
|
|
177
|
-
if (redrawDecorations && !isResizerResizing && api) {
|
|
178
|
-
const oldNodeDecs = decorations.find(undefined, undefined, spec => spec.type !== 'drop-target-decoration');
|
|
179
|
-
decorations = decorations.remove(oldNodeDecs);
|
|
180
|
-
const newNodeDecs = nodeDecorations(newState);
|
|
181
|
-
decorations = decorations.add(newState.doc, [...newNodeDecs]);
|
|
182
|
-
if (activeNode && !(meta !== null && meta !== void 0 && meta.nodeMoved) && !isDecsMissing) {
|
|
183
|
-
let mappedPosisiton = tr.mapping.map(activeNode.pos);
|
|
184
|
-
const prevMappedPos = oldState.tr.mapping.map(activeNode.pos);
|
|
185
|
-
|
|
186
|
-
// When a node type changed to be nested inside another node, the position of the active node is off by 1
|
|
187
|
-
// This is a workaround to fix the position of the active node when it is nested
|
|
188
|
-
if (tr.docChanged && !maybeNodeCountChanged && mappedPosisiton === prevMappedPos + 1) {
|
|
189
|
-
mappedPosisiton = prevMappedPos;
|
|
190
|
-
}
|
|
191
|
-
const newActiveNode = tr.doc.nodeAt(mappedPosisiton);
|
|
192
|
-
let draghandleDec;
|
|
193
|
-
if (isPerformanceFix) {
|
|
194
|
-
var _meta$activeNode$pos, _meta$activeNode2, _ref, _meta$activeNode$anch, _meta$activeNode3, _decAtPos$spec, _ref2, _meta$activeNode$node, _meta$activeNode4, _decAtPos$spec2, _meta$activeNode5;
|
|
195
|
-
if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
|
|
196
|
-
const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
|
|
197
|
-
decorations = decorations.remove(oldHandle);
|
|
198
|
-
}
|
|
199
|
-
const decAtPos = newNodeDecs.find(dec => dec.from === mappedPosisiton);
|
|
200
|
-
draghandleDec = dragHandleDecoration(api, getIntl, (_meta$activeNode$pos = meta === null || meta === void 0 ? void 0 : (_meta$activeNode2 = meta.activeNode) === null || _meta$activeNode2 === void 0 ? void 0 : _meta$activeNode2.pos) !== null && _meta$activeNode$pos !== void 0 ? _meta$activeNode$pos : mappedPosisiton, (_ref = (_meta$activeNode$anch = meta === null || meta === void 0 ? void 0 : (_meta$activeNode3 = meta.activeNode) === null || _meta$activeNode3 === void 0 ? void 0 : _meta$activeNode3.anchorName) !== null && _meta$activeNode$anch !== void 0 ? _meta$activeNode$anch : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec = decAtPos.spec) === null || _decAtPos$spec === void 0 ? void 0 : _decAtPos$spec.anchorName) !== null && _ref !== void 0 ? _ref : activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName, (_ref2 = (_meta$activeNode$node = meta === null || meta === void 0 ? void 0 : (_meta$activeNode4 = meta.activeNode) === null || _meta$activeNode4 === void 0 ? void 0 : _meta$activeNode4.nodeType) !== null && _meta$activeNode$node !== void 0 ? _meta$activeNode$node : decAtPos === null || decAtPos === void 0 ? void 0 : (_decAtPos$spec2 = decAtPos.spec) === null || _decAtPos$spec2 === void 0 ? void 0 : _decAtPos$spec2.nodeType) !== null && _ref2 !== void 0 ? _ref2 : activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType, meta === null || meta === void 0 ? void 0 : (_meta$activeNode5 = meta.activeNode) === null || _meta$activeNode5 === void 0 ? void 0 : _meta$activeNode5.handleOptions);
|
|
201
|
-
} else {
|
|
202
|
-
let nodeType = activeNode.nodeType;
|
|
203
|
-
let anchorName = activeNode.anchorName;
|
|
204
|
-
if (newActiveNode && (newActiveNode === null || newActiveNode === void 0 ? void 0 : newActiveNode.type.name) !== activeNode.nodeType) {
|
|
205
|
-
nodeType = newActiveNode.type.name;
|
|
206
|
-
anchorName = activeNode.anchorName.replace(activeNode.nodeType, nodeType);
|
|
207
|
-
activeNodeWithNewNodeType = {
|
|
208
|
-
pos: prevMappedPos,
|
|
209
|
-
nodeType,
|
|
210
|
-
anchorName
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
draghandleDec = dragHandleDecoration(api, getIntl, activeNode.pos, anchorName, nodeType);
|
|
214
|
-
}
|
|
215
|
-
decorations = decorations.add(newState.doc, [draghandleDec]);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// Remove previous drag handle widget and draw new drag handle widget when activeNode changes
|
|
220
|
-
if (api && meta !== null && meta !== void 0 && meta.activeNode && ((meta === null || meta === void 0 ? void 0 : meta.activeNode.pos) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos) && (meta === null || meta === void 0 ? void 0 : meta.activeNode.anchorName) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.anchorName) || meta !== null && meta !== void 0 && (_meta$activeNode$hand = meta.activeNode.handleOptions) !== null && _meta$activeNode$hand !== void 0 && _meta$activeNode$hand.isFocused)) {
|
|
221
|
-
const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
|
|
222
|
-
decorations = decorations.remove(oldHandle);
|
|
223
|
-
const decs = dragHandleDecoration(api, getIntl, meta.activeNode.pos, meta.activeNode.anchorName, meta.activeNode.nodeType, meta.activeNode.handleOptions);
|
|
224
|
-
decorations = decorations.add(newState.doc, [decs]);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Remove previous drag handle widget and draw new drag handle widget when node type changes
|
|
228
|
-
if (!isPerformanceFix && activeNodeWithNewNodeType && ((_activeNodeWithNewNod = activeNodeWithNewNodeType) === null || _activeNodeWithNewNod === void 0 ? void 0 : _activeNodeWithNewNod.nodeType) !== (activeNode === null || activeNode === void 0 ? void 0 : activeNode.nodeType) && api) {
|
|
229
|
-
const oldHandle = decorations.find(undefined, undefined, spec => spec.id === 'drag-handle');
|
|
230
|
-
decorations = decorations.remove(oldHandle);
|
|
231
|
-
const decs = dragHandleDecoration(api, getIntl, activeNodeWithNewNodeType.pos, activeNodeWithNewNodeType.anchorName, activeNodeWithNewNodeType.nodeType);
|
|
232
|
-
decorations = decorations.add(newState.doc, [decs]);
|
|
233
|
-
}
|
|
234
|
-
if ((meta === null || meta === void 0 ? void 0 : meta.isDragging) === false || isDropTargetsMissing) {
|
|
235
|
-
// Remove drop target decoration when dragging stops
|
|
236
|
-
const dropTargetDecs = decorations.find(undefined, undefined, spec => spec.type === 'drop-target-decoration');
|
|
237
|
-
decorations = decorations.remove(dropTargetDecs);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Map active node position when the document changes
|
|
241
|
-
const mappedActiveNodePos = tr.docChanged && activeNode ? !isPerformanceFix && activeNodeWithNewNodeType || {
|
|
242
|
-
pos: tr.mapping.map(activeNode.pos),
|
|
243
|
-
anchorName: activeNode.anchorName,
|
|
244
|
-
nodeType: activeNode.nodeType
|
|
245
|
-
} : activeNode;
|
|
246
|
-
const shouldCreateDropTargets = (meta === null || meta === void 0 ? void 0 : meta.isDragging) || isDropTargetsMissing;
|
|
247
|
-
if (api) {
|
|
248
|
-
// Add drop targets when node is being dragged
|
|
249
|
-
// if the transaction is only for analytics and user is dragging, continue to draw drop targets
|
|
250
|
-
if (shouldCreateDropTargets || isBlocksDragTargetDebug()) {
|
|
251
|
-
var _meta$activeNode6;
|
|
252
|
-
const decs = dropTargetDecorations(newState, api, formatMessage, isNestedEnabled ? (_meta$activeNode6 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode6 !== void 0 ? _meta$activeNode6 : mappedActiveNodePos : meta === null || meta === void 0 ? void 0 : meta.activeNode, anchorHeightsCache);
|
|
253
|
-
decorations = decorations.add(newState.doc, decs);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
const isEmptyDoc = isNestedEnabled ? newState.doc.childCount === 1 && newState.doc.nodeSize <= 4 && (newState.doc.firstChild === null || newState.doc.firstChild.nodeSize <= 2) : newState.doc.childCount === 1 && newState.doc.nodeSize <= 4;
|
|
257
|
-
if (isEmptyDoc) {
|
|
258
|
-
const hasNodeDecoration = !!decorations.find(undefined, undefined, spec => spec.type === 'node-decoration').length;
|
|
259
|
-
if (!hasNodeDecoration) {
|
|
260
|
-
decorations = decorations.add(newState.doc, [emptyParagraphNodeDecorations()]);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
const newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && decorations.find(undefined, undefined, spec => spec.id === 'drag-handle').length === 0 ? null : (_meta$activeNode7 = meta === null || meta === void 0 ? void 0 : meta.activeNode) !== null && _meta$activeNode7 !== void 0 ? _meta$activeNode7 : mappedActiveNodePos;
|
|
264
|
-
return {
|
|
265
|
-
decorations,
|
|
266
|
-
activeNode: newActiveNode,
|
|
267
|
-
isDragging: (_meta$isDragging2 = meta === null || meta === void 0 ? void 0 : meta.isDragging) !== null && _meta$isDragging2 !== void 0 ? _meta$isDragging2 : isDragging,
|
|
268
|
-
isMenuOpen: meta !== null && meta !== void 0 && meta.toggleMenu ? !isMenuOpen : isMenuOpen,
|
|
269
|
-
editorHeight: (_meta$editorHeight = meta === null || meta === void 0 ? void 0 : meta.editorHeight) !== null && _meta$editorHeight !== void 0 ? _meta$editorHeight : currentState.editorHeight,
|
|
270
|
-
editorWidthLeft: (_meta$editorWidthLeft = meta === null || meta === void 0 ? void 0 : meta.editorWidthLeft) !== null && _meta$editorWidthLeft !== void 0 ? _meta$editorWidthLeft : currentState.editorWidthLeft,
|
|
271
|
-
editorWidthRight: (_meta$editorWidthRigh = meta === null || meta === void 0 ? void 0 : meta.editorWidthRight) !== null && _meta$editorWidthRigh !== void 0 ? _meta$editorWidthRigh : currentState.editorWidthRight,
|
|
272
|
-
isResizerResizing: isResizerResizing,
|
|
273
|
-
isDocSizeLimitEnabled: initialState.isDocSizeLimitEnabled,
|
|
274
|
-
isPMDragging: (_meta$isPMDragging = meta === null || meta === void 0 ? void 0 : meta.isPMDragging) !== null && _meta$isPMDragging !== void 0 ? _meta$isPMDragging : isPMDragging
|
|
275
|
-
};
|
|
432
|
+
return oldApply(api, formatMessage, tr, currentState, oldState, newState, flags, anchorHeightsCache);
|
|
276
433
|
}
|
|
277
434
|
},
|
|
278
435
|
props: {
|
|
@@ -376,13 +533,8 @@ export const createPlugin = (api, getIntl) => {
|
|
|
376
533
|
const dom = editorView.dom;
|
|
377
534
|
const editorContentArea = editorView.dom.closest('.fabric-editor-popup-scroll-parent');
|
|
378
535
|
|
|
379
|
-
// Use ResizeObserver to observe width changes
|
|
536
|
+
// Use ResizeObserver to observe resizer (scroll-parent typically grows when resizing) and editor width changes
|
|
380
537
|
const resizeObserverWidth = new ResizeObserver(rafSchedule(entries => {
|
|
381
|
-
const editorContentArea = entries[0].target;
|
|
382
|
-
const editorWidthRight = editorContentArea.getBoundingClientRect().right;
|
|
383
|
-
const editorWidthLeft = editorContentArea.getBoundingClientRect().left;
|
|
384
|
-
|
|
385
|
-
// Update the plugin state when the height changes
|
|
386
538
|
const pluginState = key.getState(editorView.state);
|
|
387
539
|
if (!(pluginState !== null && pluginState !== void 0 && pluginState.isDragging)) {
|
|
388
540
|
const isResizerResizing = !!dom.querySelector('.is-resizing');
|
|
@@ -391,17 +543,18 @@ export const createPlugin = (api, getIntl) => {
|
|
|
391
543
|
transaction.setMeta('is-resizer-resizing', isResizerResizing);
|
|
392
544
|
}
|
|
393
545
|
if (!isResizerResizing) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
546
|
+
const editorContentArea = entries[0].target;
|
|
547
|
+
const editorWidthRight = editorContentArea.getBoundingClientRect().right;
|
|
548
|
+
const editorWidthLeft = editorContentArea.getBoundingClientRect().left;
|
|
549
|
+
transaction.setMeta(key, {
|
|
550
|
+
editorWidthLeft,
|
|
551
|
+
editorWidthRight
|
|
552
|
+
});
|
|
400
553
|
}
|
|
401
554
|
editorView.dispatch(transaction);
|
|
402
555
|
}
|
|
403
556
|
}));
|
|
404
|
-
if (editorContentArea
|
|
557
|
+
if (editorContentArea) {
|
|
405
558
|
resizeObserverWidth.observe(editorContentArea);
|
|
406
559
|
}
|
|
407
560
|
|
|
@@ -409,7 +562,7 @@ export const createPlugin = (api, getIntl) => {
|
|
|
409
562
|
const pragmaticCleanup = destroyFn(api);
|
|
410
563
|
return {
|
|
411
564
|
destroy() {
|
|
412
|
-
if (editorContentArea
|
|
565
|
+
if (editorContentArea) {
|
|
413
566
|
resizeObserverWidth.unobserve(editorContentArea);
|
|
414
567
|
}
|
|
415
568
|
pragmaticCleanup();
|
|
@@ -6,7 +6,6 @@ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react
|
|
|
6
6
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
7
7
|
import { css, jsx } from '@emotion/react';
|
|
8
8
|
import { bind } from 'bind-event-listener';
|
|
9
|
-
import { injectIntl } from 'react-intl-next';
|
|
10
9
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
11
10
|
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
12
11
|
import { dragToMoveDown, dragToMoveLeft, dragToMoveRight, dragToMoveUp, getAriaKeyshortcuts, TooltipContentWithMultipleShortcuts } from '@atlaskit/editor-common/keymaps';
|
|
@@ -58,15 +57,13 @@ const selectedStyles = css({
|
|
|
58
57
|
backgroundColor: "var(--ds-background-selected, #E9F2FF)",
|
|
59
58
|
color: "var(--ds-icon-selected, #0C66E4)"
|
|
60
59
|
});
|
|
61
|
-
const
|
|
60
|
+
export const DragHandle = ({
|
|
62
61
|
view,
|
|
63
62
|
api,
|
|
63
|
+
formatMessage,
|
|
64
64
|
getPos,
|
|
65
65
|
anchorName,
|
|
66
66
|
nodeType,
|
|
67
|
-
intl: {
|
|
68
|
-
formatMessage
|
|
69
|
-
},
|
|
70
67
|
handleOptions,
|
|
71
68
|
isTopLevelNode = true
|
|
72
69
|
}) => {
|
|
@@ -360,7 +357,7 @@ const DragHandleInternal = ({
|
|
|
360
357
|
keymap: dragToMoveDown
|
|
361
358
|
}];
|
|
362
359
|
let isParentNodeOfTypeLayout;
|
|
363
|
-
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
360
|
+
if (!isTopLevelNode && handleOptions !== null && handleOptions !== void 0 && handleOptions.isFocused && editorExperiment('nested-dnd', true) && fg('platform_editor_element_dnd_nested_a11y')) {
|
|
364
361
|
isParentNodeOfTypeLayout = nodeType === 'layoutSection' || view.state.doc.resolve(getNestedNodePosition(view.state)).node().type.name === 'layoutColumn';
|
|
365
362
|
if (isParentNodeOfTypeLayout) {
|
|
366
363
|
helpDescriptors = [...helpDescriptors, {
|
|
@@ -404,5 +401,4 @@ const DragHandleInternal = ({
|
|
|
404
401
|
});
|
|
405
402
|
}
|
|
406
403
|
}, renderButton()) : renderButton();
|
|
407
|
-
};
|
|
408
|
-
export const DragHandle = injectIntl(DragHandleInternal);
|
|
404
|
+
};
|