@atlaskit/editor-plugin-block-controls 2.6.2 → 2.7.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 +26 -0
- package/dist/cjs/commands/move-to-layout.js +76 -0
- package/dist/cjs/consts.js +3 -2
- package/dist/cjs/plugin.js +3 -12
- package/dist/cjs/pm-plugins/decorations.js +15 -11
- package/dist/cjs/pm-plugins/handle-mouse-over.js +2 -12
- package/dist/cjs/pm-plugins/main.js +14 -18
- package/dist/cjs/ui/consts.js +8 -1
- package/dist/cjs/ui/drop-target-v2.js +24 -17
- package/dist/cjs/ui/inline-drop-target.js +138 -0
- package/dist/cjs/utils/advanced-layouts-flags.js +11 -0
- package/dist/cjs/utils/anchor-utils.js +71 -15
- package/dist/cjs/utils/inline-drop-target.js +18 -0
- package/dist/es2019/commands/move-to-layout.js +69 -0
- package/dist/es2019/consts.js +2 -1
- package/dist/es2019/plugin.js +2 -10
- package/dist/es2019/pm-plugins/decorations.js +15 -11
- package/dist/es2019/pm-plugins/handle-mouse-over.js +2 -12
- package/dist/es2019/pm-plugins/main.js +15 -21
- package/dist/es2019/ui/consts.js +7 -0
- package/dist/es2019/ui/drop-target-v2.js +24 -16
- package/dist/es2019/ui/inline-drop-target.js +130 -0
- package/dist/es2019/utils/advanced-layouts-flags.js +5 -0
- package/dist/es2019/utils/anchor-utils.js +55 -9
- package/dist/es2019/utils/inline-drop-target.js +12 -0
- package/dist/esm/commands/move-to-layout.js +70 -0
- package/dist/esm/consts.js +2 -1
- package/dist/esm/plugin.js +3 -12
- package/dist/esm/pm-plugins/decorations.js +15 -11
- package/dist/esm/pm-plugins/handle-mouse-over.js +2 -12
- package/dist/esm/pm-plugins/main.js +15 -19
- package/dist/esm/ui/consts.js +7 -0
- package/dist/esm/ui/drop-target-v2.js +24 -17
- package/dist/esm/ui/inline-drop-target.js +130 -0
- package/dist/esm/utils/advanced-layouts-flags.js +5 -0
- package/dist/esm/utils/anchor-utils.js +70 -14
- package/dist/esm/utils/inline-drop-target.js +12 -0
- package/dist/types/commands/move-to-layout.d.ts +3 -0
- package/dist/types/consts.d.ts +1 -0
- package/dist/types/pm-plugins/decorations.d.ts +3 -3
- package/dist/types/pm-plugins/main.d.ts +3 -4
- package/dist/types/types.d.ts +1 -1
- package/dist/types/ui/consts.d.ts +3 -0
- package/dist/types/ui/drop-target-v2.d.ts +3 -3
- package/dist/types/ui/inline-drop-target.d.ts +20 -0
- package/dist/types/utils/advanced-layouts-flags.d.ts +1 -0
- package/dist/types/utils/anchor-utils.d.ts +16 -3
- package/dist/types/utils/inline-drop-target.d.ts +2 -0
- package/dist/types-ts4.5/commands/move-to-layout.d.ts +3 -0
- package/dist/types-ts4.5/consts.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/decorations.d.ts +3 -3
- package/dist/types-ts4.5/pm-plugins/main.d.ts +3 -4
- package/dist/types-ts4.5/types.d.ts +1 -1
- package/dist/types-ts4.5/ui/consts.d.ts +3 -0
- package/dist/types-ts4.5/ui/drop-target-v2.d.ts +3 -3
- package/dist/types-ts4.5/ui/inline-drop-target.d.ts +20 -0
- package/dist/types-ts4.5/utils/advanced-layouts-flags.d.ts +1 -0
- package/dist/types-ts4.5/utils/anchor-utils.d.ts +16 -3
- package/dist/types-ts4.5/utils/inline-drop-target.d.ts +2 -0
- package/package.json +8 -5
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
1
2
|
/**
|
|
2
3
|
* @jsxRuntime classic
|
|
3
4
|
* @jsx jsx
|
|
@@ -14,7 +15,9 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
|
14
15
|
import { getNodeAnchor } from '../pm-plugins/decorations';
|
|
15
16
|
import { isAnchorSupported } from '../utils/anchor-utils';
|
|
16
17
|
import { isBlocksDragTargetDebug } from '../utils/drag-target-debug';
|
|
18
|
+
import { shouldAllowInlineDropTarget } from '../utils/inline-drop-target';
|
|
17
19
|
import { getNestedNodeLeftPaddingMargin } from './consts';
|
|
20
|
+
import { InlineDropTarget } from './inline-drop-target';
|
|
18
21
|
const DEFAULT_DROP_INDICATOR_WIDTH = 760;
|
|
19
22
|
const EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_WIDTH = '--editor-block-controls-drop-indicator-width';
|
|
20
23
|
const EDITOR_BLOCK_CONTROLS_DROP_TARGET_LEFT_MARGIN = '--editor-block-controls-drop-target-leftMargin';
|
|
@@ -70,7 +73,7 @@ const HoverZone = ({
|
|
|
70
73
|
node,
|
|
71
74
|
parent,
|
|
72
75
|
editorWidth,
|
|
73
|
-
|
|
76
|
+
anchorRectCache,
|
|
74
77
|
position,
|
|
75
78
|
isNestedDropTarget,
|
|
76
79
|
dropTargetStyle
|
|
@@ -90,7 +93,7 @@ const HoverZone = ({
|
|
|
90
93
|
const anchorName = node ? getNodeAnchor(node) : '';
|
|
91
94
|
const heightStyleOffset = `var(--editor-block-controls-drop-indicator-gap, 0)/2`;
|
|
92
95
|
const transformOffset = `var(${EDITOR_BLOCK_CONTROLS_DROP_INDICATOR_OFFSET}, 0)`;
|
|
93
|
-
const heightStyle = anchorName && enableDropZone.includes((node === null || node === void 0 ? void 0 : node.type.name) || '') ? isAnchorSupported() ? `calc(anchor-size(${anchorName} height)/2 + ${heightStyleOffset})` : `calc(${((
|
|
96
|
+
const heightStyle = anchorName && enableDropZone.includes((node === null || node === void 0 ? void 0 : node.type.name) || '') ? isAnchorSupported() ? `calc(anchor-size(${anchorName} height)/2 + ${heightStyleOffset})` : `calc(${((anchorRectCache === null || anchorRectCache === void 0 ? void 0 : anchorRectCache.getHeight(anchorName)) || 0) / 2}px + ${heightStyleOffset})` : '4px';
|
|
94
97
|
const transform = position === 'upper' ? `translateY(calc(-100% + ${transformOffset}))` : `translateY(${transformOffset})`;
|
|
95
98
|
return css({
|
|
96
99
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
|
|
@@ -100,7 +103,7 @@ const HoverZone = ({
|
|
|
100
103
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values
|
|
101
104
|
maxWidth: `${editorWidth || 0}px`
|
|
102
105
|
});
|
|
103
|
-
}, [
|
|
106
|
+
}, [anchorRectCache, editorWidth, node, position]);
|
|
104
107
|
const isFullHeight = useMemo(() => {
|
|
105
108
|
return dropTargetStyle === 'fullHeight';
|
|
106
109
|
}, [dropTargetStyle]);
|
|
@@ -120,16 +123,17 @@ const HoverZone = ({
|
|
|
120
123
|
hoverZoneUpperStyle, isFullHeight && fullHeightStyle, isFullHeightInLayout && fullHeightStyleAdjustZIndexStyle]
|
|
121
124
|
});
|
|
122
125
|
};
|
|
123
|
-
export const DropTargetV2 =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
export const DropTargetV2 = props => {
|
|
127
|
+
const {
|
|
128
|
+
api,
|
|
129
|
+
getPos,
|
|
130
|
+
prevNode,
|
|
131
|
+
nextNode,
|
|
132
|
+
parentNode,
|
|
133
|
+
formatMessage,
|
|
134
|
+
anchorRectCache,
|
|
135
|
+
dropTargetStyle
|
|
136
|
+
} = props;
|
|
133
137
|
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
|
134
138
|
const {
|
|
135
139
|
widthState
|
|
@@ -165,7 +169,7 @@ export const DropTargetV2 = ({
|
|
|
165
169
|
onDrop: onDrop,
|
|
166
170
|
node: prevNode,
|
|
167
171
|
editorWidth: widthState === null || widthState === void 0 ? void 0 : widthState.lineLength,
|
|
168
|
-
|
|
172
|
+
anchorRectCache: anchorRectCache,
|
|
169
173
|
position: "upper",
|
|
170
174
|
isNestedDropTarget: isNestedDropTarget
|
|
171
175
|
}), jsx("div", {
|
|
@@ -189,9 +193,13 @@ export const DropTargetV2 = ({
|
|
|
189
193
|
node: nextNode,
|
|
190
194
|
parent: parentNode,
|
|
191
195
|
editorWidth: widthState === null || widthState === void 0 ? void 0 : widthState.lineLength,
|
|
192
|
-
|
|
196
|
+
anchorRectCache: anchorRectCache,
|
|
193
197
|
position: "lower",
|
|
194
198
|
isNestedDropTarget: isNestedDropTarget,
|
|
195
199
|
dropTargetStyle: dropTargetStyle
|
|
196
|
-
}))
|
|
200
|
+
}), shouldAllowInlineDropTarget(isNestedDropTarget, nextNode) && jsx(Fragment, null, jsx(InlineDropTarget, _extends({}, props, {
|
|
201
|
+
position: "left"
|
|
202
|
+
})), jsx(InlineDropTarget, _extends({}, props, {
|
|
203
|
+
position: "right"
|
|
204
|
+
}))));
|
|
197
205
|
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/* eslint-disable @atlaskit/design-system/consistent-css-prop-usage */
|
|
2
|
+
/* eslint-disable @atlaskit/ui-styling-standard/no-unsafe-values */
|
|
3
|
+
/**
|
|
4
|
+
* @jsxRuntime classic
|
|
5
|
+
* @jsx jsx
|
|
6
|
+
*/
|
|
7
|
+
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
10
|
+
import { css, jsx } from '@emotion/react';
|
|
11
|
+
import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
|
|
12
|
+
import { DropIndicator } from '@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box';
|
|
13
|
+
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
14
|
+
import { getNodeAnchor } from '../pm-plugins/decorations';
|
|
15
|
+
import { isAnchorSupported } from '../utils/anchor-utils';
|
|
16
|
+
const dropTargetCommonStyle = css({
|
|
17
|
+
position: 'absolute',
|
|
18
|
+
display: 'block'
|
|
19
|
+
});
|
|
20
|
+
const hideDropTargetStyle = css({
|
|
21
|
+
display: 'none'
|
|
22
|
+
});
|
|
23
|
+
const hoverZoneCommonStyle = css({
|
|
24
|
+
position: 'absolute',
|
|
25
|
+
// same value as block hover zone
|
|
26
|
+
zIndex: 110
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// gap between node boundary and drop indicator/drop zone
|
|
30
|
+
const GAP = 4;
|
|
31
|
+
const HOVER_ZONE_WIDTH_OFFSET = 40;
|
|
32
|
+
const HOVER_ZONE_HEIGHT_OFFSET = 10;
|
|
33
|
+
const HOVER_ZONE_DEFAULT_WIDTH = 40;
|
|
34
|
+
export const InlineDropTarget = ({
|
|
35
|
+
api,
|
|
36
|
+
nextNode,
|
|
37
|
+
position,
|
|
38
|
+
anchorRectCache
|
|
39
|
+
}) => {
|
|
40
|
+
const {
|
|
41
|
+
widthState
|
|
42
|
+
} = useSharedPluginState(api, ['width']);
|
|
43
|
+
const [isDraggedOver, setIsDraggedOver] = useState(false);
|
|
44
|
+
const anchorName = nextNode ? getNodeAnchor(nextNode) : '';
|
|
45
|
+
const handleDragEnter = useCallback(() => {
|
|
46
|
+
setIsDraggedOver(true);
|
|
47
|
+
}, []);
|
|
48
|
+
const handleDragLeave = useCallback(() => {
|
|
49
|
+
setIsDraggedOver(false);
|
|
50
|
+
}, []);
|
|
51
|
+
const dropTargetRectStyle = useMemo(() => {
|
|
52
|
+
if (isAnchorSupported()) {
|
|
53
|
+
return css({
|
|
54
|
+
height: `calc(anchor-size(${anchorName} height))`,
|
|
55
|
+
positionAnchor: anchorName,
|
|
56
|
+
left: position === 'left' ? `calc(anchor(left) - ${GAP}px)` : `calc(anchor(right) + ${GAP}px)`,
|
|
57
|
+
top: `calc(anchor(top))`
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const nodeRect = anchorRectCache === null || anchorRectCache === void 0 ? void 0 : anchorRectCache.getRect(anchorName);
|
|
61
|
+
return css({
|
|
62
|
+
height: `calc(${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.height) || 0}px)`,
|
|
63
|
+
left: position === 'left' ? `${((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.left) || 0) - GAP}px` : `${((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.right) || 0) + GAP}px`,
|
|
64
|
+
top: `${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.top) || 0}px`
|
|
65
|
+
});
|
|
66
|
+
}, [anchorName, anchorRectCache, position]);
|
|
67
|
+
return jsx(Fragment, null, jsx("div", {
|
|
68
|
+
"data-test-id": `block-ctrl-drop-target-${position}`,
|
|
69
|
+
css: [dropTargetCommonStyle, dropTargetRectStyle, !isDraggedOver && hideDropTargetStyle]
|
|
70
|
+
}, jsx(DropIndicator, {
|
|
71
|
+
edge: position
|
|
72
|
+
})), jsx(InlineHoverZone, {
|
|
73
|
+
position: position,
|
|
74
|
+
node: nextNode,
|
|
75
|
+
editorWidthState: widthState,
|
|
76
|
+
anchorRectCache: anchorRectCache,
|
|
77
|
+
onDragEnter: handleDragEnter,
|
|
78
|
+
onDragLeave: handleDragLeave,
|
|
79
|
+
onDrop: () => {}
|
|
80
|
+
}));
|
|
81
|
+
};
|
|
82
|
+
export const InlineHoverZone = ({
|
|
83
|
+
node,
|
|
84
|
+
editorWidthState,
|
|
85
|
+
anchorRectCache,
|
|
86
|
+
position,
|
|
87
|
+
onDragEnter,
|
|
88
|
+
onDragLeave,
|
|
89
|
+
onDrop
|
|
90
|
+
}) => {
|
|
91
|
+
const ref = useRef(null);
|
|
92
|
+
const {
|
|
93
|
+
width: editorWith
|
|
94
|
+
} = editorWidthState || {};
|
|
95
|
+
const anchorName = node ? getNodeAnchor(node) : '';
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (ref.current) {
|
|
98
|
+
return dropTargetForElements({
|
|
99
|
+
element: ref.current,
|
|
100
|
+
onDragEnter,
|
|
101
|
+
onDragLeave,
|
|
102
|
+
onDrop
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}, [onDragEnter, onDragLeave, onDrop]);
|
|
106
|
+
const inlineHoverZoneRectStyle = useMemo(() => {
|
|
107
|
+
if (isAnchorSupported()) {
|
|
108
|
+
return css({
|
|
109
|
+
positionAnchor: anchorName,
|
|
110
|
+
left: position === 'left' ? 'unset' : `calc(anchor(right) + ${GAP}px)`,
|
|
111
|
+
right: position === 'left' ? `calc(anchor(left) + ${GAP}px)` : 'unset',
|
|
112
|
+
top: `calc(anchor(top))`,
|
|
113
|
+
width: editorWith ? `calc((${editorWith}px - anchor-size(${anchorName} width))/2 - ${HOVER_ZONE_WIDTH_OFFSET}px)` : `${HOVER_ZONE_DEFAULT_WIDTH}px`,
|
|
114
|
+
height: `calc(anchor-size(${anchorName} height))`
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const nodeRect = anchorRectCache === null || anchorRectCache === void 0 ? void 0 : anchorRectCache.getRect(anchorName);
|
|
118
|
+
const width = editorWith ? (editorWith - ((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.width) || 0)) / 2 - HOVER_ZONE_WIDTH_OFFSET : HOVER_ZONE_DEFAULT_WIDTH;
|
|
119
|
+
return css({
|
|
120
|
+
left: position === 'left' ? `${((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.left) || 0) - width - GAP}px` : `${((nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.right) || 0) + GAP}px`,
|
|
121
|
+
top: `${(nodeRect === null || nodeRect === void 0 ? void 0 : nodeRect.top) || 0}px`,
|
|
122
|
+
width: `${width}px`,
|
|
123
|
+
height: `calc(${(anchorRectCache === null || anchorRectCache === void 0 ? void 0 : anchorRectCache.getHeight(anchorName)) || 0}px - ${HOVER_ZONE_HEIGHT_OFFSET}px)`
|
|
124
|
+
});
|
|
125
|
+
}, [anchorName, anchorRectCache, editorWith, position]);
|
|
126
|
+
return jsx("div", {
|
|
127
|
+
ref: ref,
|
|
128
|
+
css: [hoverZoneCommonStyle, inlineHoverZoneRectStyle]
|
|
129
|
+
});
|
|
130
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
3
|
+
export const isPreRelease1 = () => {
|
|
4
|
+
return editorExperiment('advanced_layouts', true) || fg('platform_editor_advanced_layouts_pre_release_1');
|
|
5
|
+
};
|
|
@@ -7,34 +7,40 @@ export const isAnchorSupported = memoizeOne(() => {
|
|
|
7
7
|
}
|
|
8
8
|
return false;
|
|
9
9
|
});
|
|
10
|
-
export class
|
|
10
|
+
export class AnchorRectCache {
|
|
11
11
|
constructor() {
|
|
12
|
-
_defineProperty(this, "
|
|
12
|
+
_defineProperty(this, "anchorRectMap", {});
|
|
13
13
|
_defineProperty(this, "isAnchorSupported", isAnchorSupported());
|
|
14
14
|
_defineProperty(this, "isDirty", true);
|
|
15
15
|
_defineProperty(this, "view", null);
|
|
16
16
|
}
|
|
17
17
|
clear() {
|
|
18
18
|
this.isDirty = true;
|
|
19
|
-
this.
|
|
19
|
+
this.anchorRectMap = {};
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
getRects() {
|
|
22
22
|
if (this.isDirty) {
|
|
23
23
|
var _this$view;
|
|
24
24
|
const anchorElements = ((_this$view = this.view) === null || _this$view === void 0 ? void 0 : _this$view.dom.querySelectorAll('[data-drag-handler-anchor-name]')) || [];
|
|
25
|
-
this.
|
|
25
|
+
this.anchorRectMap = Array.from(anchorElements).reduce((prev, curr) => {
|
|
26
26
|
const anchorName = curr.getAttribute('data-drag-handler-anchor-name');
|
|
27
27
|
if (anchorName) {
|
|
28
28
|
return {
|
|
29
29
|
...prev,
|
|
30
|
-
[anchorName]:
|
|
30
|
+
[anchorName]: {
|
|
31
|
+
height: curr.clientHeight,
|
|
32
|
+
top: curr.offsetTop,
|
|
33
|
+
left: curr.offsetLeft,
|
|
34
|
+
right: curr.offsetLeft + curr.clientWidth,
|
|
35
|
+
width: curr.clientWidth
|
|
36
|
+
}
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
39
|
return prev;
|
|
34
40
|
}, {});
|
|
35
41
|
this.isDirty = false;
|
|
36
42
|
}
|
|
37
|
-
return this.
|
|
43
|
+
return this.anchorRectMap;
|
|
38
44
|
}
|
|
39
45
|
setEditorView(view) {
|
|
40
46
|
if (this.view !== view) {
|
|
@@ -42,10 +48,50 @@ export class AnchorHeightsCache {
|
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
50
|
getHeight(anchorName) {
|
|
51
|
+
var _rects$anchorName;
|
|
45
52
|
if (this.isAnchorSupported) {
|
|
46
53
|
return null;
|
|
47
54
|
}
|
|
48
|
-
const
|
|
49
|
-
return
|
|
55
|
+
const rects = this.getRects();
|
|
56
|
+
return (_rects$anchorName = rects[anchorName]) === null || _rects$anchorName === void 0 ? void 0 : _rects$anchorName.height;
|
|
57
|
+
}
|
|
58
|
+
getWidth(anchorName) {
|
|
59
|
+
var _rects$anchorName2;
|
|
60
|
+
if (this.isAnchorSupported) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const rects = this.getRects();
|
|
64
|
+
return (_rects$anchorName2 = rects[anchorName]) === null || _rects$anchorName2 === void 0 ? void 0 : _rects$anchorName2.width;
|
|
65
|
+
}
|
|
66
|
+
getLeft(anchorName) {
|
|
67
|
+
var _rects$anchorName3;
|
|
68
|
+
if (this.isAnchorSupported) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const rects = this.getRects();
|
|
72
|
+
return (_rects$anchorName3 = rects[anchorName]) === null || _rects$anchorName3 === void 0 ? void 0 : _rects$anchorName3.left;
|
|
73
|
+
}
|
|
74
|
+
getTop(anchorName) {
|
|
75
|
+
var _rects$anchorName4;
|
|
76
|
+
if (this.isAnchorSupported) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const rects = this.getRects();
|
|
80
|
+
return (_rects$anchorName4 = rects[anchorName]) === null || _rects$anchorName4 === void 0 ? void 0 : _rects$anchorName4.top;
|
|
81
|
+
}
|
|
82
|
+
getRight(anchorName) {
|
|
83
|
+
var _rects$anchorName5;
|
|
84
|
+
if (this.isAnchorSupported) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const rects = this.getRects();
|
|
88
|
+
return (_rects$anchorName5 = rects[anchorName]) === null || _rects$anchorName5 === void 0 ? void 0 : _rects$anchorName5.right;
|
|
89
|
+
}
|
|
90
|
+
getRect(anchorName) {
|
|
91
|
+
if (this.isAnchorSupported) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const rects = this.getRects();
|
|
95
|
+
return rects[anchorName];
|
|
50
96
|
}
|
|
51
97
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
2
|
+
import { MAX_LAYOUT_COLUMN_SUPPORTED } from '../consts';
|
|
3
|
+
import { isPreRelease1 } from './advanced-layouts-flags';
|
|
4
|
+
export const shouldAllowInlineDropTarget = (isNested, node) => {
|
|
5
|
+
if (!isPreRelease1() || isNested) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if ((node === null || node === void 0 ? void 0 : node.type.name) === 'layoutSection') {
|
|
9
|
+
return node.childCount < MAX_LAYOUT_COLUMN_SUPPORTED;
|
|
10
|
+
}
|
|
11
|
+
return !isEmptyParagraph(node);
|
|
12
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { DEFAULT_COLUMN_DISTRIBUTIONS } from '../ui/consts';
|
|
3
|
+
var createNewLayout = function createNewLayout(schema, layoutContents) {
|
|
4
|
+
// TODO update with constant
|
|
5
|
+
if (layoutContents.length === 0 || layoutContents.length > 5) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
var width = DEFAULT_COLUMN_DISTRIBUTIONS[layoutContents.length];
|
|
9
|
+
if (!width) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
var _ref = schema.nodes || {},
|
|
13
|
+
layoutSection = _ref.layoutSection,
|
|
14
|
+
layoutColumn = _ref.layoutColumn;
|
|
15
|
+
try {
|
|
16
|
+
var layoutSectionNode = layoutSection.createChecked(undefined, Fragment.fromArray(layoutContents.map(function (layoutContent) {
|
|
17
|
+
return layoutColumn.createChecked({
|
|
18
|
+
width: width
|
|
19
|
+
}, layoutContent);
|
|
20
|
+
})));
|
|
21
|
+
return layoutSectionNode;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
// TODO analytics
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
export var moveToLayout = function moveToLayout(api) {
|
|
28
|
+
return function (from, to, position) {
|
|
29
|
+
return function (_ref2) {
|
|
30
|
+
var tr = _ref2.tr;
|
|
31
|
+
var _ref3 = tr.doc.type.schema.nodes || {},
|
|
32
|
+
layoutSection = _ref3.layoutSection,
|
|
33
|
+
layoutColumn = _ref3.layoutColumn,
|
|
34
|
+
doc = _ref3.doc;
|
|
35
|
+
|
|
36
|
+
// layout plugin does not exist
|
|
37
|
+
if (!layoutSection || !layoutColumn) {
|
|
38
|
+
return tr;
|
|
39
|
+
}
|
|
40
|
+
var $to = tr.doc.resolve(to);
|
|
41
|
+
|
|
42
|
+
// invalid to position or not top level.
|
|
43
|
+
if (!$to.nodeAfter || $to.parent.type !== doc) {
|
|
44
|
+
return tr;
|
|
45
|
+
}
|
|
46
|
+
var $from = tr.doc.resolve(from);
|
|
47
|
+
|
|
48
|
+
// invalid from position
|
|
49
|
+
if (!$from.nodeAfter) {
|
|
50
|
+
return tr;
|
|
51
|
+
}
|
|
52
|
+
var toNode = $to.nodeAfter;
|
|
53
|
+
var fromNode = $from.nodeAfter;
|
|
54
|
+
var fromNodeEndPos = from + fromNode.nodeSize;
|
|
55
|
+
var toNodeEndPos = to + toNode.nodeSize;
|
|
56
|
+
if ($to.nodeAfter.type !== layoutSection) {
|
|
57
|
+
var layoutContents = position === 'left' ? [fromNode, toNode] : [toNode, fromNode];
|
|
58
|
+
var newLayout = createNewLayout(tr.doc.type.schema, layoutContents);
|
|
59
|
+
if (newLayout) {
|
|
60
|
+
tr.delete(from, fromNodeEndPos);
|
|
61
|
+
var mappedTo = tr.mapping.map(to);
|
|
62
|
+
tr.delete(mappedTo, toNodeEndPos);
|
|
63
|
+
tr.insert(mappedTo, newLayout); // insert the content at the new position
|
|
64
|
+
}
|
|
65
|
+
return tr;
|
|
66
|
+
}
|
|
67
|
+
return tr;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
};
|
package/dist/esm/consts.js
CHANGED
package/dist/esm/plugin.js
CHANGED
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
4
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
5
5
|
import { moveNode } from './commands/move-node';
|
|
6
|
+
import { moveToLayout } from './commands/move-to-layout';
|
|
6
7
|
import { createEmptyBlockExperimentPlugin } from './pm-plugins/empty-block-experiment';
|
|
7
8
|
import { createPlugin, key } from './pm-plugins/main';
|
|
8
9
|
import { DragHandleMenu } from './ui/drag-handle-menu';
|
|
@@ -31,6 +32,7 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
|
|
|
31
32
|
},
|
|
32
33
|
commands: {
|
|
33
34
|
moveNode: moveNode(api),
|
|
35
|
+
moveToLayout: moveToLayout(api),
|
|
34
36
|
showDragHandleAt: function showDragHandleAt(pos, anchorName, nodeType, handleOptions) {
|
|
35
37
|
return function (_ref4) {
|
|
36
38
|
var tr = _ref4.tr;
|
|
@@ -45,20 +47,9 @@ export var blockControlsPlugin = function blockControlsPlugin(_ref) {
|
|
|
45
47
|
return tr;
|
|
46
48
|
};
|
|
47
49
|
},
|
|
48
|
-
|
|
50
|
+
setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
|
|
49
51
|
return function (_ref5) {
|
|
50
52
|
var tr = _ref5.tr;
|
|
51
|
-
if (fg('confluence_frontend_page_title_enter_improvements')) {
|
|
52
|
-
tr.setMeta(key, {
|
|
53
|
-
hideDragHandle: true
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
return tr;
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
setNodeDragged: function setNodeDragged(getPos, anchorName, nodeType) {
|
|
60
|
-
return function (_ref6) {
|
|
61
|
-
var tr = _ref6.tr;
|
|
62
53
|
var pos = getPos();
|
|
63
54
|
if (pos === undefined) {
|
|
64
55
|
return tr;
|
|
@@ -122,7 +122,7 @@ export var findNodeDecs = function findNodeDecs(decorations, from, to) {
|
|
|
122
122
|
return spec.type === TYPE_NODE_DEC;
|
|
123
123
|
});
|
|
124
124
|
};
|
|
125
|
-
export var createDropTargetDecoration = function createDropTargetDecoration(pos, props, side,
|
|
125
|
+
export var createDropTargetDecoration = function createDropTargetDecoration(pos, props, side, anchorRectCache) {
|
|
126
126
|
return Decoration.widget(pos, function (_, getPos) {
|
|
127
127
|
var element = document.createElement('div');
|
|
128
128
|
element.setAttribute('data-blocks-drop-target-container', 'true');
|
|
@@ -137,7 +137,7 @@ export var createDropTargetDecoration = function createDropTargetDecoration(pos,
|
|
|
137
137
|
if (fg('platform_editor_drag_and_drop_target_v2')) {
|
|
138
138
|
ReactDOM.render( /*#__PURE__*/createElement(DropTargetV2, _objectSpread(_objectSpread({}, props), {}, {
|
|
139
139
|
getPos: getPos,
|
|
140
|
-
|
|
140
|
+
anchorRectCache: anchorRectCache
|
|
141
141
|
})), element);
|
|
142
142
|
} else {
|
|
143
143
|
ReactDOM.render( /*#__PURE__*/createElement(DropTarget, _objectSpread(_objectSpread({}, props), {}, {
|
|
@@ -150,7 +150,7 @@ export var createDropTargetDecoration = function createDropTargetDecoration(pos,
|
|
|
150
150
|
side: side
|
|
151
151
|
});
|
|
152
152
|
};
|
|
153
|
-
export var dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, activeNode,
|
|
153
|
+
export var dropTargetDecorations = function dropTargetDecorations(newState, api, formatMessage, activeNode, anchorRectCache, from, to) {
|
|
154
154
|
unmountDecorations('data-blocks-drop-target-container');
|
|
155
155
|
var decs = [];
|
|
156
156
|
var POS_END_OF_DOC = newState.doc.nodeSize - 2;
|
|
@@ -159,7 +159,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
159
159
|
var prevNode;
|
|
160
160
|
var activeNodePos = activeNode === null || activeNode === void 0 ? void 0 : activeNode.pos;
|
|
161
161
|
var activePMNode = typeof activeNodePos === 'number' && newState.doc.resolve(activeNodePos).nodeAfter;
|
|
162
|
-
|
|
162
|
+
anchorRectCache === null || anchorRectCache === void 0 || anchorRectCache.clear();
|
|
163
163
|
var prevNodeStack = [];
|
|
164
164
|
var popNodeStack = function popNodeStack(depth) {
|
|
165
165
|
var result;
|
|
@@ -224,7 +224,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
224
224
|
parentNode: parent || undefined,
|
|
225
225
|
formatMessage: formatMessage,
|
|
226
226
|
dropTargetStyle: shouldShowFullHeight ? 'fullHeight' : 'default'
|
|
227
|
-
}, -1,
|
|
227
|
+
}, -1, anchorRectCache));
|
|
228
228
|
if (endPos !== undefined) {
|
|
229
229
|
decs.push(createDropTargetDecoration(endPos, {
|
|
230
230
|
api: api,
|
|
@@ -232,7 +232,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
232
232
|
parentNode: parent || undefined,
|
|
233
233
|
formatMessage: formatMessage,
|
|
234
234
|
dropTargetStyle: isInSupportedContainer ? 'fullHeight' : 'default'
|
|
235
|
-
}, -1,
|
|
235
|
+
}, -1, anchorRectCache));
|
|
236
236
|
}
|
|
237
237
|
if (fg('platform_editor_drag_and_drop_target_v2')) {
|
|
238
238
|
pushNodeStack(node, depth);
|
|
@@ -247,7 +247,7 @@ export var dropTargetDecorations = function dropTargetDecorations(newState, api,
|
|
|
247
247
|
formatMessage: formatMessage,
|
|
248
248
|
prevNode: newState.doc.lastChild || undefined,
|
|
249
249
|
parentNode: newState.doc
|
|
250
|
-
}, undefined,
|
|
250
|
+
}, undefined, anchorRectCache));
|
|
251
251
|
}
|
|
252
252
|
return decs;
|
|
253
253
|
};
|
|
@@ -329,18 +329,22 @@ export var dragHandleDecoration = function dragHandleDecoration(api, formatMessa
|
|
|
329
329
|
return Decoration.widget(pos, function (view, getPos) {
|
|
330
330
|
var element = document.createElement('span');
|
|
331
331
|
// Need to set it to inline to avoid text being split when merging two paragraphs
|
|
332
|
-
|
|
332
|
+
// platform_editor_element_dnd_nested_fix_patch_2 -> inline decoration causes focus issues when refocusing Editor into first line
|
|
333
|
+
element.style.display = fg('platform_editor_element_dnd_nested_fix_patch_2') ? 'block' : 'inline';
|
|
333
334
|
element.setAttribute('data-testid', 'block-ctrl-decorator-widget');
|
|
334
335
|
element.setAttribute('data-blocks-drag-handle-container', 'true');
|
|
335
336
|
var isTopLevelNode = true;
|
|
336
337
|
if (editorExperiment('nested-dnd', true)) {
|
|
337
|
-
var
|
|
338
|
-
|
|
338
|
+
var newPos = fg('platform_editor_element_dnd_nested_fix_patch_3') ? getPos() : pos;
|
|
339
|
+
if (typeof newPos === 'number') {
|
|
340
|
+
var $pos = view.state.doc.resolve(newPos);
|
|
341
|
+
isTopLevelNode = ($pos === null || $pos === void 0 ? void 0 : $pos.parent.type.name) === 'doc';
|
|
342
|
+
}
|
|
339
343
|
/*
|
|
340
344
|
* We disable mouseover event to fix flickering issue on hover
|
|
341
345
|
* However, the tooltip for nested drag handle is no long working.
|
|
342
346
|
*/
|
|
343
|
-
if (!isTopLevelNode) {
|
|
347
|
+
if (newPos === undefined || !isTopLevelNode) {
|
|
344
348
|
// This will also hide the tooltip.
|
|
345
349
|
unbind = bind(element, {
|
|
346
350
|
type: 'mouseover',
|
|
@@ -7,11 +7,6 @@ var isEmptyNestedParagraphOrHeading = function isEmptyNestedParagraphOrHeading(t
|
|
|
7
7
|
}
|
|
8
8
|
return false;
|
|
9
9
|
};
|
|
10
|
-
var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
|
|
11
|
-
var _elem$firstElementChi;
|
|
12
|
-
var parentElement = elem.parentElement;
|
|
13
|
-
return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
|
|
14
|
-
};
|
|
15
10
|
export var handleMouseOver = function handleMouseOver(view, event, api) {
|
|
16
11
|
var _api$blockControls, _target$classList;
|
|
17
12
|
var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
|
|
@@ -30,11 +25,6 @@ export var handleMouseOver = function handleMouseOver(view, event, api) {
|
|
|
30
25
|
var rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
|
|
31
26
|
if (rootElement) {
|
|
32
27
|
var _rootElement$parentEl;
|
|
33
|
-
if (isDocFirstChildEmptyLine(rootElement) && fg('confluence_frontend_page_title_enter_improvements')) {
|
|
34
|
-
var _api$core, _api$blockControls2;
|
|
35
|
-
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.hideDragHandle());
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
28
|
// We want to exlude handles from showing for empty paragraph and heading nodes
|
|
39
29
|
if (editorExperiment('nested-dnd', true) && isEmptyNestedParagraphOrHeading(rootElement)) {
|
|
40
30
|
return false;
|
|
@@ -83,8 +73,8 @@ export var handleMouseOver = function handleMouseOver(view, event, api) {
|
|
|
83
73
|
}
|
|
84
74
|
var nodeType = rootElement.getAttribute('data-drag-handler-node-type');
|
|
85
75
|
if (nodeType) {
|
|
86
|
-
var _api$
|
|
87
|
-
api === null || api === void 0 || (_api$
|
|
76
|
+
var _api$core, _api$blockControls2;
|
|
77
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(api === null || api === void 0 || (_api$blockControls2 = api.blockControls) === null || _api$blockControls2 === void 0 ? void 0 : _api$blockControls2.commands.showDragHandleAt(rootPos, anchorName, nodeType));
|
|
88
78
|
}
|
|
89
79
|
}
|
|
90
80
|
};
|