@atlaskit/editor-plugin-paste-options-toolbar 13.0.17 → 13.0.18
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 +8 -0
- package/compass.yml +4 -1
- package/dist/cjs/ui/on-paste-actions-menu/PasteActionsMenu.js +6 -2
- package/dist/cjs/ui/utils/paste-menu-rules/isNotSingleLink.js +26 -49
- package/dist/es2019/ui/on-paste-actions-menu/PasteActionsMenu.js +3 -1
- package/dist/es2019/ui/utils/paste-menu-rules/isNotSingleLink.js +18 -48
- package/dist/esm/ui/on-paste-actions-menu/PasteActionsMenu.js +5 -1
- package/dist/esm/ui/utils/paste-menu-rules/isNotSingleLink.js +25 -49
- package/dist/types/ui/on-paste-actions-menu/PasteActionsMenu.d.ts +1 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste-options-toolbar
|
|
2
2
|
|
|
3
|
+
## 13.0.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`e8a2ffea2c9eb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e8a2ffea2c9eb) -
|
|
8
|
+
[ux] Paste actions popup no longer appears for link-only pastes.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 13.0.17
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/compass.yml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
configVersion: 1
|
|
2
2
|
id: ari:cloud:compass:a436116f-02ce-4520-8fbb-7301462a1674:component/c5751cc6-3513-4070-9deb-af31e86aed34/e2696006-dd71-4fa9-8c65-6f36e32bac76
|
|
3
3
|
name: '@atlaskit/editor-plugin-paste-options-toolbar'
|
|
4
|
-
ownerId: ari:cloud:identity::team/
|
|
4
|
+
ownerId: ari:cloud:identity::team/0250ee69-f755-47fd-a468-bf8a9d10a3c5 # Editor AI
|
|
5
5
|
labels:
|
|
6
6
|
- platform-code
|
|
7
7
|
- platform-afm
|
|
@@ -24,6 +24,9 @@ customFields:
|
|
|
24
24
|
- name: Department
|
|
25
25
|
type: text
|
|
26
26
|
value: Eng - Editor
|
|
27
|
+
- name: Trusted Reviewer Teams
|
|
28
|
+
type: text
|
|
29
|
+
value: ari:cloud:identity::team/cf6a670b-5252-4c68-a769-9207de366beb
|
|
27
30
|
- name: Technical Owner
|
|
28
31
|
type: user
|
|
29
32
|
value: ari:cloud:identity::user/612646c53fe26c00694fbe6a # Chris Kimber
|
|
@@ -12,7 +12,7 @@ exports.getVisualEndBottom = getVisualEndBottom;
|
|
|
12
12
|
exports.onInlinePositionCalculated = onInlinePositionCalculated;
|
|
13
13
|
exports.onPositionCalculated = onPositionCalculated;
|
|
14
14
|
exports.resolveTableAfterPos = resolveTableAfterPos;
|
|
15
|
-
exports.shouldSuppressPasteActionsForAgentMention = void 0;
|
|
15
|
+
exports.shouldSuppressPasteActionsForSingleLink = exports.shouldSuppressPasteActionsForAgentMention = void 0;
|
|
16
16
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
17
17
|
var _react = _interopRequireWildcard(require("react"));
|
|
18
18
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
@@ -28,6 +28,7 @@ var _commands = require("../../editor-commands/commands");
|
|
|
28
28
|
var _constants = require("../../pm-plugins/constants");
|
|
29
29
|
var _types = require("../../types/types");
|
|
30
30
|
var _toolbar2 = require("../toolbar");
|
|
31
|
+
var _isNotSingleLink = require("../utils/paste-menu-rules/isNotSingleLink");
|
|
31
32
|
var _hasVisibleButton = require("./hasVisibleButton");
|
|
32
33
|
var _PasteActionsMenuContent = require("./PasteActionsMenuContent");
|
|
33
34
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
@@ -56,6 +57,9 @@ var containsAgentMention = exports.containsAgentMention = function containsAgent
|
|
|
56
57
|
var shouldSuppressPasteActionsForAgentMention = exports.shouldSuppressPasteActionsForAgentMention = function shouldSuppressPasteActionsForAgentMention(slice) {
|
|
57
58
|
return (0, _expVal.expVal)('platform_editor_agent_mentions', 'isEnabled', false) && containsAgentMention(slice);
|
|
58
59
|
};
|
|
60
|
+
var shouldSuppressPasteActionsForSingleLink = exports.shouldSuppressPasteActionsForSingleLink = function shouldSuppressPasteActionsForSingleLink(slice) {
|
|
61
|
+
return (0, _expVal.expVal)('platform_editor_fix_link_paste_menu', 'isEnabled', false) && !(0, _isNotSingleLink.isNotSingleLink)(slice !== null && slice !== void 0 ? slice : undefined);
|
|
62
|
+
};
|
|
59
63
|
/**
|
|
60
64
|
* Returns the DOM element at the given document position for use as a Popup anchor.
|
|
61
65
|
* For empty blocks (BR elements), returns the parent element to ensure correct positioning.
|
|
@@ -265,7 +269,7 @@ var PasteActionsMenu = exports.PasteActionsMenu = function PasteActionsMenu(_ref
|
|
|
265
269
|
lastContentPasted = _useSharedPluginState.lastContentPasted;
|
|
266
270
|
var sliceForAgentMentionSuppression = lastContentPasted === null || lastContentPasted === void 0 ? void 0 : lastContentPasted.sourcePastedSlice;
|
|
267
271
|
var shouldSuppressPasteActions = (0, _react.useMemo)(function () {
|
|
268
|
-
return shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression);
|
|
272
|
+
return shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression) || shouldSuppressPasteActionsForSingleLink(sliceForAgentMentionSuppression);
|
|
269
273
|
}, [sliceForAgentMentionSuppression]);
|
|
270
274
|
var prevShowToolbarRef = (0, _react.useRef)(false);
|
|
271
275
|
var popupContentRef = (0, _react.useRef)(null);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.isNotSingleLink = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
7
9
|
/**
|
|
8
10
|
* Returns true if the given text node's sole mark is a `link` mark whose href
|
|
9
11
|
* matches the node's text content exactly (i.e. the link label IS the URL).
|
|
@@ -42,36 +44,10 @@ var isParseableUrl = function isParseableUrl(text) {
|
|
|
42
44
|
return false;
|
|
43
45
|
}
|
|
44
46
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* Returns true if the slice represents a single smart-link card node.
|
|
48
|
-
* Handles two shapes:
|
|
49
|
-
* - paragraph > inlineCard|blockCard (smartlink from editor/renderer, wrapped in a paragraph)
|
|
50
|
-
* - inlineCard|blockCard (top-level card with no paragraph wrapper)
|
|
51
|
-
*/
|
|
52
|
-
var isSingleSmartLinkCard = function isSingleSmartLinkCard(slice) {
|
|
53
|
-
var isSupportedCard = function isSupportedCard(node) {
|
|
54
|
-
return node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
55
|
-
};
|
|
56
|
-
if (slice.content.childCount !== 1) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
var topNode = slice.content.child(0);
|
|
60
|
-
|
|
61
|
-
// Top-level inlineCard/blockCard (no paragraph wrapper)
|
|
62
|
-
if (isSupportedCard(topNode)) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// paragraph > inlineCard/blockCard
|
|
67
|
-
if (topNode.type.name !== 'paragraph') {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
if (topNode.childCount !== 1) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
return isSupportedCard(topNode.child(0));
|
|
47
|
+
var isSupportedCard = function isSupportedCard(node) {
|
|
48
|
+
return node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
74
49
|
};
|
|
50
|
+
var transparentSingleChildContainerNodeTypes = new Set(['paragraph', 'listItem', 'bulletList', 'orderedList']);
|
|
75
51
|
|
|
76
52
|
/**
|
|
77
53
|
* Returns the children of a Fragment, filtering out whitespace-only text nodes.
|
|
@@ -91,32 +67,33 @@ var significantChildren = function significantChildren(fragment) {
|
|
|
91
67
|
};
|
|
92
68
|
|
|
93
69
|
/**
|
|
94
|
-
* Returns true
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* Whitespace-only sibling text nodes
|
|
70
|
+
* Returns true when the fragment contains exactly one meaningful leaf that
|
|
71
|
+
* satisfies `isSupportedLeaf`.
|
|
72
|
+
*
|
|
73
|
+
* Transparent single-child containers (paragraph, listItem, bulletList, and
|
|
74
|
+
* orderedList) are traversed recursively. Whitespace-only sibling text nodes
|
|
75
|
+
* are ignored at each level.
|
|
99
76
|
*/
|
|
100
|
-
var
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (significantTopChildren.length === 1 && isUrlOnlyLinkTextNode(significantTopChildren[0])) {
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// paragraph > text(link mark)
|
|
108
|
-
if (slice.content.childCount !== 1) {
|
|
77
|
+
var _containsExactlyOneMeaningfulLeaf = function containsExactlyOneMeaningfulLeaf(fragment, isSupportedLeaf) {
|
|
78
|
+
var children = significantChildren(fragment);
|
|
79
|
+
if (children.length !== 1) {
|
|
109
80
|
return false;
|
|
110
81
|
}
|
|
111
|
-
var
|
|
112
|
-
|
|
113
|
-
|
|
82
|
+
var _children = (0, _slicedToArray2.default)(children, 1),
|
|
83
|
+
child = _children[0];
|
|
84
|
+
if (isSupportedLeaf(child)) {
|
|
85
|
+
return true;
|
|
114
86
|
}
|
|
115
|
-
|
|
116
|
-
if (children.length !== 1) {
|
|
87
|
+
if (!transparentSingleChildContainerNodeTypes.has(child.type.name)) {
|
|
117
88
|
return false;
|
|
118
89
|
}
|
|
119
|
-
return
|
|
90
|
+
return _containsExactlyOneMeaningfulLeaf(child.content, isSupportedLeaf);
|
|
91
|
+
};
|
|
92
|
+
var isSingleSmartLinkCard = function isSingleSmartLinkCard(slice) {
|
|
93
|
+
return _containsExactlyOneMeaningfulLeaf(slice.content, isSupportedCard);
|
|
94
|
+
};
|
|
95
|
+
var isSingleBareLink = function isSingleBareLink(slice) {
|
|
96
|
+
return _containsExactlyOneMeaningfulLeaf(slice.content, isUrlOnlyLinkTextNode);
|
|
120
97
|
};
|
|
121
98
|
|
|
122
99
|
/**
|
|
@@ -12,6 +12,7 @@ import { hideToolbar, highlightContent, showToolbar } from '../../editor-command
|
|
|
12
12
|
import { PASTE_MENU_GAP_HORIZONTAL, PASTE_MENU_GAP_TOP } from '../../pm-plugins/constants';
|
|
13
13
|
import { ToolbarDropdownOption } from '../../types/types';
|
|
14
14
|
import { isToolbarVisible } from '../toolbar';
|
|
15
|
+
import { isNotSingleLink } from '../utils/paste-menu-rules/isNotSingleLink';
|
|
15
16
|
import { getVisibleKeys, hasVisibleButton } from './hasVisibleButton';
|
|
16
17
|
import { PasteActionsMenuContent } from './PasteActionsMenuContent';
|
|
17
18
|
const PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
@@ -33,6 +34,7 @@ export const containsAgentMention = slice => {
|
|
|
33
34
|
return hasAgentMention;
|
|
34
35
|
};
|
|
35
36
|
export const shouldSuppressPasteActionsForAgentMention = slice => expVal('platform_editor_agent_mentions', 'isEnabled', false) && containsAgentMention(slice);
|
|
37
|
+
export const shouldSuppressPasteActionsForSingleLink = slice => expVal('platform_editor_fix_link_paste_menu', 'isEnabled', false) && !isNotSingleLink(slice !== null && slice !== void 0 ? slice : undefined);
|
|
36
38
|
/**
|
|
37
39
|
* Returns the DOM element at the given document position for use as a Popup anchor.
|
|
38
40
|
* For empty blocks (BR elements), returns the parent element to ensure correct positioning.
|
|
@@ -245,7 +247,7 @@ export const PasteActionsMenu = ({
|
|
|
245
247
|
};
|
|
246
248
|
});
|
|
247
249
|
const sliceForAgentMentionSuppression = lastContentPasted === null || lastContentPasted === void 0 ? void 0 : lastContentPasted.sourcePastedSlice;
|
|
248
|
-
const shouldSuppressPasteActions = useMemo(() => shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression), [sliceForAgentMentionSuppression]);
|
|
250
|
+
const shouldSuppressPasteActions = useMemo(() => shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression) || shouldSuppressPasteActionsForSingleLink(sliceForAgentMentionSuppression), [sliceForAgentMentionSuppression]);
|
|
249
251
|
const prevShowToolbarRef = useRef(false);
|
|
250
252
|
const popupContentRef = useRef(null);
|
|
251
253
|
useEffect(() => {
|
|
@@ -36,34 +36,8 @@ const isParseableUrl = text => {
|
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
* Returns true if the slice represents a single smart-link card node.
|
|
42
|
-
* Handles two shapes:
|
|
43
|
-
* - paragraph > inlineCard|blockCard (smartlink from editor/renderer, wrapped in a paragraph)
|
|
44
|
-
* - inlineCard|blockCard (top-level card with no paragraph wrapper)
|
|
45
|
-
*/
|
|
46
|
-
const isSingleSmartLinkCard = slice => {
|
|
47
|
-
const isSupportedCard = node => node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
48
|
-
if (slice.content.childCount !== 1) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
const topNode = slice.content.child(0);
|
|
52
|
-
|
|
53
|
-
// Top-level inlineCard/blockCard (no paragraph wrapper)
|
|
54
|
-
if (isSupportedCard(topNode)) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// paragraph > inlineCard/blockCard
|
|
59
|
-
if (topNode.type.name !== 'paragraph') {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
if (topNode.childCount !== 1) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
return isSupportedCard(topNode.child(0));
|
|
66
|
-
};
|
|
39
|
+
const isSupportedCard = node => node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
40
|
+
const transparentSingleChildContainerNodeTypes = new Set(['paragraph', 'listItem', 'bulletList', 'orderedList']);
|
|
67
41
|
|
|
68
42
|
/**
|
|
69
43
|
* Returns the children of a Fragment, filtering out whitespace-only text nodes.
|
|
@@ -83,33 +57,29 @@ const significantChildren = fragment => {
|
|
|
83
57
|
};
|
|
84
58
|
|
|
85
59
|
/**
|
|
86
|
-
* Returns true
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* Whitespace-only sibling text nodes
|
|
60
|
+
* Returns true when the fragment contains exactly one meaningful leaf that
|
|
61
|
+
* satisfies `isSupportedLeaf`.
|
|
62
|
+
*
|
|
63
|
+
* Transparent single-child containers (paragraph, listItem, bulletList, and
|
|
64
|
+
* orderedList) are traversed recursively. Whitespace-only sibling text nodes
|
|
65
|
+
* are ignored at each level.
|
|
91
66
|
*/
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (significantTopChildren.length === 1 && isUrlOnlyLinkTextNode(significantTopChildren[0])) {
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// paragraph > text(link mark)
|
|
100
|
-
if (slice.content.childCount !== 1) {
|
|
67
|
+
const containsExactlyOneMeaningfulLeaf = (fragment, isSupportedLeaf) => {
|
|
68
|
+
const children = significantChildren(fragment);
|
|
69
|
+
if (children.length !== 1) {
|
|
101
70
|
return false;
|
|
102
71
|
}
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
return
|
|
72
|
+
const [child] = children;
|
|
73
|
+
if (isSupportedLeaf(child)) {
|
|
74
|
+
return true;
|
|
106
75
|
}
|
|
107
|
-
|
|
108
|
-
if (children.length !== 1) {
|
|
76
|
+
if (!transparentSingleChildContainerNodeTypes.has(child.type.name)) {
|
|
109
77
|
return false;
|
|
110
78
|
}
|
|
111
|
-
return
|
|
79
|
+
return containsExactlyOneMeaningfulLeaf(child.content, isSupportedLeaf);
|
|
112
80
|
};
|
|
81
|
+
const isSingleSmartLinkCard = slice => containsExactlyOneMeaningfulLeaf(slice.content, isSupportedCard);
|
|
82
|
+
const isSingleBareLink = slice => containsExactlyOneMeaningfulLeaf(slice.content, isUrlOnlyLinkTextNode);
|
|
113
83
|
|
|
114
84
|
/**
|
|
115
85
|
* Returns `true` when the pasted content is NOT a single standalone link.
|
|
@@ -15,6 +15,7 @@ import { hideToolbar, highlightContent, showToolbar } from '../../editor-command
|
|
|
15
15
|
import { PASTE_MENU_GAP_HORIZONTAL, PASTE_MENU_GAP_TOP } from '../../pm-plugins/constants';
|
|
16
16
|
import { ToolbarDropdownOption } from '../../types/types';
|
|
17
17
|
import { isToolbarVisible } from '../toolbar';
|
|
18
|
+
import { isNotSingleLink } from '../utils/paste-menu-rules/isNotSingleLink';
|
|
18
19
|
import { getVisibleKeys, hasVisibleButton } from './hasVisibleButton';
|
|
19
20
|
import { PasteActionsMenuContent } from './PasteActionsMenuContent';
|
|
20
21
|
var PopupWithListeners = withReactEditorViewOuterListeners(Popup);
|
|
@@ -40,6 +41,9 @@ export var containsAgentMention = function containsAgentMention(slice) {
|
|
|
40
41
|
export var shouldSuppressPasteActionsForAgentMention = function shouldSuppressPasteActionsForAgentMention(slice) {
|
|
41
42
|
return expVal('platform_editor_agent_mentions', 'isEnabled', false) && containsAgentMention(slice);
|
|
42
43
|
};
|
|
44
|
+
export var shouldSuppressPasteActionsForSingleLink = function shouldSuppressPasteActionsForSingleLink(slice) {
|
|
45
|
+
return expVal('platform_editor_fix_link_paste_menu', 'isEnabled', false) && !isNotSingleLink(slice !== null && slice !== void 0 ? slice : undefined);
|
|
46
|
+
};
|
|
43
47
|
/**
|
|
44
48
|
* Returns the DOM element at the given document position for use as a Popup anchor.
|
|
45
49
|
* For empty blocks (BR elements), returns the parent element to ensure correct positioning.
|
|
@@ -249,7 +253,7 @@ export var PasteActionsMenu = function PasteActionsMenu(_ref) {
|
|
|
249
253
|
lastContentPasted = _useSharedPluginState.lastContentPasted;
|
|
250
254
|
var sliceForAgentMentionSuppression = lastContentPasted === null || lastContentPasted === void 0 ? void 0 : lastContentPasted.sourcePastedSlice;
|
|
251
255
|
var shouldSuppressPasteActions = useMemo(function () {
|
|
252
|
-
return shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression);
|
|
256
|
+
return shouldSuppressPasteActionsForAgentMention(sliceForAgentMentionSuppression) || shouldSuppressPasteActionsForSingleLink(sliceForAgentMentionSuppression);
|
|
253
257
|
}, [sliceForAgentMentionSuppression]);
|
|
254
258
|
var prevShowToolbarRef = useRef(false);
|
|
255
259
|
var popupContentRef = useRef(null);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
/**
|
|
2
3
|
* Returns true if the given text node's sole mark is a `link` mark whose href
|
|
3
4
|
* matches the node's text content exactly (i.e. the link label IS the URL).
|
|
@@ -36,36 +37,10 @@ var isParseableUrl = function isParseableUrl(text) {
|
|
|
36
37
|
return false;
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
* Returns true if the slice represents a single smart-link card node.
|
|
42
|
-
* Handles two shapes:
|
|
43
|
-
* - paragraph > inlineCard|blockCard (smartlink from editor/renderer, wrapped in a paragraph)
|
|
44
|
-
* - inlineCard|blockCard (top-level card with no paragraph wrapper)
|
|
45
|
-
*/
|
|
46
|
-
var isSingleSmartLinkCard = function isSingleSmartLinkCard(slice) {
|
|
47
|
-
var isSupportedCard = function isSupportedCard(node) {
|
|
48
|
-
return node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
49
|
-
};
|
|
50
|
-
if (slice.content.childCount !== 1) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
var topNode = slice.content.child(0);
|
|
54
|
-
|
|
55
|
-
// Top-level inlineCard/blockCard (no paragraph wrapper)
|
|
56
|
-
if (isSupportedCard(topNode)) {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// paragraph > inlineCard/blockCard
|
|
61
|
-
if (topNode.type.name !== 'paragraph') {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
if (topNode.childCount !== 1) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
return isSupportedCard(topNode.child(0));
|
|
40
|
+
var isSupportedCard = function isSupportedCard(node) {
|
|
41
|
+
return node.type.name === 'inlineCard' || node.type.name === 'blockCard';
|
|
68
42
|
};
|
|
43
|
+
var transparentSingleChildContainerNodeTypes = new Set(['paragraph', 'listItem', 'bulletList', 'orderedList']);
|
|
69
44
|
|
|
70
45
|
/**
|
|
71
46
|
* Returns the children of a Fragment, filtering out whitespace-only text nodes.
|
|
@@ -85,32 +60,33 @@ var significantChildren = function significantChildren(fragment) {
|
|
|
85
60
|
};
|
|
86
61
|
|
|
87
62
|
/**
|
|
88
|
-
* Returns true
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* Whitespace-only sibling text nodes
|
|
63
|
+
* Returns true when the fragment contains exactly one meaningful leaf that
|
|
64
|
+
* satisfies `isSupportedLeaf`.
|
|
65
|
+
*
|
|
66
|
+
* Transparent single-child containers (paragraph, listItem, bulletList, and
|
|
67
|
+
* orderedList) are traversed recursively. Whitespace-only sibling text nodes
|
|
68
|
+
* are ignored at each level.
|
|
93
69
|
*/
|
|
94
|
-
var
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (significantTopChildren.length === 1 && isUrlOnlyLinkTextNode(significantTopChildren[0])) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// paragraph > text(link mark)
|
|
102
|
-
if (slice.content.childCount !== 1) {
|
|
70
|
+
var _containsExactlyOneMeaningfulLeaf = function containsExactlyOneMeaningfulLeaf(fragment, isSupportedLeaf) {
|
|
71
|
+
var children = significantChildren(fragment);
|
|
72
|
+
if (children.length !== 1) {
|
|
103
73
|
return false;
|
|
104
74
|
}
|
|
105
|
-
var
|
|
106
|
-
|
|
107
|
-
|
|
75
|
+
var _children = _slicedToArray(children, 1),
|
|
76
|
+
child = _children[0];
|
|
77
|
+
if (isSupportedLeaf(child)) {
|
|
78
|
+
return true;
|
|
108
79
|
}
|
|
109
|
-
|
|
110
|
-
if (children.length !== 1) {
|
|
80
|
+
if (!transparentSingleChildContainerNodeTypes.has(child.type.name)) {
|
|
111
81
|
return false;
|
|
112
82
|
}
|
|
113
|
-
return
|
|
83
|
+
return _containsExactlyOneMeaningfulLeaf(child.content, isSupportedLeaf);
|
|
84
|
+
};
|
|
85
|
+
var isSingleSmartLinkCard = function isSingleSmartLinkCard(slice) {
|
|
86
|
+
return _containsExactlyOneMeaningfulLeaf(slice.content, isSupportedCard);
|
|
87
|
+
};
|
|
88
|
+
var isSingleBareLink = function isSingleBareLink(slice) {
|
|
89
|
+
return _containsExactlyOneMeaningfulLeaf(slice.content, isUrlOnlyLinkTextNode);
|
|
114
90
|
};
|
|
115
91
|
|
|
116
92
|
/**
|
|
@@ -8,6 +8,7 @@ import type { PasteOptionsToolbarPlugin } from '../../pasteOptionsToolbarPluginT
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const containsAgentMention: (slice?: Slice | null) => boolean;
|
|
10
10
|
export declare const shouldSuppressPasteActionsForAgentMention: (slice?: Slice | null) => boolean;
|
|
11
|
+
export declare const shouldSuppressPasteActionsForSingleLink: (slice?: Slice | null) => boolean;
|
|
11
12
|
interface PasteActionsMenuProps {
|
|
12
13
|
api: ExtractInjectionAPI<PasteOptionsToolbarPlugin> | undefined;
|
|
13
14
|
boundariesElement?: HTMLElement;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-paste-options-toolbar",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.18",
|
|
4
4
|
"description": "Paste options toolbar for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@atlaskit/icon": "^36.1.0",
|
|
35
35
|
"@atlaskit/platform-feature-flags": "^2.0.0",
|
|
36
36
|
"@atlaskit/primitives": "^20.3.0",
|
|
37
|
-
"@atlaskit/tmp-editor-statsig": "^119.
|
|
37
|
+
"@atlaskit/tmp-editor-statsig": "^119.1.0",
|
|
38
38
|
"@atlaskit/tokens": "^15.3.0",
|
|
39
39
|
"@babel/runtime": "^7.0.0",
|
|
40
40
|
"@compiled/react": "^0.20.0",
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
"platform_editor_agent_mentions": {
|
|
58
58
|
"type": "experiment"
|
|
59
59
|
},
|
|
60
|
+
"platform_editor_fix_link_paste_menu": {
|
|
61
|
+
"type": "experiment"
|
|
62
|
+
},
|
|
60
63
|
"platform_editor_paste_actions_menu_exposure": {
|
|
61
64
|
"type": "boolean"
|
|
62
65
|
},
|