@atlaskit/editor-plugin-card 17.4.1 → 17.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/cjs/nodeviews/inlineCard.js +3 -3
- package/dist/cjs/nodeviews/inlineCardWithAwareness.js +5 -1
- package/dist/cjs/ui/InlineCardOverlay/index.js +5 -1
- package/dist/cjs/ui/OpenLinkToolbarButton/index.js +45 -0
- package/dist/cjs/ui/toolbar.js +32 -3
- package/dist/es2019/nodeviews/inlineCard.js +3 -3
- package/dist/es2019/nodeviews/inlineCardWithAwareness.js +5 -1
- package/dist/es2019/ui/InlineCardOverlay/index.js +5 -1
- package/dist/es2019/ui/OpenLinkToolbarButton/index.js +37 -0
- package/dist/es2019/ui/toolbar.js +30 -3
- package/dist/esm/nodeviews/inlineCard.js +3 -3
- package/dist/esm/nodeviews/inlineCardWithAwareness.js +5 -1
- package/dist/esm/ui/InlineCardOverlay/index.js +5 -1
- package/dist/esm/ui/OpenLinkToolbarButton/index.js +36 -0
- package/dist/esm/ui/toolbar.js +32 -3
- package/dist/types/ui/OpenLinkToolbarButton/index.d.ts +20 -0
- package/dist/types-ts4.5/ui/OpenLinkToolbarButton/index.d.ts +20 -0
- package/package.json +8 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-card
|
|
2
2
|
|
|
3
|
+
## 17.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 17.4.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`92da883bae00d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/92da883bae00d) -
|
|
14
|
+
Use XPC-wrapped destination URL for link navigation behind `platform_smartlink_xpc_url_wrapping`.
|
|
15
|
+
|
|
16
|
+
When the feature gate is enabled, the following link-opening locations now use the cross-product
|
|
17
|
+
analytics parameter-enriched URL provided by SmartCard instead of the raw node URL:
|
|
18
|
+
- **Toolbar "Open Link" button** (both smart card and datasource paths) — uses the new
|
|
19
|
+
`useSmartLinkDestinationUrl` hook from
|
|
20
|
+
`@atlaskit/smart-card/hook/use-smart-link-destination-url` via a new `OpenLinkToolbarButton`
|
|
21
|
+
custom toolbar component.
|
|
22
|
+
- **Inline card overlay anchor** (`InlineCardOverlay`) — `href` updated to use
|
|
23
|
+
`useSmartLinkDestinationUrl`.
|
|
24
|
+
- **Hover link overlay** (`HoverLinkOverlay`) — accepts a new optional `destinationUrl` prop; when
|
|
25
|
+
provided and the gate is on, uses it for both the anchor `href` and double-click `window.open`.
|
|
26
|
+
The `destinationUrl` is computed by `inlineCardWithAwareness` using `useSmartLinkDestinationUrl`
|
|
27
|
+
and passed down — keeping `editor-common` free of any SmartCard provider dependency.
|
|
28
|
+
- **Inline card Cmd/Ctrl+click** — reads `data.destinationUrl` from SmartCard's `onClick` callback
|
|
29
|
+
(typed as `OnClickCallback` from `@atlaskit/smart-card/card/types`).
|
|
30
|
+
|
|
31
|
+
All changes gracefully fall back to the raw URL when the gate is off or the link has not yet
|
|
32
|
+
resolved.
|
|
33
|
+
|
|
34
|
+
- Updated dependencies
|
|
35
|
+
|
|
3
36
|
## 17.4.1
|
|
4
37
|
|
|
5
38
|
### Patch Changes
|
|
@@ -112,13 +112,13 @@ var InlineCard = exports.InlineCard = /*#__PURE__*/(0, _react.memo)(function (_r
|
|
|
112
112
|
url: url
|
|
113
113
|
});
|
|
114
114
|
}, [onResolve]);
|
|
115
|
-
var handleOnClick = (0, _react.useCallback)(function (event) {
|
|
115
|
+
var handleOnClick = (0, _react.useCallback)(function (event, data) {
|
|
116
116
|
if (event.metaKey || event.ctrlKey) {
|
|
117
|
-
var _pluginInjectionApi$a;
|
|
117
|
+
var _pluginInjectionApi$a, _data$destinationUrl;
|
|
118
118
|
var _ref3 = (_pluginInjectionApi$a = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.analytics) !== null && _pluginInjectionApi$a !== void 0 ? _pluginInjectionApi$a : {},
|
|
119
119
|
editorAnalyticsApi = _ref3.actions;
|
|
120
120
|
(0, _toolbar.visitCardLinkAnalytics)(editorAnalyticsApi, _analytics.INPUT_METHOD.META_CLICK)(view.state, view.dispatch);
|
|
121
|
-
window.open(url, '_blank');
|
|
121
|
+
window.open((0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping') ? (_data$destinationUrl = data === null || data === void 0 ? void 0 : data.destinationUrl) !== null && _data$destinationUrl !== void 0 ? _data$destinationUrl : url : url, '_blank');
|
|
122
122
|
} else {
|
|
123
123
|
// only trigger the provided onClick callback if the meta key or ctrl key is not pressed
|
|
124
124
|
propsOnClick === null || propsOnClick === void 0 || propsOnClick(event);
|
|
@@ -15,6 +15,7 @@ var _state = require("@atlaskit/editor-prosemirror/state");
|
|
|
15
15
|
var _linkExtractors = require("@atlaskit/link-extractors");
|
|
16
16
|
var _utils = require("@atlaskit/linking-common/utils");
|
|
17
17
|
var _smartCard = require("@atlaskit/smart-card");
|
|
18
|
+
var _useSmartLinkDestinationUrl = require("@atlaskit/smart-card/hook/use-smart-link-destination-url");
|
|
18
19
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
19
20
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
20
21
|
var _actions = require("../pm-plugins/actions");
|
|
@@ -59,6 +60,7 @@ var InlineCardWithAwareness = exports.InlineCardWithAwareness = /*#__PURE__*/(0,
|
|
|
59
60
|
isResolvedViewRendered = _useState6[0],
|
|
60
61
|
setIsResolvedViewRendered = _useState6[1];
|
|
61
62
|
var editorAppearance = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card.sharedState.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.editorAppearance;
|
|
63
|
+
var destinationUrl = (0, _useSmartLinkDestinationUrl.useSmartLinkDestinationUrl)(node.attrs.url);
|
|
62
64
|
var onResolve = (0, _react.useCallback)(function (tr, title) {
|
|
63
65
|
var metadata = tr.getMeta(_pluginKey.pluginKey);
|
|
64
66
|
if (metadata && metadata.type === 'REGISTER') {
|
|
@@ -97,6 +99,7 @@ var InlineCardWithAwareness = exports.InlineCardWithAwareness = /*#__PURE__*/(0,
|
|
|
97
99
|
return /*#__PURE__*/_react.default.createElement(_ui.HoverLinkOverlay, {
|
|
98
100
|
isVisible: isResolvedViewRendered,
|
|
99
101
|
url: node.attrs.url,
|
|
102
|
+
destinationUrl: destinationUrl,
|
|
100
103
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
101
104
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions,
|
|
102
105
|
view: view
|
|
@@ -115,7 +118,7 @@ var InlineCardWithAwareness = exports.InlineCardWithAwareness = /*#__PURE__*/(0,
|
|
|
115
118
|
pluginInjectionApi: pluginInjectionApi,
|
|
116
119
|
disablePreviewPanel: true
|
|
117
120
|
}));
|
|
118
|
-
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi]);
|
|
121
|
+
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi, destinationUrl]);
|
|
119
122
|
var innerCardOriginal = (0, _react.useMemo)(function () {
|
|
120
123
|
return /*#__PURE__*/_react.default.createElement(_inlineCard.InlineCard, {
|
|
121
124
|
node: node,
|
|
@@ -194,6 +197,7 @@ var InlineCardWithAwareness = exports.InlineCardWithAwareness = /*#__PURE__*/(0,
|
|
|
194
197
|
return /*#__PURE__*/_react.default.createElement(_ui.HoverLinkOverlay, {
|
|
195
198
|
isVisible: isResolvedViewRendered,
|
|
196
199
|
url: url,
|
|
200
|
+
destinationUrl: destinationUrl,
|
|
197
201
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
198
202
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions,
|
|
199
203
|
view: view,
|
|
@@ -17,6 +17,8 @@ var _reactIntl = require("react-intl");
|
|
|
17
17
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
18
18
|
var _whitespace = require("@atlaskit/editor-common/whitespace");
|
|
19
19
|
var _customize = _interopRequireDefault(require("@atlaskit/icon/core/customize"));
|
|
20
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
21
|
+
var _useSmartLinkDestinationUrl = require("@atlaskit/smart-card/hook/use-smart-link-destination-url");
|
|
20
22
|
var _utils = require("./utils");
|
|
21
23
|
var _excluded = ["children", "isSelected", "isVisible", "testId", "url"];
|
|
22
24
|
/* eslint-disable @atlaskit/design-system/no-nested-styles */
|
|
@@ -111,6 +113,7 @@ var gradientStyles = (0, _react2.css)({
|
|
|
111
113
|
background: getGradientWithColor(SMART_LINK_BACKGROUND_COLOR)
|
|
112
114
|
});
|
|
113
115
|
var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
116
|
+
var _useSmartLinkDestinat;
|
|
114
117
|
var children = _ref.children,
|
|
115
118
|
_ref$isSelected = _ref.isSelected,
|
|
116
119
|
isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
|
|
@@ -221,6 +224,7 @@ var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
|
221
224
|
observer.disconnect();
|
|
222
225
|
};
|
|
223
226
|
}, [isVisible, setVisibility]);
|
|
227
|
+
var destinationUrl = (_useSmartLinkDestinat = (0, _useSmartLinkDestinationUrl.useSmartLinkDestinationUrl)(url)) !== null && _useSmartLinkDestinat !== void 0 ? _useSmartLinkDestinat : url;
|
|
224
228
|
var intl = (0, _reactIntl.useIntl)();
|
|
225
229
|
var label = intl.formatMessage(_messages.cardMessages.inlineOverlay);
|
|
226
230
|
return (
|
|
@@ -240,7 +244,7 @@ var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
|
240
244
|
width: availableWidth
|
|
241
245
|
},
|
|
242
246
|
"data-testid": testId,
|
|
243
|
-
href: url,
|
|
247
|
+
href: (0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping') ? destinationUrl : url,
|
|
244
248
|
onClick: function onClick(e) {
|
|
245
249
|
return e.preventDefault();
|
|
246
250
|
},
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.OpenLinkToolbarButton = void 0;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _ui = require("@atlaskit/editor-common/ui");
|
|
11
|
+
var _linkExternal = _interopRequireDefault(require("@atlaskit/icon/core/link-external"));
|
|
12
|
+
var _useSmartLinkDestinationUrl = require("@atlaskit/smart-card/hook/use-smart-link-destination-url");
|
|
13
|
+
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); }
|
|
14
|
+
/**
|
|
15
|
+
* Toolbar button that opens a Smart Link URL in a new tab, with the XPC-wrapped destination URL.
|
|
16
|
+
*
|
|
17
|
+
* This component is only rendered when `fg('platform_smartlink_xpc_url_wrapping')` is ON.
|
|
18
|
+
* It wraps `FloatingToolbarButton` and replaces `href` with the resolved destination URL
|
|
19
|
+
* (cross-product analytics parameters appended), falling back to the raw `url` when the
|
|
20
|
+
* link is unresolved or not a first-party Atlassian link.
|
|
21
|
+
*/
|
|
22
|
+
var OpenLinkToolbarButton = exports.OpenLinkToolbarButton = function OpenLinkToolbarButton(_ref) {
|
|
23
|
+
var url = _ref.url,
|
|
24
|
+
areAnyNewToolbarFlagsEnabled = _ref.areAnyNewToolbarFlagsEnabled,
|
|
25
|
+
editorView = _ref.editorView,
|
|
26
|
+
onClick = _ref.onClick,
|
|
27
|
+
title = _ref.title;
|
|
28
|
+
var destinationUrl = (0, _useSmartLinkDestinationUrl.useSmartLinkDestinationUrl)(url);
|
|
29
|
+
var handleClick = (0, _react.useCallback)(function () {
|
|
30
|
+
onClick(editorView.state, editorView.dispatch);
|
|
31
|
+
}, [editorView, onClick]);
|
|
32
|
+
return /*#__PURE__*/_react.default.createElement(_ui.FloatingToolbarButton
|
|
33
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
34
|
+
, {
|
|
35
|
+
className: "hyperlink-open-link",
|
|
36
|
+
title: title,
|
|
37
|
+
icon: /*#__PURE__*/_react.default.createElement(_linkExternal.default, {
|
|
38
|
+
label: ""
|
|
39
|
+
}),
|
|
40
|
+
href: destinationUrl,
|
|
41
|
+
target: "_blank",
|
|
42
|
+
onClick: handleClick,
|
|
43
|
+
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
|
|
44
|
+
});
|
|
45
|
+
};
|
package/dist/cjs/ui/toolbar.js
CHANGED
|
@@ -28,6 +28,7 @@ var _edit = _interopRequireDefault(require("@atlaskit/icon/core/edit"));
|
|
|
28
28
|
var _linkBroken = _interopRequireDefault(require("@atlaskit/icon/core/link-broken"));
|
|
29
29
|
var _linkExternal = _interopRequireDefault(require("@atlaskit/icon/core/link-external"));
|
|
30
30
|
var _settings = _interopRequireDefault(require("@atlaskit/icon/core/settings"));
|
|
31
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
31
32
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
32
33
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
33
34
|
var _doc = require("../pm-plugins/doc");
|
|
@@ -40,6 +41,7 @@ var _HyperlinkToolbarAppearance = require("./HyperlinkToolbarAppearance");
|
|
|
40
41
|
var _HyperlinkToolbarAppearanceDropdown = require("./HyperlinkToolbarAppearanceDropdown");
|
|
41
42
|
var _LinkToolbarAppearance = require("./LinkToolbarAppearance");
|
|
42
43
|
var _LinkToolbarAppearanceDropdown = require("./LinkToolbarAppearanceDropdown");
|
|
44
|
+
var _OpenLinkToolbarButton = require("./OpenLinkToolbarButton");
|
|
43
45
|
var _OpenPreviewButton = require("./OpenPreviewButton");
|
|
44
46
|
var _ToolbarViewedEvent = require("./ToolbarViewedEvent");
|
|
45
47
|
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); }
|
|
@@ -370,7 +372,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
|
|
|
370
372
|
}
|
|
371
373
|
}] : [];
|
|
372
374
|
var resolvedToolbarAttributes = url ? (_pluginState$resolved = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[url]) !== null && _pluginState$resolved !== void 0 ? _pluginState$resolved : {} : {};
|
|
373
|
-
var
|
|
375
|
+
var openLinkToolbarItemFallback = {
|
|
374
376
|
id: 'editor.link.openLink',
|
|
375
377
|
type: 'button',
|
|
376
378
|
icon: _linkExternal.default,
|
|
@@ -382,6 +384,19 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
|
|
|
382
384
|
href: url,
|
|
383
385
|
target: '_blank'
|
|
384
386
|
};
|
|
387
|
+
var openLinkToolbarItem = (0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping') ? {
|
|
388
|
+
type: 'custom',
|
|
389
|
+
fallback: [openLinkToolbarItemFallback],
|
|
390
|
+
render: function render(editorView) {
|
|
391
|
+
return editorView && url ? /*#__PURE__*/_react.default.createElement(_OpenLinkToolbarButton.OpenLinkToolbarButton, {
|
|
392
|
+
url: url,
|
|
393
|
+
title: intl.formatMessage(_messages.linkMessages.openLink),
|
|
394
|
+
editorView: editorView,
|
|
395
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, resolvedToolbarAttributes),
|
|
396
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
397
|
+
}) : null;
|
|
398
|
+
}
|
|
399
|
+
} : openLinkToolbarItemFallback;
|
|
385
400
|
var toolbarItems = areAllNewToolbarFlagsDisabled ? [].concat(editItems, commentItems, openPreviewPanelItems, [openLinkToolbarItem, {
|
|
386
401
|
type: 'separator'
|
|
387
402
|
}], (0, _toConsumableArray2.default)(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled)), [{
|
|
@@ -646,7 +661,7 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
|
|
|
646
661
|
});
|
|
647
662
|
if (node !== null && node !== void 0 && (_node$attrs3 = node.attrs) !== null && _node$attrs3 !== void 0 && _node$attrs3.url) {
|
|
648
663
|
var _pluginState$resolved2;
|
|
649
|
-
|
|
664
|
+
var openLinkToolbarItemFallback = {
|
|
650
665
|
id: 'editor.link.openLink',
|
|
651
666
|
type: 'button',
|
|
652
667
|
icon: _linkExternal.default,
|
|
@@ -657,7 +672,21 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
|
|
|
657
672
|
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved2 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved2 !== void 0 ? _pluginState$resolved2 : {}),
|
|
658
673
|
href: node.attrs.url,
|
|
659
674
|
target: '_blank'
|
|
660
|
-
}
|
|
675
|
+
};
|
|
676
|
+
toolbarItems.push((0, _platformFeatureFlags.fg)('platform_smartlink_xpc_url_wrapping') ? {
|
|
677
|
+
type: 'custom',
|
|
678
|
+
fallback: [openLinkToolbarItemFallback],
|
|
679
|
+
render: function render(editorView) {
|
|
680
|
+
var _pluginState$resolved3;
|
|
681
|
+
return editorView ? /*#__PURE__*/_react.default.createElement(_OpenLinkToolbarButton.OpenLinkToolbarButton, {
|
|
682
|
+
url: node.attrs.url,
|
|
683
|
+
title: intl.formatMessage(_messages.linkMessages.openLink),
|
|
684
|
+
editorView: editorView,
|
|
685
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved3 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved3 !== void 0 ? _pluginState$resolved3 : {}),
|
|
686
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
687
|
+
}) : null;
|
|
688
|
+
}
|
|
689
|
+
} : openLinkToolbarItemFallback);
|
|
661
690
|
if (areAllNewToolbarFlagsDisabled) {
|
|
662
691
|
toolbarItems.push({
|
|
663
692
|
type: 'separator'
|
|
@@ -107,14 +107,14 @@ export const InlineCard = /*#__PURE__*/memo(({
|
|
|
107
107
|
url
|
|
108
108
|
});
|
|
109
109
|
}, [onResolve]);
|
|
110
|
-
const handleOnClick = useCallback(event => {
|
|
110
|
+
const handleOnClick = useCallback((event, data) => {
|
|
111
111
|
if (event.metaKey || event.ctrlKey) {
|
|
112
|
-
var _pluginInjectionApi$a;
|
|
112
|
+
var _pluginInjectionApi$a, _data$destinationUrl;
|
|
113
113
|
const {
|
|
114
114
|
actions: editorAnalyticsApi
|
|
115
115
|
} = (_pluginInjectionApi$a = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.analytics) !== null && _pluginInjectionApi$a !== void 0 ? _pluginInjectionApi$a : {};
|
|
116
116
|
visitCardLinkAnalytics(editorAnalyticsApi, INPUT_METHOD.META_CLICK)(view.state, view.dispatch);
|
|
117
|
-
window.open(url, '_blank');
|
|
117
|
+
window.open(fg('platform_smartlink_xpc_url_wrapping') ? (_data$destinationUrl = data === null || data === void 0 ? void 0 : data.destinationUrl) !== null && _data$destinationUrl !== void 0 ? _data$destinationUrl : url : url, '_blank');
|
|
118
118
|
} else {
|
|
119
119
|
// only trigger the provided onClick callback if the meta key or ctrl key is not pressed
|
|
120
120
|
propsOnClick === null || propsOnClick === void 0 ? void 0 : propsOnClick(event);
|
|
@@ -6,6 +6,7 @@ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
|
6
6
|
import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
|
|
7
7
|
import { isWithinPreviewPanelIFrame } from '@atlaskit/linking-common/utils';
|
|
8
8
|
import { getObjectAri, getObjectName, getObjectIconUrl } from '@atlaskit/smart-card';
|
|
9
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
9
10
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
10
11
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
11
12
|
import { registerRemoveOverlay } from '../pm-plugins/actions';
|
|
@@ -41,6 +42,7 @@ export const InlineCardWithAwareness = /*#__PURE__*/memo(({
|
|
|
41
42
|
const [isInserted, setIsInserted] = useState(false);
|
|
42
43
|
const [isResolvedViewRendered, setIsResolvedViewRendered] = useState(false);
|
|
43
44
|
const editorAppearance = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.card.sharedState.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.editorAppearance;
|
|
45
|
+
const destinationUrl = useSmartLinkDestinationUrl(node.attrs.url);
|
|
44
46
|
const onResolve = useCallback((tr, title) => {
|
|
45
47
|
const metadata = tr.getMeta(pluginKey);
|
|
46
48
|
if (metadata && metadata.type === 'REGISTER') {
|
|
@@ -76,6 +78,7 @@ export const InlineCardWithAwareness = /*#__PURE__*/memo(({
|
|
|
76
78
|
return /*#__PURE__*/React.createElement(HoverLinkOverlay, {
|
|
77
79
|
isVisible: isResolvedViewRendered,
|
|
78
80
|
url: node.attrs.url,
|
|
81
|
+
destinationUrl: destinationUrl,
|
|
79
82
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
80
83
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions,
|
|
81
84
|
view: view
|
|
@@ -94,7 +97,7 @@ export const InlineCardWithAwareness = /*#__PURE__*/memo(({
|
|
|
94
97
|
pluginInjectionApi: pluginInjectionApi,
|
|
95
98
|
disablePreviewPanel: true
|
|
96
99
|
}));
|
|
97
|
-
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi]);
|
|
100
|
+
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi, destinationUrl]);
|
|
98
101
|
const innerCardOriginal = useMemo(() => /*#__PURE__*/React.createElement(InlineCard, {
|
|
99
102
|
node: node,
|
|
100
103
|
view: view,
|
|
@@ -173,6 +176,7 @@ export const InlineCardWithAwareness = /*#__PURE__*/memo(({
|
|
|
173
176
|
return /*#__PURE__*/React.createElement(HoverLinkOverlay, {
|
|
174
177
|
isVisible: isResolvedViewRendered,
|
|
175
178
|
url: url,
|
|
179
|
+
destinationUrl: destinationUrl,
|
|
176
180
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
177
181
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a5 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a5 === void 0 ? void 0 : _pluginInjectionApi$a5.actions,
|
|
178
182
|
view: view,
|
|
@@ -14,6 +14,8 @@ import { useIntl } from 'react-intl';
|
|
|
14
14
|
import { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
15
15
|
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
|
|
16
16
|
import CustomizeIcon from '@atlaskit/icon/core/customize';
|
|
17
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
18
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
17
19
|
import { getChildElement, getInlineCardAvailableWidth, getOverlayWidths, isOneLine } from './utils';
|
|
18
20
|
const DEBOUNCE_IN_MS = 5;
|
|
19
21
|
const ESTIMATED_MIN_WIDTH_IN_PX = 16;
|
|
@@ -111,6 +113,7 @@ const InlineCardOverlay = ({
|
|
|
111
113
|
url,
|
|
112
114
|
...props
|
|
113
115
|
}) => {
|
|
116
|
+
var _useSmartLinkDestinat;
|
|
114
117
|
const [showOverlay, setShowOverlay] = useState(false);
|
|
115
118
|
const [showLabel, setShowLabel] = useState(true);
|
|
116
119
|
const [availableWidth, setAvailableWidth] = useState(undefined);
|
|
@@ -204,6 +207,7 @@ const InlineCardOverlay = ({
|
|
|
204
207
|
observer.disconnect();
|
|
205
208
|
};
|
|
206
209
|
}, [isVisible, setVisibility]);
|
|
210
|
+
const destinationUrl = (_useSmartLinkDestinat = useSmartLinkDestinationUrl(url)) !== null && _useSmartLinkDestinat !== void 0 ? _useSmartLinkDestinat : url;
|
|
207
211
|
const intl = useIntl();
|
|
208
212
|
const label = intl.formatMessage(messages.inlineOverlay);
|
|
209
213
|
return (
|
|
@@ -223,7 +227,7 @@ const InlineCardOverlay = ({
|
|
|
223
227
|
width: availableWidth
|
|
224
228
|
},
|
|
225
229
|
"data-testid": testId,
|
|
226
|
-
href: url,
|
|
230
|
+
href: fg('platform_smartlink_xpc_url_wrapping') ? destinationUrl : url,
|
|
227
231
|
onClick: e => e.preventDefault(),
|
|
228
232
|
tabIndex: -1
|
|
229
233
|
}, jsx("span", {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
|
|
3
|
+
import LinkExternalIcon from '@atlaskit/icon/core/link-external';
|
|
4
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
5
|
+
/**
|
|
6
|
+
* Toolbar button that opens a Smart Link URL in a new tab, with the XPC-wrapped destination URL.
|
|
7
|
+
*
|
|
8
|
+
* This component is only rendered when `fg('platform_smartlink_xpc_url_wrapping')` is ON.
|
|
9
|
+
* It wraps `FloatingToolbarButton` and replaces `href` with the resolved destination URL
|
|
10
|
+
* (cross-product analytics parameters appended), falling back to the raw `url` when the
|
|
11
|
+
* link is unresolved or not a first-party Atlassian link.
|
|
12
|
+
*/
|
|
13
|
+
export const OpenLinkToolbarButton = ({
|
|
14
|
+
url,
|
|
15
|
+
areAnyNewToolbarFlagsEnabled,
|
|
16
|
+
editorView,
|
|
17
|
+
onClick,
|
|
18
|
+
title
|
|
19
|
+
}) => {
|
|
20
|
+
const destinationUrl = useSmartLinkDestinationUrl(url);
|
|
21
|
+
const handleClick = useCallback(() => {
|
|
22
|
+
onClick(editorView.state, editorView.dispatch);
|
|
23
|
+
}, [editorView, onClick]);
|
|
24
|
+
return /*#__PURE__*/React.createElement(Button
|
|
25
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
26
|
+
, {
|
|
27
|
+
className: "hyperlink-open-link",
|
|
28
|
+
title: title,
|
|
29
|
+
icon: /*#__PURE__*/React.createElement(LinkExternalIcon, {
|
|
30
|
+
label: ""
|
|
31
|
+
}),
|
|
32
|
+
href: destinationUrl,
|
|
33
|
+
target: "_blank",
|
|
34
|
+
onClick: handleClick,
|
|
35
|
+
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
|
|
36
|
+
});
|
|
37
|
+
};
|
|
@@ -18,6 +18,7 @@ import EditIcon from '@atlaskit/icon/core/edit';
|
|
|
18
18
|
import LinkBrokenIcon from '@atlaskit/icon/core/link-broken';
|
|
19
19
|
import LinkExternalIcon from '@atlaskit/icon/core/link-external';
|
|
20
20
|
import CogIcon from '@atlaskit/icon/core/settings';
|
|
21
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
21
22
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
22
23
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
23
24
|
import { changeSelectedCardToText } from '../pm-plugins/doc';
|
|
@@ -30,6 +31,7 @@ import { HyperlinkToolbarAppearance } from './HyperlinkToolbarAppearance';
|
|
|
30
31
|
import { getCustomHyperlinkAppearanceDropdown } from './HyperlinkToolbarAppearanceDropdown';
|
|
31
32
|
import { LinkToolbarAppearance } from './LinkToolbarAppearance';
|
|
32
33
|
import { getLinkAppearanceDropdown } from './LinkToolbarAppearanceDropdown';
|
|
34
|
+
import { OpenLinkToolbarButton } from './OpenLinkToolbarButton';
|
|
33
35
|
import { OpenPreviewPanelToolbarButton } from './OpenPreviewButton';
|
|
34
36
|
import { ToolbarViewedEvent } from './ToolbarViewedEvent';
|
|
35
37
|
export const removeCard = editorAnalyticsApi => commandWithMetadata((state, dispatch) => {
|
|
@@ -355,7 +357,7 @@ const generateToolbarItems = (state, intl, providerFactory, cardOptions, lpLinkP
|
|
|
355
357
|
})
|
|
356
358
|
}] : [];
|
|
357
359
|
const resolvedToolbarAttributes = url ? (_pluginState$resolved = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[url]) !== null && _pluginState$resolved !== void 0 ? _pluginState$resolved : {} : {};
|
|
358
|
-
const
|
|
360
|
+
const openLinkToolbarItemFallback = {
|
|
359
361
|
id: 'editor.link.openLink',
|
|
360
362
|
type: 'button',
|
|
361
363
|
icon: LinkExternalIcon,
|
|
@@ -367,6 +369,17 @@ const generateToolbarItems = (state, intl, providerFactory, cardOptions, lpLinkP
|
|
|
367
369
|
href: url,
|
|
368
370
|
target: '_blank'
|
|
369
371
|
};
|
|
372
|
+
const openLinkToolbarItem = fg('platform_smartlink_xpc_url_wrapping') ? {
|
|
373
|
+
type: 'custom',
|
|
374
|
+
fallback: [openLinkToolbarItemFallback],
|
|
375
|
+
render: editorView => editorView && url ? /*#__PURE__*/React.createElement(OpenLinkToolbarButton, {
|
|
376
|
+
url: url,
|
|
377
|
+
title: intl.formatMessage(linkMessages.openLink),
|
|
378
|
+
editorView: editorView,
|
|
379
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, resolvedToolbarAttributes),
|
|
380
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
381
|
+
}) : null
|
|
382
|
+
} : openLinkToolbarItemFallback;
|
|
370
383
|
const toolbarItems = areAllNewToolbarFlagsDisabled ? [...editItems, ...commentItems, ...openPreviewPanelItems, openLinkToolbarItem, {
|
|
371
384
|
type: 'separator'
|
|
372
385
|
}, ...getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled), {
|
|
@@ -628,7 +641,7 @@ const getDatasourceButtonGroup = (metadata, intl, editorAnalyticsApi, node, hove
|
|
|
628
641
|
});
|
|
629
642
|
if (node !== null && node !== void 0 && (_node$attrs3 = node.attrs) !== null && _node$attrs3 !== void 0 && _node$attrs3.url) {
|
|
630
643
|
var _pluginState$resolved2;
|
|
631
|
-
|
|
644
|
+
const openLinkToolbarItemFallback = {
|
|
632
645
|
id: 'editor.link.openLink',
|
|
633
646
|
type: 'button',
|
|
634
647
|
icon: LinkExternalIcon,
|
|
@@ -639,7 +652,21 @@ const getDatasourceButtonGroup = (metadata, intl, editorAnalyticsApi, node, hove
|
|
|
639
652
|
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved2 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved2 !== void 0 ? _pluginState$resolved2 : {}),
|
|
640
653
|
href: node.attrs.url,
|
|
641
654
|
target: '_blank'
|
|
642
|
-
}
|
|
655
|
+
};
|
|
656
|
+
toolbarItems.push(fg('platform_smartlink_xpc_url_wrapping') ? {
|
|
657
|
+
type: 'custom',
|
|
658
|
+
fallback: [openLinkToolbarItemFallback],
|
|
659
|
+
render: editorView => {
|
|
660
|
+
var _pluginState$resolved3;
|
|
661
|
+
return editorView ? /*#__PURE__*/React.createElement(OpenLinkToolbarButton, {
|
|
662
|
+
url: node.attrs.url,
|
|
663
|
+
title: intl.formatMessage(linkMessages.openLink),
|
|
664
|
+
editorView: editorView,
|
|
665
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved3 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved3 !== void 0 ? _pluginState$resolved3 : {}),
|
|
666
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
667
|
+
}) : null;
|
|
668
|
+
}
|
|
669
|
+
} : openLinkToolbarItemFallback);
|
|
643
670
|
if (areAllNewToolbarFlagsDisabled) {
|
|
644
671
|
toolbarItems.push({
|
|
645
672
|
type: 'separator'
|
|
@@ -100,13 +100,13 @@ export var InlineCard = /*#__PURE__*/memo(function (_ref) {
|
|
|
100
100
|
url: url
|
|
101
101
|
});
|
|
102
102
|
}, [onResolve]);
|
|
103
|
-
var handleOnClick = useCallback(function (event) {
|
|
103
|
+
var handleOnClick = useCallback(function (event, data) {
|
|
104
104
|
if (event.metaKey || event.ctrlKey) {
|
|
105
|
-
var _pluginInjectionApi$a;
|
|
105
|
+
var _pluginInjectionApi$a, _data$destinationUrl;
|
|
106
106
|
var _ref3 = (_pluginInjectionApi$a = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.analytics) !== null && _pluginInjectionApi$a !== void 0 ? _pluginInjectionApi$a : {},
|
|
107
107
|
editorAnalyticsApi = _ref3.actions;
|
|
108
108
|
visitCardLinkAnalytics(editorAnalyticsApi, INPUT_METHOD.META_CLICK)(view.state, view.dispatch);
|
|
109
|
-
window.open(url, '_blank');
|
|
109
|
+
window.open(fg('platform_smartlink_xpc_url_wrapping') ? (_data$destinationUrl = data === null || data === void 0 ? void 0 : data.destinationUrl) !== null && _data$destinationUrl !== void 0 ? _data$destinationUrl : url : url, '_blank');
|
|
110
110
|
} else {
|
|
111
111
|
// only trigger the provided onClick callback if the meta key or ctrl key is not pressed
|
|
112
112
|
propsOnClick === null || propsOnClick === void 0 || propsOnClick(event);
|
|
@@ -7,6 +7,7 @@ import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
|
7
7
|
import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
|
|
8
8
|
import { isWithinPreviewPanelIFrame } from '@atlaskit/linking-common/utils';
|
|
9
9
|
import { getObjectAri, getObjectName, getObjectIconUrl } from '@atlaskit/smart-card';
|
|
10
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
10
11
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
11
12
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
12
13
|
import { registerRemoveOverlay } from '../pm-plugins/actions';
|
|
@@ -50,6 +51,7 @@ export var InlineCardWithAwareness = /*#__PURE__*/memo(function (_ref) {
|
|
|
50
51
|
isResolvedViewRendered = _useState6[0],
|
|
51
52
|
setIsResolvedViewRendered = _useState6[1];
|
|
52
53
|
var editorAppearance = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card.sharedState.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.editorAppearance;
|
|
54
|
+
var destinationUrl = useSmartLinkDestinationUrl(node.attrs.url);
|
|
53
55
|
var onResolve = useCallback(function (tr, title) {
|
|
54
56
|
var metadata = tr.getMeta(pluginKey);
|
|
55
57
|
if (metadata && metadata.type === 'REGISTER') {
|
|
@@ -88,6 +90,7 @@ export var InlineCardWithAwareness = /*#__PURE__*/memo(function (_ref) {
|
|
|
88
90
|
return /*#__PURE__*/React.createElement(HoverLinkOverlay, {
|
|
89
91
|
isVisible: isResolvedViewRendered,
|
|
90
92
|
url: node.attrs.url,
|
|
93
|
+
destinationUrl: destinationUrl,
|
|
91
94
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
92
95
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions,
|
|
93
96
|
view: view
|
|
@@ -106,7 +109,7 @@ export var InlineCardWithAwareness = /*#__PURE__*/memo(function (_ref) {
|
|
|
106
109
|
pluginInjectionApi: pluginInjectionApi,
|
|
107
110
|
disablePreviewPanel: true
|
|
108
111
|
}));
|
|
109
|
-
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi]);
|
|
112
|
+
}, [isResolvedViewRendered, node, editorAppearance, view, getPos, useAlternativePreloader, actionOptions, onResolve, onClick, cardContext, isHovered, isPageSSRed, provider, pluginInjectionApi, destinationUrl]);
|
|
110
113
|
var innerCardOriginal = useMemo(function () {
|
|
111
114
|
return /*#__PURE__*/React.createElement(InlineCard, {
|
|
112
115
|
node: node,
|
|
@@ -185,6 +188,7 @@ export var InlineCardWithAwareness = /*#__PURE__*/memo(function (_ref) {
|
|
|
185
188
|
return /*#__PURE__*/React.createElement(HoverLinkOverlay, {
|
|
186
189
|
isVisible: isResolvedViewRendered,
|
|
187
190
|
url: url,
|
|
191
|
+
destinationUrl: destinationUrl,
|
|
188
192
|
compactPadding: editorAppearance === 'comment' || editorAppearance === 'chromeless',
|
|
189
193
|
editorAnalyticsApi: pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions,
|
|
190
194
|
view: view,
|
|
@@ -18,6 +18,8 @@ import { useIntl } from 'react-intl';
|
|
|
18
18
|
import { cardMessages as messages } from '@atlaskit/editor-common/messages';
|
|
19
19
|
import { ZERO_WIDTH_JOINER } from '@atlaskit/editor-common/whitespace';
|
|
20
20
|
import CustomizeIcon from '@atlaskit/icon/core/customize';
|
|
21
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
22
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
21
23
|
import { getChildElement, getInlineCardAvailableWidth, getOverlayWidths, isOneLine } from './utils';
|
|
22
24
|
var DEBOUNCE_IN_MS = 5;
|
|
23
25
|
var ESTIMATED_MIN_WIDTH_IN_PX = 16;
|
|
@@ -103,6 +105,7 @@ var gradientStyles = css({
|
|
|
103
105
|
background: getGradientWithColor(SMART_LINK_BACKGROUND_COLOR)
|
|
104
106
|
});
|
|
105
107
|
var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
108
|
+
var _useSmartLinkDestinat;
|
|
106
109
|
var children = _ref.children,
|
|
107
110
|
_ref$isSelected = _ref.isSelected,
|
|
108
111
|
isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
|
|
@@ -213,6 +216,7 @@ var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
|
213
216
|
observer.disconnect();
|
|
214
217
|
};
|
|
215
218
|
}, [isVisible, setVisibility]);
|
|
219
|
+
var destinationUrl = (_useSmartLinkDestinat = useSmartLinkDestinationUrl(url)) !== null && _useSmartLinkDestinat !== void 0 ? _useSmartLinkDestinat : url;
|
|
216
220
|
var intl = useIntl();
|
|
217
221
|
var label = intl.formatMessage(messages.inlineOverlay);
|
|
218
222
|
return (
|
|
@@ -232,7 +236,7 @@ var InlineCardOverlay = function InlineCardOverlay(_ref) {
|
|
|
232
236
|
width: availableWidth
|
|
233
237
|
},
|
|
234
238
|
"data-testid": testId,
|
|
235
|
-
href: url,
|
|
239
|
+
href: fg('platform_smartlink_xpc_url_wrapping') ? destinationUrl : url,
|
|
236
240
|
onClick: function onClick(e) {
|
|
237
241
|
return e.preventDefault();
|
|
238
242
|
},
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { FloatingToolbarButton as Button } from '@atlaskit/editor-common/ui';
|
|
3
|
+
import LinkExternalIcon from '@atlaskit/icon/core/link-external';
|
|
4
|
+
import { useSmartLinkDestinationUrl } from '@atlaskit/smart-card/hook/use-smart-link-destination-url';
|
|
5
|
+
/**
|
|
6
|
+
* Toolbar button that opens a Smart Link URL in a new tab, with the XPC-wrapped destination URL.
|
|
7
|
+
*
|
|
8
|
+
* This component is only rendered when `fg('platform_smartlink_xpc_url_wrapping')` is ON.
|
|
9
|
+
* It wraps `FloatingToolbarButton` and replaces `href` with the resolved destination URL
|
|
10
|
+
* (cross-product analytics parameters appended), falling back to the raw `url` when the
|
|
11
|
+
* link is unresolved or not a first-party Atlassian link.
|
|
12
|
+
*/
|
|
13
|
+
export var OpenLinkToolbarButton = function OpenLinkToolbarButton(_ref) {
|
|
14
|
+
var url = _ref.url,
|
|
15
|
+
areAnyNewToolbarFlagsEnabled = _ref.areAnyNewToolbarFlagsEnabled,
|
|
16
|
+
editorView = _ref.editorView,
|
|
17
|
+
onClick = _ref.onClick,
|
|
18
|
+
title = _ref.title;
|
|
19
|
+
var destinationUrl = useSmartLinkDestinationUrl(url);
|
|
20
|
+
var handleClick = useCallback(function () {
|
|
21
|
+
onClick(editorView.state, editorView.dispatch);
|
|
22
|
+
}, [editorView, onClick]);
|
|
23
|
+
return /*#__PURE__*/React.createElement(Button
|
|
24
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
25
|
+
, {
|
|
26
|
+
className: "hyperlink-open-link",
|
|
27
|
+
title: title,
|
|
28
|
+
icon: /*#__PURE__*/React.createElement(LinkExternalIcon, {
|
|
29
|
+
label: ""
|
|
30
|
+
}),
|
|
31
|
+
href: destinationUrl,
|
|
32
|
+
target: "_blank",
|
|
33
|
+
onClick: handleClick,
|
|
34
|
+
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
|
|
35
|
+
});
|
|
36
|
+
};
|
package/dist/esm/ui/toolbar.js
CHANGED
|
@@ -22,6 +22,7 @@ import EditIcon from '@atlaskit/icon/core/edit';
|
|
|
22
22
|
import LinkBrokenIcon from '@atlaskit/icon/core/link-broken';
|
|
23
23
|
import LinkExternalIcon from '@atlaskit/icon/core/link-external';
|
|
24
24
|
import CogIcon from '@atlaskit/icon/core/settings';
|
|
25
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
25
26
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
26
27
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
27
28
|
import { changeSelectedCardToText } from '../pm-plugins/doc';
|
|
@@ -34,6 +35,7 @@ import { HyperlinkToolbarAppearance } from './HyperlinkToolbarAppearance';
|
|
|
34
35
|
import { getCustomHyperlinkAppearanceDropdown } from './HyperlinkToolbarAppearanceDropdown';
|
|
35
36
|
import { LinkToolbarAppearance } from './LinkToolbarAppearance';
|
|
36
37
|
import { getLinkAppearanceDropdown } from './LinkToolbarAppearanceDropdown';
|
|
38
|
+
import { OpenLinkToolbarButton } from './OpenLinkToolbarButton';
|
|
37
39
|
import { OpenPreviewPanelToolbarButton } from './OpenPreviewButton';
|
|
38
40
|
import { ToolbarViewedEvent } from './ToolbarViewedEvent';
|
|
39
41
|
export var removeCard = function removeCard(editorAnalyticsApi) {
|
|
@@ -361,7 +363,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
|
|
|
361
363
|
}
|
|
362
364
|
}] : [];
|
|
363
365
|
var resolvedToolbarAttributes = url ? (_pluginState$resolved = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[url]) !== null && _pluginState$resolved !== void 0 ? _pluginState$resolved : {} : {};
|
|
364
|
-
var
|
|
366
|
+
var openLinkToolbarItemFallback = {
|
|
365
367
|
id: 'editor.link.openLink',
|
|
366
368
|
type: 'button',
|
|
367
369
|
icon: LinkExternalIcon,
|
|
@@ -373,6 +375,19 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
|
|
|
373
375
|
href: url,
|
|
374
376
|
target: '_blank'
|
|
375
377
|
};
|
|
378
|
+
var openLinkToolbarItem = fg('platform_smartlink_xpc_url_wrapping') ? {
|
|
379
|
+
type: 'custom',
|
|
380
|
+
fallback: [openLinkToolbarItemFallback],
|
|
381
|
+
render: function render(editorView) {
|
|
382
|
+
return editorView && url ? /*#__PURE__*/React.createElement(OpenLinkToolbarButton, {
|
|
383
|
+
url: url,
|
|
384
|
+
title: intl.formatMessage(linkMessages.openLink),
|
|
385
|
+
editorView: editorView,
|
|
386
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, resolvedToolbarAttributes),
|
|
387
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
388
|
+
}) : null;
|
|
389
|
+
}
|
|
390
|
+
} : openLinkToolbarItemFallback;
|
|
376
391
|
var toolbarItems = areAllNewToolbarFlagsDisabled ? [].concat(editItems, commentItems, openPreviewPanelItems, [openLinkToolbarItem, {
|
|
377
392
|
type: 'separator'
|
|
378
393
|
}], _toConsumableArray(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled)), [{
|
|
@@ -637,7 +652,7 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
|
|
|
637
652
|
});
|
|
638
653
|
if (node !== null && node !== void 0 && (_node$attrs3 = node.attrs) !== null && _node$attrs3 !== void 0 && _node$attrs3.url) {
|
|
639
654
|
var _pluginState$resolved2;
|
|
640
|
-
|
|
655
|
+
var openLinkToolbarItemFallback = {
|
|
641
656
|
id: 'editor.link.openLink',
|
|
642
657
|
type: 'button',
|
|
643
658
|
icon: LinkExternalIcon,
|
|
@@ -648,7 +663,21 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
|
|
|
648
663
|
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved2 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved2 !== void 0 ? _pluginState$resolved2 : {}),
|
|
649
664
|
href: node.attrs.url,
|
|
650
665
|
target: '_blank'
|
|
651
|
-
}
|
|
666
|
+
};
|
|
667
|
+
toolbarItems.push(fg('platform_smartlink_xpc_url_wrapping') ? {
|
|
668
|
+
type: 'custom',
|
|
669
|
+
fallback: [openLinkToolbarItemFallback],
|
|
670
|
+
render: function render(editorView) {
|
|
671
|
+
var _pluginState$resolved3;
|
|
672
|
+
return editorView ? /*#__PURE__*/React.createElement(OpenLinkToolbarButton, {
|
|
673
|
+
url: node.attrs.url,
|
|
674
|
+
title: intl.formatMessage(linkMessages.openLink),
|
|
675
|
+
editorView: editorView,
|
|
676
|
+
onClick: fireOpenLinkToolbarAnalytics(editorAnalyticsApi, openLinkInputMethod, (_pluginState$resolved3 = pluginState === null || pluginState === void 0 ? void 0 : pluginState.resolvedToolbarAttributesByUrl[node.attrs.url]) !== null && _pluginState$resolved3 !== void 0 ? _pluginState$resolved3 : {}),
|
|
677
|
+
areAnyNewToolbarFlagsEnabled: !areAllNewToolbarFlagsDisabled
|
|
678
|
+
}) : null;
|
|
679
|
+
}
|
|
680
|
+
} : openLinkToolbarItemFallback);
|
|
652
681
|
if (areAllNewToolbarFlagsDisabled) {
|
|
653
682
|
toolbarItems.push({
|
|
654
683
|
type: 'separator'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Command } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
+
type OpenLinkToolbarButtonProps = {
|
|
5
|
+
areAnyNewToolbarFlagsEnabled: boolean;
|
|
6
|
+
editorView: EditorView;
|
|
7
|
+
onClick: Command;
|
|
8
|
+
title: string;
|
|
9
|
+
url: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Toolbar button that opens a Smart Link URL in a new tab, with the XPC-wrapped destination URL.
|
|
13
|
+
*
|
|
14
|
+
* This component is only rendered when `fg('platform_smartlink_xpc_url_wrapping')` is ON.
|
|
15
|
+
* It wraps `FloatingToolbarButton` and replaces `href` with the resolved destination URL
|
|
16
|
+
* (cross-product analytics parameters appended), falling back to the raw `url` when the
|
|
17
|
+
* link is unresolved or not a first-party Atlassian link.
|
|
18
|
+
*/
|
|
19
|
+
export declare const OpenLinkToolbarButton: ({ url, areAnyNewToolbarFlagsEnabled, editorView, onClick, title, }: OpenLinkToolbarButtonProps) => React.JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Command } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
+
type OpenLinkToolbarButtonProps = {
|
|
5
|
+
areAnyNewToolbarFlagsEnabled: boolean;
|
|
6
|
+
editorView: EditorView;
|
|
7
|
+
onClick: Command;
|
|
8
|
+
title: string;
|
|
9
|
+
url: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Toolbar button that opens a Smart Link URL in a new tab, with the XPC-wrapped destination URL.
|
|
13
|
+
*
|
|
14
|
+
* This component is only rendered when `fg('platform_smartlink_xpc_url_wrapping')` is ON.
|
|
15
|
+
* It wraps `FloatingToolbarButton` and replaces `href` with the resolved destination URL
|
|
16
|
+
* (cross-product analytics parameters appended), falling back to the raw `url` when the
|
|
17
|
+
* link is unresolved or not a first-party Atlassian link.
|
|
18
|
+
*/
|
|
19
|
+
export declare const OpenLinkToolbarButton: ({ url, areAnyNewToolbarFlagsEnabled, editorView, onClick, title, }: OpenLinkToolbarButtonProps) => React.JSX.Element;
|
|
20
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-card",
|
|
3
|
-
"version": "17.4.
|
|
3
|
+
"version": "17.4.3",
|
|
4
4
|
"description": "Card plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"atlaskit:src": "src/index.ts",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@atlaskit/adf-schema": "^
|
|
32
|
+
"@atlaskit/adf-schema": "^53.0.0",
|
|
33
33
|
"@atlaskit/analytics-next": "^11.3.0",
|
|
34
34
|
"@atlaskit/button": "^23.11.0",
|
|
35
35
|
"@atlaskit/css": "^0.19.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@atlaskit/platform-feature-flags-react": "^0.5.0",
|
|
66
66
|
"@atlaskit/primitives": "^19.0.0",
|
|
67
67
|
"@atlaskit/prosemirror-history": "^0.2.0",
|
|
68
|
-
"@atlaskit/smart-card": "^44.
|
|
68
|
+
"@atlaskit/smart-card": "^44.26.0",
|
|
69
69
|
"@atlaskit/tmp-editor-statsig": "^94.0.0",
|
|
70
70
|
"@atlaskit/tokens": "^13.3.0",
|
|
71
71
|
"@babel/runtime": "^7.0.0",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"uuid": "^3.1.0"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
|
-
"@atlaskit/editor-common": "^115.
|
|
79
|
+
"@atlaskit/editor-common": "^115.10.0",
|
|
80
80
|
"@atlaskit/link-provider": "^4.7.0",
|
|
81
81
|
"react": "^18.2.0",
|
|
82
82
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -130,6 +130,10 @@
|
|
|
130
130
|
"platform_editor_adf_with_localid": {
|
|
131
131
|
"type": "boolean"
|
|
132
132
|
},
|
|
133
|
+
"platform_smartlink_xpc_url_wrapping": {
|
|
134
|
+
"type": "boolean",
|
|
135
|
+
"referenceOnly": true
|
|
136
|
+
},
|
|
133
137
|
"jim-lower-ranking-in-jira-macro-search": {
|
|
134
138
|
"type": "boolean"
|
|
135
139
|
}
|