@atlaskit/editor-plugin-block-controls 12.1.1 → 12.2.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 +21 -0
- package/dist/cjs/editor-commands/move-node.js +2 -1
- package/dist/cjs/pm-plugins/decorations-drag-handle.js +19 -1
- package/dist/cjs/pm-plugins/decorations-drop-target.js +2 -1
- package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +19 -1
- package/dist/cjs/pm-plugins/main.js +77 -19
- package/dist/cjs/ui/consts.js +3 -1
- package/dist/cjs/ui/drag-handle.js +9 -0
- package/dist/cjs/ui/global-styles.js +13 -1
- package/dist/cjs/ui/quick-insert-button.js +8 -0
- package/dist/es2019/editor-commands/move-node.js +2 -1
- package/dist/es2019/pm-plugins/decorations-drag-handle.js +14 -0
- package/dist/es2019/pm-plugins/decorations-drop-target.js +2 -1
- package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +13 -0
- package/dist/es2019/pm-plugins/main.js +79 -21
- package/dist/es2019/ui/consts.js +2 -0
- package/dist/es2019/ui/drag-handle.js +10 -1
- package/dist/es2019/ui/global-styles.js +17 -2
- package/dist/es2019/ui/quick-insert-button.js +9 -1
- package/dist/esm/editor-commands/move-node.js +2 -1
- package/dist/esm/pm-plugins/decorations-drag-handle.js +18 -0
- package/dist/esm/pm-plugins/decorations-drop-target.js +2 -1
- package/dist/esm/pm-plugins/decorations-quick-insert-button.js +18 -0
- package/dist/esm/pm-plugins/main.js +79 -21
- package/dist/esm/ui/consts.js +2 -0
- package/dist/esm/ui/drag-handle.js +10 -1
- package/dist/esm/ui/global-styles.js +14 -2
- package/dist/esm/ui/quick-insert-button.js +9 -1
- package/dist/types/pm-plugins/decorations-drag-handle.d.ts +7 -0
- package/dist/types/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
- package/dist/types/ui/consts.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/decorations-drag-handle.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/decorations-quick-insert-button.d.ts +7 -0
- package/dist/types-ts4.5/ui/consts.d.ts +2 -0
- package/package.json +2 -2
|
@@ -19,10 +19,10 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
|
19
19
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
20
20
|
import { getAnchorAttrName } from '../ui/utils/dom-attr-name';
|
|
21
21
|
import { findNodeDecs, nodeDecorations } from './decorations-anchor';
|
|
22
|
-
import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
|
|
22
|
+
import { createActiveDragHandleNodeDecoration, dragHandleDecoration, emptyParagraphNodeDecorations, findActiveDragHandleNodeDec, findHandleDec } from './decorations-drag-handle';
|
|
23
23
|
import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
|
|
24
24
|
import { getActiveDropTargetDecorations } from './decorations-drop-target-active';
|
|
25
|
-
import { findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
|
|
25
|
+
import { createActiveQuickInsertNodeDecoration, findActiveQuickInsertNodeDec, findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
|
|
26
26
|
import { handleMouseDown } from './handle-mouse-down';
|
|
27
27
|
import { handleMouseOver } from './handle-mouse-over';
|
|
28
28
|
import { boundKeydownHandler } from './keymap';
|
|
@@ -435,34 +435,45 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
if (shouldRemoveHandle) {
|
|
438
|
-
var _activeNode5, _activeNode6;
|
|
438
|
+
var _activeNode5, _activeNode6, _activeNode7;
|
|
439
439
|
const oldHandle = findHandleDec(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
|
|
440
440
|
decorations = decorations.remove(oldHandle);
|
|
441
|
+
// When removing the handle, also remove the anchor-marker node decorations
|
|
442
|
+
// (data-active-drag-handle / data-active-quick-insert) so the DOM attributes
|
|
443
|
+
// don't linger on nodes that are no longer active.
|
|
444
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && ((_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.pos) !== undefined) {
|
|
445
|
+
const oldActiveNodeDec = findActiveDragHandleNodeDec(decorations, activeNode.pos, activeNode.pos);
|
|
446
|
+
decorations = decorations.remove(oldActiveNodeDec);
|
|
447
|
+
if (activeNode.rootPos !== undefined) {
|
|
448
|
+
const oldActiveQuickInsertDec = findActiveQuickInsertNodeDec(decorations, activeNode.rootPos, activeNode.rootPos);
|
|
449
|
+
decorations = decorations.remove(oldActiveQuickInsertDec);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
441
452
|
// platform_editor_controls note: enables quick insert
|
|
442
453
|
if (flags.toolbarFlagsEnabled && quickInsertButtonEnabled) {
|
|
443
|
-
var
|
|
444
|
-
const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (
|
|
454
|
+
var _activeNode8, _activeNode9;
|
|
455
|
+
const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.rootPos, (_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos);
|
|
445
456
|
decorations = decorations.remove(oldQuickInsertButton);
|
|
446
457
|
for (const factory of nodeDecorationRegistry) {
|
|
447
|
-
var
|
|
448
|
-
const old = decorations.find((
|
|
458
|
+
var _activeNode0, _activeNode1;
|
|
459
|
+
const old = decorations.find((_activeNode0 = activeNode) === null || _activeNode0 === void 0 ? void 0 : _activeNode0.rootPos, (_activeNode1 = activeNode) === null || _activeNode1 === void 0 ? void 0 : _activeNode1.rootPos, spec => spec.type === factory.type);
|
|
449
460
|
decorations = decorations.remove(old);
|
|
450
461
|
}
|
|
451
462
|
if (rightSideControlsEnabled && isViewMode && fg('confluence_remix_button_right_side_block_fg')) {
|
|
452
463
|
for (const factory of nodeDecorationRegistry) {
|
|
453
464
|
if (factory.showInViewMode) {
|
|
454
|
-
var
|
|
455
|
-
const old = decorations.find((
|
|
465
|
+
var _activeNode10, _activeNode11;
|
|
466
|
+
const old = decorations.find((_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.rootPos, spec => spec.type === factory.type);
|
|
456
467
|
decorations = decorations.remove(old);
|
|
457
468
|
}
|
|
458
469
|
}
|
|
459
470
|
}
|
|
460
471
|
}
|
|
461
472
|
} else if (api) {
|
|
462
|
-
var _latestActiveNode5,
|
|
473
|
+
var _latestActiveNode5, _latestActiveNode10;
|
|
463
474
|
if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
|
|
464
|
-
var
|
|
465
|
-
const oldHandle = findHandleDec(decorations, (
|
|
475
|
+
var _activeNode12, _activeNode13, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
|
|
476
|
+
const oldHandle = findHandleDec(decorations, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos, (_activeNode13 = activeNode) === null || _activeNode13 === void 0 ? void 0 : _activeNode13.pos);
|
|
466
477
|
decorations = decorations.remove(oldHandle);
|
|
467
478
|
const handleDec = dragHandleDecoration({
|
|
468
479
|
api,
|
|
@@ -476,12 +487,44 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
476
487
|
editorState: newState
|
|
477
488
|
});
|
|
478
489
|
decorations = decorations.add(newState.doc, [handleDec]);
|
|
490
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
|
|
491
|
+
// Recreate the drag handle node decoration when the edit-mode node itself changed
|
|
492
|
+
// or its content was modified. Other triggers (editorSizeChanged, handleNeedsRedraw)
|
|
493
|
+
// don't move the decoration — DecorationSet.map() already remaps it correctly.
|
|
494
|
+
const needsNodeDecUpdate = activeNodeChanged || isActiveNodeModified;
|
|
495
|
+
if (needsNodeDecUpdate) {
|
|
496
|
+
var _newState$doc$nodeAt;
|
|
497
|
+
const nodeSize = (_newState$doc$nodeAt = newState.doc.nodeAt(latestActiveNode.pos)) === null || _newState$doc$nodeAt === void 0 ? void 0 : _newState$doc$nodeAt.nodeSize;
|
|
498
|
+
if (nodeSize !== undefined) {
|
|
499
|
+
var _activeNode14, _activeNode15;
|
|
500
|
+
const oldActiveNodeDec = findActiveDragHandleNodeDec(decorations, (_activeNode14 = activeNode) === null || _activeNode14 === void 0 ? void 0 : _activeNode14.pos, (_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.pos);
|
|
501
|
+
decorations = decorations.remove(oldActiveNodeDec);
|
|
502
|
+
decorations = decorations.add(newState.doc, [createActiveDragHandleNodeDecoration(latestActiveNode.pos, nodeSize)]);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// The quick-insert decoration lives on the root node (rootPos), which can change
|
|
507
|
+
// independently of the edit-mode node — e.g. when only editorSizeChanged fires but
|
|
508
|
+
// rootActiveNodeChanged is also true. So we use a separate, broader guard that
|
|
509
|
+
// includes rootActiveNodeChanged to avoid leaving the attribute on a stale root node.
|
|
510
|
+
const needsQuickInsertDecUpdate = activeNodeChanged || isActiveNodeModified || rootActiveNodeChanged;
|
|
511
|
+
if (needsQuickInsertDecUpdate && latestActiveNode.rootPos !== undefined) {
|
|
512
|
+
var _newState$doc$nodeAt2;
|
|
513
|
+
const rootNodeSize = (_newState$doc$nodeAt2 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt2 === void 0 ? void 0 : _newState$doc$nodeAt2.nodeSize;
|
|
514
|
+
if (rootNodeSize !== undefined) {
|
|
515
|
+
var _activeNode16, _activeNode17;
|
|
516
|
+
const oldActiveQuickInsertDec = findActiveQuickInsertNodeDec(decorations, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, (_activeNode17 = activeNode) === null || _activeNode17 === void 0 ? void 0 : _activeNode17.rootPos);
|
|
517
|
+
decorations = decorations.remove(oldActiveQuickInsertDec);
|
|
518
|
+
decorations = decorations.add(newState.doc, [createActiveQuickInsertNodeDecoration(latestActiveNode.rootPos, rootNodeSize)]);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
479
522
|
}
|
|
480
523
|
if (shouldRecreateQuickInsertButton && ((_latestActiveNode5 = latestActiveNode) === null || _latestActiveNode5 === void 0 ? void 0 : _latestActiveNode5.rootPos) !== undefined &&
|
|
481
524
|
// platform_editor_controls note: enables quick insert
|
|
482
525
|
flags.toolbarFlagsEnabled && quickInsertButtonEnabled && (!rightSideControlsEnabled || !isViewMode)) {
|
|
483
|
-
var
|
|
484
|
-
const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (
|
|
526
|
+
var _activeNode18, _activeNode19, _latestActiveNode6, _latestActiveNode7, _latestActiveNode8, _latestActiveNode9, _latestActiveNode0, _latestActiveNode1;
|
|
527
|
+
const oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode18 = activeNode) === null || _activeNode18 === void 0 ? void 0 : _activeNode18.rootPos, (_activeNode19 = activeNode) === null || _activeNode19 === void 0 ? void 0 : _activeNode19.rootPos);
|
|
485
528
|
decorations = decorations.remove(oldQuickInsertButton);
|
|
486
529
|
const quickInsertButton = quickInsertButtonDecoration({
|
|
487
530
|
api,
|
|
@@ -496,9 +539,24 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
496
539
|
editorState: newState
|
|
497
540
|
});
|
|
498
541
|
decorations = decorations.add(newState.doc, [quickInsertButton]);
|
|
542
|
+
|
|
543
|
+
// Update quick insert node decoration when the quick insert button is recreated but
|
|
544
|
+
// the drag handle was NOT recreated (shouldRecreateHandle was false). When
|
|
545
|
+
// shouldRecreateHandle is true, the block above already handles this.
|
|
546
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !shouldRecreateHandle && ((_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos) !== undefined) {
|
|
547
|
+
var _activeNode20, _newState$doc$nodeAt3;
|
|
548
|
+
if (((_activeNode20 = activeNode) === null || _activeNode20 === void 0 ? void 0 : _activeNode20.rootPos) !== undefined) {
|
|
549
|
+
const oldActiveQuickInsertDec = findActiveQuickInsertNodeDec(decorations, activeNode.rootPos, activeNode.rootPos);
|
|
550
|
+
decorations = decorations.remove(oldActiveQuickInsertDec);
|
|
551
|
+
}
|
|
552
|
+
const rootNodeSize = (_newState$doc$nodeAt3 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt3 === void 0 ? void 0 : _newState$doc$nodeAt3.nodeSize;
|
|
553
|
+
if (rootNodeSize !== undefined) {
|
|
554
|
+
decorations = decorations.add(newState.doc, [createActiveQuickInsertNodeDecoration(latestActiveNode.rootPos, rootNodeSize)]);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
499
557
|
if (rightSideControlsEnabled) {
|
|
500
558
|
for (const factory of nodeDecorationRegistry) {
|
|
501
|
-
var
|
|
559
|
+
var _activeNode21, _activeNode22;
|
|
502
560
|
if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
|
|
503
561
|
continue;
|
|
504
562
|
}
|
|
@@ -511,7 +569,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
511
569
|
rootAnchorName: latestActiveNode.rootAnchorName,
|
|
512
570
|
rootNodeType: latestActiveNode.rootNodeType
|
|
513
571
|
};
|
|
514
|
-
const old = decorations.find((
|
|
572
|
+
const old = decorations.find((_activeNode21 = activeNode) === null || _activeNode21 === void 0 ? void 0 : _activeNode21.rootPos, (_activeNode22 = activeNode) === null || _activeNode22 === void 0 ? void 0 : _activeNode22.rootPos, spec => spec.type === factory.type);
|
|
515
573
|
decorations = decorations.remove(old);
|
|
516
574
|
|
|
517
575
|
// determines whether to show the decorations, see malleableUiPlugin.tsx
|
|
@@ -530,7 +588,7 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
530
588
|
}
|
|
531
589
|
|
|
532
590
|
// In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
|
|
533
|
-
const rootPos = (
|
|
591
|
+
const rootPos = (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.rootPos;
|
|
534
592
|
// rootPos is computed using the same logic as the floating insert menu, so it always points to a top-level (doc child) block when defined.
|
|
535
593
|
const isDocLevel = rootPos !== undefined && !isNaN(rootPos);
|
|
536
594
|
if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
|
|
@@ -620,15 +678,15 @@ export const apply = (api, formatMessage, tr, currentState, newState, flags, nod
|
|
|
620
678
|
let newActiveNode;
|
|
621
679
|
// platform_editor_controls note: enables quick insert
|
|
622
680
|
if (flags.toolbarFlagsEnabled) {
|
|
623
|
-
var
|
|
681
|
+
var _latestActiveNode11, _latestActiveNode12;
|
|
624
682
|
// remove isEmptyDoc check and let decorations render and determine their own visibility
|
|
625
683
|
// In view mode with right-side controls we render node decorations (right-edge button), not the
|
|
626
684
|
// handle - so findHandleDec is always empty. Don't clear activeNode in that case.
|
|
627
|
-
const hasHandleOrViewModeControls = findHandleDec(decorations, (
|
|
685
|
+
const hasHandleOrViewModeControls = findHandleDec(decorations, (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.pos, (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.pos).length > 0 || isViewMode && rightSideControlsEnabled;
|
|
628
686
|
newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
|
|
629
687
|
} else {
|
|
630
|
-
var
|
|
631
|
-
newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (
|
|
688
|
+
var _latestActiveNode13, _latestActiveNode14;
|
|
689
|
+
newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.pos, (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.pos).length === 0 ? null : latestActiveNode;
|
|
632
690
|
}
|
|
633
691
|
let isMenuOpenNew = isMenuOpen;
|
|
634
692
|
if (editorExperiment('platform_editor_block_menu', true)) {
|
package/dist/es2019/ui/consts.js
CHANGED
|
@@ -3,6 +3,8 @@ import { breakoutResizableNodes as breakoutResizableNodesNew } from '@atlaskit/e
|
|
|
3
3
|
import { akEditorUnitZIndex, akRichMediaResizeZIndex } from '@atlaskit/editor-shared-styles';
|
|
4
4
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
5
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
6
|
+
export const ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
|
|
7
|
+
export const ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
|
|
6
8
|
export const DRAG_HANDLE_HEIGHT = 24;
|
|
7
9
|
export const DRAG_HANDLE_BORDER_RADIUS = 4;
|
|
8
10
|
export const DRAG_HANDLE_ZINDEX = akRichMediaResizeZIndex + akEditorUnitZIndex; //place above legacy resizer
|
|
@@ -35,7 +35,7 @@ import { getControlBottomCSSValue, getControlHeightCSSValue, getLeftPosition, ge
|
|
|
35
35
|
import { expandAndUpdateSelection } from '../pm-plugins/utils/expand-and-update-selection';
|
|
36
36
|
import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
|
|
37
37
|
import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
|
|
38
|
-
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
38
|
+
import { ACTIVE_DRAG_HANDLE_ATTR, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
39
39
|
import { DragHandleNestedIcon } from './drag-handle-nested-icon';
|
|
40
40
|
import { dragPreview } from './drag-preview';
|
|
41
41
|
import { refreshAnchorName } from './utils/anchor-name';
|
|
@@ -807,6 +807,15 @@ export const DragHandle = ({
|
|
|
807
807
|
anchorName
|
|
808
808
|
}) : anchorName;
|
|
809
809
|
const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${safeAnchorName}"]`);
|
|
810
|
+
|
|
811
|
+
// Defence-in-depth guard: since the node decoration sets data-active-drag-handle on the
|
|
812
|
+
// active node, we check for it directly. This is a cheap DOM attribute read (no reflow,
|
|
813
|
+
// no style recalculation) and hides the control if the decoration hasn't been applied yet.
|
|
814
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !(dom !== null && dom !== void 0 && dom.hasAttribute(ACTIVE_DRAG_HANDLE_ATTR))) {
|
|
815
|
+
return {
|
|
816
|
+
display: 'none'
|
|
817
|
+
};
|
|
818
|
+
}
|
|
810
819
|
const hasResizer = nodeType === 'table' || nodeType === 'mediaSingle';
|
|
811
820
|
const isExtension = nodeType === 'extension' || nodeType === 'bodiedExtension' || nodeType === 'multiBodiedExtension' && fg('confluence_frontend_native_tabs_extension');
|
|
812
821
|
const isBlockCard = nodeType === 'blockCard' && !!blockCardWidth;
|
|
@@ -11,7 +11,7 @@ import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
|
11
11
|
import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
|
|
12
12
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
13
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
14
|
-
import { DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
|
|
14
|
+
import { ACTIVE_DRAG_HANDLE_ATTR, ACTIVE_QUICK_INSERT_ATTR, DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
|
|
15
15
|
import { NODE_ANCHOR_ATTR_NAME } from './utils/dom-attr-name';
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -449,6 +449,21 @@ const dragHandlerAnchorStyles = css({
|
|
|
449
449
|
}
|
|
450
450
|
}
|
|
451
451
|
});
|
|
452
|
+
const activeControlsSelector = `[${ACTIVE_DRAG_HANDLE_ATTR}], [${ACTIVE_QUICK_INSERT_ATTR}]`;
|
|
453
|
+
|
|
454
|
+
// Applies anchor-name via node decoration attributes rather than adjacency CSS selectors.
|
|
455
|
+
// This is more reliable than dragHandlerAnchorStyles which depends on DOM structure.
|
|
456
|
+
// Only nodes decorated with data-active-drag-handle / data-active-quick-insert get anchor-name.
|
|
457
|
+
const staticControlsAnchorStyles = css({
|
|
458
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
|
|
459
|
+
'.ProseMirror': {
|
|
460
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
|
|
461
|
+
[activeControlsSelector]: {
|
|
462
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
|
|
463
|
+
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
});
|
|
452
467
|
|
|
453
468
|
// Styles applied to nodes with anchors when dragging
|
|
454
469
|
const dragAnchorStyles = css({
|
|
@@ -499,6 +514,6 @@ export const GlobalStylesWrapper = ({
|
|
|
499
514
|
exposure: true
|
|
500
515
|
}) ? expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
|
|
501
516
|
// platform_editor_controls note: this allows drag handles to render on empty lines
|
|
502
|
-
toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles)]
|
|
517
|
+
toolbarFlagsEnabled ? undefined : withInlineNodeStyle, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles), expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) ? staticControlsAnchorStyles : undefined]
|
|
503
518
|
});
|
|
504
519
|
};
|
|
@@ -24,7 +24,7 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
24
24
|
import { getNodeTypeWithLevel } from '../pm-plugins/decorations-common';
|
|
25
25
|
import { getControlBottomCSSValue, getControlHeightCSSValue, getNodeHeight, getTopPosition, shouldBeSticky } from '../pm-plugins/utils/drag-handle-positions';
|
|
26
26
|
import { getLeftPositionForRootElement } from '../pm-plugins/utils/widget-positions';
|
|
27
|
-
import { QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
27
|
+
import { ACTIVE_QUICK_INSERT_ATTR, QUICK_INSERT_DIMENSIONS, QUICK_INSERT_HEIGHT, QUICK_INSERT_LEFT_OFFSET, QUICK_INSERT_WIDTH, rootElementGap, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
28
28
|
import { refreshAnchorName } from './utils/anchor-name';
|
|
29
29
|
import { isInTextSelection, isNestedNodeSelected, isNonEditableBlock, isSelectionInNode } from './utils/document-checks';
|
|
30
30
|
import { getAnchorAttrName } from './utils/dom-attr-name';
|
|
@@ -179,6 +179,14 @@ export const TypeAheadControl = ({
|
|
|
179
179
|
anchorName: rootAnchorName
|
|
180
180
|
});
|
|
181
181
|
const dom = view.dom.querySelector(`[${getAnchorAttrName()}="${safeAnchorName}"]`);
|
|
182
|
+
|
|
183
|
+
// Defence-in-depth guard: the node decoration sets data-active-quick-insert on the
|
|
184
|
+
// active root node. Check for it directly — cheap DOM attribute read, no reflow.
|
|
185
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !(dom !== null && dom !== void 0 && dom.hasAttribute(ACTIVE_QUICK_INSERT_ATTR))) {
|
|
186
|
+
return {
|
|
187
|
+
display: 'none'
|
|
188
|
+
};
|
|
189
|
+
}
|
|
182
190
|
const hasResizer = rootNodeType === 'table' || rootNodeType === 'mediaSingle';
|
|
183
191
|
const isExtension = rootNodeType === 'extension' || rootNodeType === 'bodiedExtension' || rootNodeType === 'multiBodiedExtension' && fg('confluence_frontend_native_tabs_extension');
|
|
184
192
|
const isBlockCard = rootNodeType === 'blockCard';
|
|
@@ -7,7 +7,8 @@ import { blockControlsMessages } from '@atlaskit/editor-common/messages';
|
|
|
7
7
|
import { expandSelectionBounds, GapCursorSelection } from '@atlaskit/editor-common/selection';
|
|
8
8
|
import { transformSliceNestedExpandToExpand } from '@atlaskit/editor-common/transforms';
|
|
9
9
|
import { DIRECTION } from '@atlaskit/editor-common/types';
|
|
10
|
-
import {
|
|
10
|
+
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
11
|
+
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
11
12
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
12
13
|
import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
13
14
|
import { Mapping, StepMap } from '@atlaskit/editor-prosemirror/transform';
|
|
@@ -8,9 +8,27 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
8
8
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
9
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
10
10
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
11
|
+
import { ACTIVE_DRAG_HANDLE_ATTR } from '../ui/consts';
|
|
11
12
|
import { DragHandle, DragHandleWithVisibility } from '../ui/drag-handle';
|
|
12
13
|
import { TYPE_HANDLE_DEC, TYPE_NODE_DEC, unmountDecorations } from './decorations-common';
|
|
13
14
|
import { getActiveBlockMarks, getMatchingBlockMarks } from './utils/marks';
|
|
15
|
+
var TYPE_ACTIVE_HANDLE_DEC = 'active-drag-handle-node';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Creates a Decoration.node that marks the active node with `data-active-drag-handle="true"`.
|
|
19
|
+
* The CSS in staticControlsAnchorStyles then applies `anchor-name` to this attribute,
|
|
20
|
+
* which is more reliable than the adjacency-selector approach in dragHandlerAnchorStyles.
|
|
21
|
+
*/
|
|
22
|
+
export var createActiveDragHandleNodeDecoration = function createActiveDragHandleNodeDecoration(pos, nodeSize) {
|
|
23
|
+
return Decoration.node(pos, pos + nodeSize, _defineProperty({}, ACTIVE_DRAG_HANDLE_ATTR, 'true'), {
|
|
24
|
+
type: TYPE_ACTIVE_HANDLE_DEC
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
export var findActiveDragHandleNodeDec = function findActiveDragHandleNodeDec(decorations, from, to) {
|
|
28
|
+
return decorations.find(from, to, function (spec) {
|
|
29
|
+
return spec.type === TYPE_ACTIVE_HANDLE_DEC;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
14
32
|
export var emptyParagraphNodeDecorations = function emptyParagraphNodeDecorations() {
|
|
15
33
|
var anchorName = "--node-anchor-paragraph-0";
|
|
16
34
|
var style = "anchor-name: ".concat(anchorName, "; margin-top: 0px;");
|
|
@@ -7,7 +7,8 @@ import memoizeOne from 'memoize-one';
|
|
|
7
7
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
8
8
|
import uuid from 'uuid';
|
|
9
9
|
import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
|
|
10
|
-
import {
|
|
10
|
+
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
11
|
+
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
11
12
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
12
13
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
13
14
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
1
2
|
import { createElement } from 'react';
|
|
2
3
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
3
4
|
import uuid from 'uuid';
|
|
@@ -5,14 +6,31 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
5
6
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
8
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
9
|
+
import { ACTIVE_QUICK_INSERT_ATTR } from '../ui/consts';
|
|
8
10
|
import { QuickInsertWithVisibility } from '../ui/quick-insert-button';
|
|
9
11
|
import { getActiveBlockMarks, getMatchingBlockMarks } from './utils/marks';
|
|
10
12
|
var TYPE_QUICK_INSERT = 'INSERT_BUTTON';
|
|
13
|
+
var TYPE_ACTIVE_QUICK_INSERT_NODE = 'active-quick-insert-node';
|
|
11
14
|
export var findQuickInsertInsertButtonDecoration = function findQuickInsertInsertButtonDecoration(decorations, from, to) {
|
|
12
15
|
return decorations.find(from, to, function (spec) {
|
|
13
16
|
return spec.type === TYPE_QUICK_INSERT;
|
|
14
17
|
});
|
|
15
18
|
};
|
|
19
|
+
/**
|
|
20
|
+
* Creates a Decoration.node that marks the active node with `data-active-quick-insert="true"`.
|
|
21
|
+
* The CSS in staticControlsAnchorStyles applies `anchor-name` to this attribute directly,
|
|
22
|
+
* replacing the unreliable adjacency selector `[block-ctrl-quick-insert-button] + *`.
|
|
23
|
+
*/
|
|
24
|
+
export var createActiveQuickInsertNodeDecoration = function createActiveQuickInsertNodeDecoration(pos, nodeSize) {
|
|
25
|
+
return Decoration.node(pos, pos + nodeSize, _defineProperty({}, ACTIVE_QUICK_INSERT_ATTR, 'true'), {
|
|
26
|
+
type: TYPE_ACTIVE_QUICK_INSERT_NODE
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
export var findActiveQuickInsertNodeDec = function findActiveQuickInsertNodeDec(decorations, from, to) {
|
|
30
|
+
return decorations.find(from, to, function (spec) {
|
|
31
|
+
return spec.type === TYPE_ACTIVE_QUICK_INSERT_NODE;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
16
34
|
export var quickInsertButtonDecoration = function quickInsertButtonDecoration(_ref) {
|
|
17
35
|
var api = _ref.api,
|
|
18
36
|
formatMessage = _ref.formatMessage,
|
|
@@ -25,10 +25,10 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
|
25
25
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
26
26
|
import { getAnchorAttrName } from '../ui/utils/dom-attr-name';
|
|
27
27
|
import { findNodeDecs, nodeDecorations } from './decorations-anchor';
|
|
28
|
-
import { dragHandleDecoration, emptyParagraphNodeDecorations, findHandleDec } from './decorations-drag-handle';
|
|
28
|
+
import { createActiveDragHandleNodeDecoration, dragHandleDecoration, emptyParagraphNodeDecorations, findActiveDragHandleNodeDec, findHandleDec } from './decorations-drag-handle';
|
|
29
29
|
import { dropTargetDecorations, findDropTargetDecs } from './decorations-drop-target';
|
|
30
30
|
import { getActiveDropTargetDecorations } from './decorations-drop-target-active';
|
|
31
|
-
import { findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
|
|
31
|
+
import { createActiveQuickInsertNodeDecoration, findActiveQuickInsertNodeDec, findQuickInsertInsertButtonDecoration, quickInsertButtonDecoration } from './decorations-quick-insert-button';
|
|
32
32
|
import { handleMouseDown } from './handle-mouse-down';
|
|
33
33
|
import { handleMouseOver } from './handle-mouse-over';
|
|
34
34
|
import { boundKeydownHandler } from './keymap';
|
|
@@ -438,21 +438,32 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
if (shouldRemoveHandle) {
|
|
441
|
-
var _activeNode5, _activeNode6;
|
|
441
|
+
var _activeNode5, _activeNode6, _activeNode7;
|
|
442
442
|
var oldHandle = findHandleDec(decorations, (_activeNode5 = activeNode) === null || _activeNode5 === void 0 ? void 0 : _activeNode5.pos, (_activeNode6 = activeNode) === null || _activeNode6 === void 0 ? void 0 : _activeNode6.pos);
|
|
443
443
|
decorations = decorations.remove(oldHandle);
|
|
444
|
+
// When removing the handle, also remove the anchor-marker node decorations
|
|
445
|
+
// (data-active-drag-handle / data-active-quick-insert) so the DOM attributes
|
|
446
|
+
// don't linger on nodes that are no longer active.
|
|
447
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && ((_activeNode7 = activeNode) === null || _activeNode7 === void 0 ? void 0 : _activeNode7.pos) !== undefined) {
|
|
448
|
+
var oldActiveNodeDec = findActiveDragHandleNodeDec(decorations, activeNode.pos, activeNode.pos);
|
|
449
|
+
decorations = decorations.remove(oldActiveNodeDec);
|
|
450
|
+
if (activeNode.rootPos !== undefined) {
|
|
451
|
+
var oldActiveQuickInsertDec = findActiveQuickInsertNodeDec(decorations, activeNode.rootPos, activeNode.rootPos);
|
|
452
|
+
decorations = decorations.remove(oldActiveQuickInsertDec);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
444
455
|
// platform_editor_controls note: enables quick insert
|
|
445
456
|
if (flags.toolbarFlagsEnabled && quickInsertButtonEnabled) {
|
|
446
|
-
var
|
|
447
|
-
var oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (
|
|
457
|
+
var _activeNode8, _activeNode9;
|
|
458
|
+
var oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode8 = activeNode) === null || _activeNode8 === void 0 ? void 0 : _activeNode8.rootPos, (_activeNode9 = activeNode) === null || _activeNode9 === void 0 ? void 0 : _activeNode9.rootPos);
|
|
448
459
|
decorations = decorations.remove(oldQuickInsertButton);
|
|
449
460
|
var _iterator = _createForOfIteratorHelper(nodeDecorationRegistry),
|
|
450
461
|
_step;
|
|
451
462
|
try {
|
|
452
463
|
var _loop2 = function _loop2() {
|
|
453
|
-
var
|
|
464
|
+
var _activeNode10, _activeNode11;
|
|
454
465
|
var factory = _step.value;
|
|
455
|
-
var old = decorations.find((
|
|
466
|
+
var old = decorations.find((_activeNode10 = activeNode) === null || _activeNode10 === void 0 ? void 0 : _activeNode10.rootPos, (_activeNode11 = activeNode) === null || _activeNode11 === void 0 ? void 0 : _activeNode11.rootPos, function (spec) {
|
|
456
467
|
return spec.type === factory.type;
|
|
457
468
|
});
|
|
458
469
|
decorations = decorations.remove(old);
|
|
@@ -472,8 +483,8 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
472
483
|
var _loop = function _loop() {
|
|
473
484
|
var factory = _step2.value;
|
|
474
485
|
if (factory.showInViewMode) {
|
|
475
|
-
var
|
|
476
|
-
var old = decorations.find((
|
|
486
|
+
var _activeNode0, _activeNode1;
|
|
487
|
+
var old = decorations.find((_activeNode0 = activeNode) === null || _activeNode0 === void 0 ? void 0 : _activeNode0.rootPos, (_activeNode1 = activeNode) === null || _activeNode1 === void 0 ? void 0 : _activeNode1.rootPos, function (spec) {
|
|
477
488
|
return spec.type === factory.type;
|
|
478
489
|
});
|
|
479
490
|
decorations = decorations.remove(old);
|
|
@@ -490,10 +501,10 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
490
501
|
}
|
|
491
502
|
}
|
|
492
503
|
} else if (api) {
|
|
493
|
-
var _latestActiveNode5,
|
|
504
|
+
var _latestActiveNode5, _latestActiveNode10;
|
|
494
505
|
if (shouldRecreateHandle && (!rightSideControlsEnabled || !isViewMode)) {
|
|
495
|
-
var
|
|
496
|
-
var _oldHandle = findHandleDec(decorations, (
|
|
506
|
+
var _activeNode12, _activeNode13, _latestActiveNode, _latestActiveNode2, _latestActiveNode3, _latestActiveNode4;
|
|
507
|
+
var _oldHandle = findHandleDec(decorations, (_activeNode12 = activeNode) === null || _activeNode12 === void 0 ? void 0 : _activeNode12.pos, (_activeNode13 = activeNode) === null || _activeNode13 === void 0 ? void 0 : _activeNode13.pos);
|
|
497
508
|
decorations = decorations.remove(_oldHandle);
|
|
498
509
|
var handleDec = dragHandleDecoration({
|
|
499
510
|
api: api,
|
|
@@ -507,12 +518,44 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
507
518
|
editorState: newState
|
|
508
519
|
});
|
|
509
520
|
decorations = decorations.add(newState.doc, [handleDec]);
|
|
521
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true)) {
|
|
522
|
+
// Recreate the drag handle node decoration when the edit-mode node itself changed
|
|
523
|
+
// or its content was modified. Other triggers (editorSizeChanged, handleNeedsRedraw)
|
|
524
|
+
// don't move the decoration — DecorationSet.map() already remaps it correctly.
|
|
525
|
+
var needsNodeDecUpdate = activeNodeChanged || isActiveNodeModified;
|
|
526
|
+
if (needsNodeDecUpdate) {
|
|
527
|
+
var _newState$doc$nodeAt;
|
|
528
|
+
var nodeSize = (_newState$doc$nodeAt = newState.doc.nodeAt(latestActiveNode.pos)) === null || _newState$doc$nodeAt === void 0 ? void 0 : _newState$doc$nodeAt.nodeSize;
|
|
529
|
+
if (nodeSize !== undefined) {
|
|
530
|
+
var _activeNode14, _activeNode15;
|
|
531
|
+
var _oldActiveNodeDec = findActiveDragHandleNodeDec(decorations, (_activeNode14 = activeNode) === null || _activeNode14 === void 0 ? void 0 : _activeNode14.pos, (_activeNode15 = activeNode) === null || _activeNode15 === void 0 ? void 0 : _activeNode15.pos);
|
|
532
|
+
decorations = decorations.remove(_oldActiveNodeDec);
|
|
533
|
+
decorations = decorations.add(newState.doc, [createActiveDragHandleNodeDecoration(latestActiveNode.pos, nodeSize)]);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// The quick-insert decoration lives on the root node (rootPos), which can change
|
|
538
|
+
// independently of the edit-mode node — e.g. when only editorSizeChanged fires but
|
|
539
|
+
// rootActiveNodeChanged is also true. So we use a separate, broader guard that
|
|
540
|
+
// includes rootActiveNodeChanged to avoid leaving the attribute on a stale root node.
|
|
541
|
+
var needsQuickInsertDecUpdate = activeNodeChanged || isActiveNodeModified || rootActiveNodeChanged;
|
|
542
|
+
if (needsQuickInsertDecUpdate && latestActiveNode.rootPos !== undefined) {
|
|
543
|
+
var _newState$doc$nodeAt2;
|
|
544
|
+
var rootNodeSize = (_newState$doc$nodeAt2 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt2 === void 0 ? void 0 : _newState$doc$nodeAt2.nodeSize;
|
|
545
|
+
if (rootNodeSize !== undefined) {
|
|
546
|
+
var _activeNode16, _activeNode17;
|
|
547
|
+
var _oldActiveQuickInsertDec = findActiveQuickInsertNodeDec(decorations, (_activeNode16 = activeNode) === null || _activeNode16 === void 0 ? void 0 : _activeNode16.rootPos, (_activeNode17 = activeNode) === null || _activeNode17 === void 0 ? void 0 : _activeNode17.rootPos);
|
|
548
|
+
decorations = decorations.remove(_oldActiveQuickInsertDec);
|
|
549
|
+
decorations = decorations.add(newState.doc, [createActiveQuickInsertNodeDecoration(latestActiveNode.rootPos, rootNodeSize)]);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
510
553
|
}
|
|
511
554
|
if (shouldRecreateQuickInsertButton && ((_latestActiveNode5 = latestActiveNode) === null || _latestActiveNode5 === void 0 ? void 0 : _latestActiveNode5.rootPos) !== undefined &&
|
|
512
555
|
// platform_editor_controls note: enables quick insert
|
|
513
556
|
flags.toolbarFlagsEnabled && quickInsertButtonEnabled && (!rightSideControlsEnabled || !isViewMode)) {
|
|
514
|
-
var
|
|
515
|
-
var _oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (
|
|
557
|
+
var _activeNode18, _activeNode19, _latestActiveNode6, _latestActiveNode7, _latestActiveNode8, _latestActiveNode9, _latestActiveNode0, _latestActiveNode1;
|
|
558
|
+
var _oldQuickInsertButton = findQuickInsertInsertButtonDecoration(decorations, (_activeNode18 = activeNode) === null || _activeNode18 === void 0 ? void 0 : _activeNode18.rootPos, (_activeNode19 = activeNode) === null || _activeNode19 === void 0 ? void 0 : _activeNode19.rootPos);
|
|
516
559
|
decorations = decorations.remove(_oldQuickInsertButton);
|
|
517
560
|
var quickInsertButton = quickInsertButtonDecoration({
|
|
518
561
|
api: api,
|
|
@@ -527,12 +570,27 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
527
570
|
editorState: newState
|
|
528
571
|
});
|
|
529
572
|
decorations = decorations.add(newState.doc, [quickInsertButton]);
|
|
573
|
+
|
|
574
|
+
// Update quick insert node decoration when the quick insert button is recreated but
|
|
575
|
+
// the drag handle was NOT recreated (shouldRecreateHandle was false). When
|
|
576
|
+
// shouldRecreateHandle is true, the block above already handles this.
|
|
577
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !shouldRecreateHandle && ((_latestActiveNode1 = latestActiveNode) === null || _latestActiveNode1 === void 0 ? void 0 : _latestActiveNode1.rootPos) !== undefined) {
|
|
578
|
+
var _activeNode20, _newState$doc$nodeAt3;
|
|
579
|
+
if (((_activeNode20 = activeNode) === null || _activeNode20 === void 0 ? void 0 : _activeNode20.rootPos) !== undefined) {
|
|
580
|
+
var _oldActiveQuickInsertDec2 = findActiveQuickInsertNodeDec(decorations, activeNode.rootPos, activeNode.rootPos);
|
|
581
|
+
decorations = decorations.remove(_oldActiveQuickInsertDec2);
|
|
582
|
+
}
|
|
583
|
+
var _rootNodeSize = (_newState$doc$nodeAt3 = newState.doc.nodeAt(latestActiveNode.rootPos)) === null || _newState$doc$nodeAt3 === void 0 ? void 0 : _newState$doc$nodeAt3.nodeSize;
|
|
584
|
+
if (_rootNodeSize !== undefined) {
|
|
585
|
+
decorations = decorations.add(newState.doc, [createActiveQuickInsertNodeDecoration(latestActiveNode.rootPos, _rootNodeSize)]);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
530
588
|
if (rightSideControlsEnabled) {
|
|
531
589
|
var _iterator3 = _createForOfIteratorHelper(nodeDecorationRegistry),
|
|
532
590
|
_step3;
|
|
533
591
|
try {
|
|
534
592
|
var _loop3 = function _loop3() {
|
|
535
|
-
var
|
|
593
|
+
var _activeNode21, _activeNode22;
|
|
536
594
|
var factory = _step3.value;
|
|
537
595
|
if (!latestActiveNode || latestActiveNode.rootPos === undefined) {
|
|
538
596
|
return 0; // continue
|
|
@@ -546,7 +604,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
546
604
|
rootAnchorName: latestActiveNode.rootAnchorName,
|
|
547
605
|
rootNodeType: latestActiveNode.rootNodeType
|
|
548
606
|
};
|
|
549
|
-
var old = decorations.find((
|
|
607
|
+
var old = decorations.find((_activeNode21 = activeNode) === null || _activeNode21 === void 0 ? void 0 : _activeNode21.rootPos, (_activeNode22 = activeNode) === null || _activeNode22 === void 0 ? void 0 : _activeNode22.rootPos, function (spec) {
|
|
550
608
|
return spec.type === factory.type;
|
|
551
609
|
});
|
|
552
610
|
decorations = decorations.remove(old);
|
|
@@ -591,7 +649,7 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
591
649
|
}
|
|
592
650
|
|
|
593
651
|
// In view mode (edit/live pages), show right-side controls on block hover (without drag handle or quick insert)
|
|
594
|
-
var rootPos = (
|
|
652
|
+
var rootPos = (_latestActiveNode10 = latestActiveNode) === null || _latestActiveNode10 === void 0 ? void 0 : _latestActiveNode10.rootPos;
|
|
595
653
|
// rootPos is computed using the same logic as the floating insert menu, so it always points to a top-level (doc child) block when defined.
|
|
596
654
|
var isDocLevel = rootPos !== undefined && !isNaN(rootPos);
|
|
597
655
|
if (isViewMode && isDocLevel && flags.toolbarFlagsEnabled && rightSideControlsEnabled) {
|
|
@@ -712,15 +770,15 @@ var _apply = function apply(api, formatMessage, tr, currentState, newState, flag
|
|
|
712
770
|
var newActiveNode;
|
|
713
771
|
// platform_editor_controls note: enables quick insert
|
|
714
772
|
if (flags.toolbarFlagsEnabled) {
|
|
715
|
-
var
|
|
773
|
+
var _latestActiveNode11, _latestActiveNode12;
|
|
716
774
|
// remove isEmptyDoc check and let decorations render and determine their own visibility
|
|
717
775
|
// In view mode with right-side controls we render node decorations (right-edge button), not the
|
|
718
776
|
// handle - so findHandleDec is always empty. Don't clear activeNode in that case.
|
|
719
|
-
var hasHandleOrViewModeControls = findHandleDec(decorations, (
|
|
777
|
+
var hasHandleOrViewModeControls = findHandleDec(decorations, (_latestActiveNode11 = latestActiveNode) === null || _latestActiveNode11 === void 0 ? void 0 : _latestActiveNode11.pos, (_latestActiveNode12 = latestActiveNode) === null || _latestActiveNode12 === void 0 ? void 0 : _latestActiveNode12.pos).length > 0 || isViewMode && rightSideControlsEnabled;
|
|
720
778
|
newActiveNode = meta !== null && meta !== void 0 && meta.editorBlurred || !(meta !== null && meta !== void 0 && meta.activeNode) && !hasHandleOrViewModeControls ? null : latestActiveNode;
|
|
721
779
|
} else {
|
|
722
|
-
var
|
|
723
|
-
newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (
|
|
780
|
+
var _latestActiveNode13, _latestActiveNode14;
|
|
781
|
+
newActiveNode = isEmptyDoc || !(meta !== null && meta !== void 0 && meta.activeNode) && findHandleDec(decorations, (_latestActiveNode13 = latestActiveNode) === null || _latestActiveNode13 === void 0 ? void 0 : _latestActiveNode13.pos, (_latestActiveNode14 = latestActiveNode) === null || _latestActiveNode14 === void 0 ? void 0 : _latestActiveNode14.pos).length === 0 ? null : latestActiveNode;
|
|
724
782
|
}
|
|
725
783
|
var isMenuOpenNew = isMenuOpen;
|
|
726
784
|
if (editorExperiment('platform_editor_block_menu', true)) {
|
package/dist/esm/ui/consts.js
CHANGED
|
@@ -5,6 +5,8 @@ import { breakoutResizableNodes as breakoutResizableNodesNew } from '@atlaskit/e
|
|
|
5
5
|
import { akEditorUnitZIndex, akRichMediaResizeZIndex } from '@atlaskit/editor-shared-styles';
|
|
6
6
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
7
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
8
|
+
export var ACTIVE_DRAG_HANDLE_ATTR = 'data-active-drag-handle';
|
|
9
|
+
export var ACTIVE_QUICK_INSERT_ATTR = 'data-active-quick-insert';
|
|
8
10
|
export var DRAG_HANDLE_HEIGHT = 24;
|
|
9
11
|
export var DRAG_HANDLE_BORDER_RADIUS = 4;
|
|
10
12
|
export var DRAG_HANDLE_ZINDEX = akRichMediaResizeZIndex + akEditorUnitZIndex; //place above legacy resizer
|
|
@@ -40,7 +40,7 @@ import { getControlBottomCSSValue, getControlHeightCSSValue, getLeftPosition, ge
|
|
|
40
40
|
import { expandAndUpdateSelection } from '../pm-plugins/utils/expand-and-update-selection';
|
|
41
41
|
import { isHandleCorrelatedToSelection, selectNode } from '../pm-plugins/utils/getSelection';
|
|
42
42
|
import { alignAnchorHeadInDirectionOfPos, expandSelectionHeadToNodeAtPos } from '../pm-plugins/utils/selection';
|
|
43
|
-
import { DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
43
|
+
import { ACTIVE_DRAG_HANDLE_ATTR, DRAG_HANDLE_BORDER_RADIUS, DRAG_HANDLE_HEIGHT, DRAG_HANDLE_MAX_SHIFT_CLICK_DEPTH, DRAG_HANDLE_ZINDEX, dragHandleGap, nodeMargins, spacingBetweenNodesForPreview, STICKY_CONTROLS_TOP_MARGIN, STICKY_CONTROLS_TOP_MARGIN_FOR_STICKY_HEADER, topPositionAdjustment } from './consts';
|
|
44
44
|
import { DragHandleNestedIcon } from './drag-handle-nested-icon';
|
|
45
45
|
import { dragPreview } from './drag-preview';
|
|
46
46
|
import { refreshAnchorName } from './utils/anchor-name';
|
|
@@ -823,6 +823,15 @@ export var DragHandle = function DragHandle(_ref) {
|
|
|
823
823
|
anchorName: anchorName
|
|
824
824
|
}) : anchorName;
|
|
825
825
|
var dom = view.dom.querySelector("[".concat(getAnchorAttrName(), "=\"").concat(safeAnchorName, "\"]"));
|
|
826
|
+
|
|
827
|
+
// Defence-in-depth guard: since the node decoration sets data-active-drag-handle on the
|
|
828
|
+
// active node, we check for it directly. This is a cheap DOM attribute read (no reflow,
|
|
829
|
+
// no style recalculation) and hides the control if the decoration hasn't been applied yet.
|
|
830
|
+
if (expValEquals('platform_editor_controls_reliable_anchor', 'isEnabled', true) && !(dom !== null && dom !== void 0 && dom.hasAttribute(ACTIVE_DRAG_HANDLE_ATTR))) {
|
|
831
|
+
return {
|
|
832
|
+
display: 'none'
|
|
833
|
+
};
|
|
834
|
+
}
|
|
826
835
|
var hasResizer = nodeType === 'table' || nodeType === 'mediaSingle';
|
|
827
836
|
var isExtension = nodeType === 'extension' || nodeType === 'bodiedExtension' || nodeType === 'multiBodiedExtension' && fg('confluence_frontend_native_tabs_extension');
|
|
828
837
|
var isBlockCard = nodeType === 'blockCard' && !!blockCardWidth;
|