@atlaskit/smart-card 40.17.2 → 40.19.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cjs/extractors/action/extract-invoke-preview-action.js +9 -2
  3. package/dist/cjs/state/hooks-external/useSmartLinkActions.js +8 -1
  4. package/dist/cjs/utils/analytics/analytics.js +1 -1
  5. package/dist/cjs/utils/iframe-utils.js +40 -0
  6. package/dist/cjs/view/EmbedCard/components/ImageIcon.compiled.css +1 -1
  7. package/dist/cjs/view/EmbedCard/components/ImageIcon.js +1 -1
  8. package/dist/cjs/view/EmbedCard/components/styled.compiled.css +1 -1
  9. package/dist/cjs/view/EmbedCard/components/styled.js +2 -2
  10. package/dist/cjs/view/EmbedModal/utils.js +21 -3
  11. package/dist/cjs/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.compiled.css +1 -1
  12. package/dist/cjs/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.js +1 -1
  13. package/dist/cjs/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.compiled.css +1 -1
  14. package/dist/cjs/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.js +2 -2
  15. package/dist/cjs/view/FlexibleCard/components/blocks/action-block/action-footer/index.compiled.css +1 -1
  16. package/dist/cjs/view/FlexibleCard/components/blocks/action-block/action-footer/index.js +1 -1
  17. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.compiled.css +1 -1
  18. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +1 -1
  19. package/dist/cjs/view/InlineCard/ForbiddenView/index.compiled.css +1 -1
  20. package/dist/cjs/view/InlineCard/ForbiddenView/index.js +1 -1
  21. package/dist/cjs/view/InlineCard/IconAndTitleLayout/index.compiled.css +1 -2
  22. package/dist/cjs/view/InlineCard/IconAndTitleLayout/index.js +2 -2
  23. package/dist/cjs/view/LinkUrl/HyperlinkResolver/error-boundary.js +17 -0
  24. package/dist/cjs/view/LinkUrl/HyperlinkResolver/hooks/useScheduledRegister.js +82 -0
  25. package/dist/cjs/view/LinkUrl/HyperlinkResolver/index.js +34 -0
  26. package/dist/cjs/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +69 -0
  27. package/dist/cjs/view/LinkUrl/index.js +10 -3
  28. package/dist/es2019/extractors/action/extract-invoke-preview-action.js +6 -1
  29. package/dist/es2019/state/hooks-external/useSmartLinkActions.js +8 -1
  30. package/dist/es2019/utils/analytics/analytics.js +1 -1
  31. package/dist/es2019/utils/iframe-utils.js +34 -0
  32. package/dist/es2019/view/EmbedCard/components/ImageIcon.compiled.css +1 -1
  33. package/dist/es2019/view/EmbedCard/components/ImageIcon.js +1 -1
  34. package/dist/es2019/view/EmbedCard/components/styled.compiled.css +1 -1
  35. package/dist/es2019/view/EmbedCard/components/styled.js +2 -2
  36. package/dist/es2019/view/EmbedModal/utils.js +12 -0
  37. package/dist/es2019/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.compiled.css +1 -1
  38. package/dist/es2019/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.js +1 -1
  39. package/dist/es2019/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.compiled.css +1 -1
  40. package/dist/es2019/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.js +2 -2
  41. package/dist/es2019/view/FlexibleCard/components/blocks/action-block/action-footer/index.compiled.css +1 -1
  42. package/dist/es2019/view/FlexibleCard/components/blocks/action-block/action-footer/index.js +1 -1
  43. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.compiled.css +1 -1
  44. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +1 -1
  45. package/dist/es2019/view/InlineCard/ForbiddenView/index.compiled.css +1 -1
  46. package/dist/es2019/view/InlineCard/ForbiddenView/index.js +1 -1
  47. package/dist/es2019/view/InlineCard/IconAndTitleLayout/index.compiled.css +1 -2
  48. package/dist/es2019/view/InlineCard/IconAndTitleLayout/index.js +2 -2
  49. package/dist/es2019/view/LinkUrl/HyperlinkResolver/error-boundary.js +8 -0
  50. package/dist/es2019/view/LinkUrl/HyperlinkResolver/hooks/useScheduledRegister.js +77 -0
  51. package/dist/es2019/view/LinkUrl/HyperlinkResolver/index.js +26 -0
  52. package/dist/es2019/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +58 -0
  53. package/dist/es2019/view/LinkUrl/index.js +8 -2
  54. package/dist/esm/extractors/action/extract-invoke-preview-action.js +9 -2
  55. package/dist/esm/state/hooks-external/useSmartLinkActions.js +8 -1
  56. package/dist/esm/utils/analytics/analytics.js +1 -1
  57. package/dist/esm/utils/iframe-utils.js +34 -0
  58. package/dist/esm/view/EmbedCard/components/ImageIcon.compiled.css +1 -1
  59. package/dist/esm/view/EmbedCard/components/ImageIcon.js +1 -1
  60. package/dist/esm/view/EmbedCard/components/styled.compiled.css +1 -1
  61. package/dist/esm/view/EmbedCard/components/styled.js +2 -2
  62. package/dist/esm/view/EmbedModal/utils.js +21 -3
  63. package/dist/esm/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.compiled.css +1 -1
  64. package/dist/esm/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/header/main.js +1 -1
  65. package/dist/esm/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.compiled.css +1 -1
  66. package/dist/esm/view/FlexibleCard/components/actions/automation-action/automation-manual-triggers/manual-triggers-modal/sub-components/rule/main.js +2 -2
  67. package/dist/esm/view/FlexibleCard/components/blocks/action-block/action-footer/index.compiled.css +1 -1
  68. package/dist/esm/view/FlexibleCard/components/blocks/action-block/action-footer/index.js +1 -1
  69. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.compiled.css +1 -1
  70. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +1 -1
  71. package/dist/esm/view/InlineCard/ForbiddenView/index.compiled.css +1 -1
  72. package/dist/esm/view/InlineCard/ForbiddenView/index.js +1 -1
  73. package/dist/esm/view/InlineCard/IconAndTitleLayout/index.compiled.css +1 -2
  74. package/dist/esm/view/InlineCard/IconAndTitleLayout/index.js +2 -2
  75. package/dist/esm/view/LinkUrl/HyperlinkResolver/error-boundary.js +10 -0
  76. package/dist/esm/view/LinkUrl/HyperlinkResolver/hooks/useScheduledRegister.js +76 -0
  77. package/dist/esm/view/LinkUrl/HyperlinkResolver/index.js +25 -0
  78. package/dist/esm/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.js +60 -0
  79. package/dist/esm/view/LinkUrl/index.js +10 -3
  80. package/dist/types/common/analytics/generated/analytics.types.d.ts +19 -0
  81. package/dist/types/state/hooks-external/useSmartLinkActions.d.ts +6 -1
  82. package/dist/types/utils/iframe-utils.d.ts +5 -0
  83. package/dist/types/view/EmbedModal/types.d.ts +1 -0
  84. package/dist/types/view/LinkUrl/HyperlinkResolver/error-boundary.d.ts +4 -0
  85. package/dist/types/view/LinkUrl/HyperlinkResolver/hooks/useScheduledRegister.d.ts +5 -0
  86. package/dist/types/view/LinkUrl/HyperlinkResolver/index.d.ts +7 -0
  87. package/dist/types/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.d.ts +3 -0
  88. package/dist/types/view/LinkUrl/types.d.ts +4 -0
  89. package/dist/types-ts4.5/common/analytics/generated/analytics.types.d.ts +19 -0
  90. package/dist/types-ts4.5/state/hooks-external/useSmartLinkActions.d.ts +6 -1
  91. package/dist/types-ts4.5/utils/iframe-utils.d.ts +5 -0
  92. package/dist/types-ts4.5/view/EmbedModal/types.d.ts +1 -0
  93. package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/error-boundary.d.ts +4 -0
  94. package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/hooks/useScheduledRegister.d.ts +5 -0
  95. package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/index.d.ts +7 -0
  96. package/dist/types-ts4.5/view/LinkUrl/HyperlinkResolver/resolve-hyperlink.d.ts +3 -0
  97. package/dist/types-ts4.5/view/LinkUrl/types.d.ts +4 -0
  98. package/package.json +6 -6
@@ -10,16 +10,18 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
10
10
  var _react = _interopRequireDefault(require("react"));
11
11
  var _reactMagneticDi = require("react-magnetic-di");
12
12
  var _analyticsNext = require("@atlaskit/analytics-next");
13
+ var _featureGateJsClient = _interopRequireDefault(require("@atlaskit/feature-gate-js-client"));
13
14
  var _link = _interopRequireDefault(require("@atlaskit/link"));
14
15
  var _click = require("../../utils/analytics/click");
15
16
  var _LinkAnalyticsContext = require("../../utils/analytics/LinkAnalyticsContext");
17
+ var _HyperlinkResolver = _interopRequireDefault(require("./HyperlinkResolver"));
16
18
  var _LinkWarningModal = _interopRequireDefault(require("./LinkWarningModal"));
17
19
  var _useLinkWarningModal2 = require("./LinkWarningModal/hooks/use-link-warning-modal");
18
- var _excluded = ["href", "children", "checkSafety", "onClick", "testId", "isLinkComponent"],
20
+ var _excluded = ["href", "children", "checkSafety", "onClick", "testId", "isLinkComponent", "enableResolve"],
19
21
  _excluded2 = ["isLinkSafe", "showSafetyWarningModal"];
20
22
  var PACKAGE_DATA = {
21
23
  packageName: "@atlaskit/smart-card",
22
- packageVersion: "40.17.1",
24
+ packageVersion: "0.0.0-development",
23
25
  componentName: 'linkUrl'
24
26
  };
25
27
  var Anchor = (0, _click.withLinkClickedEvent)('a');
@@ -34,12 +36,15 @@ var LinkUrl = function LinkUrl(_ref) {
34
36
  testId = _ref$testId === void 0 ? 'link-with-safety' : _ref$testId,
35
37
  _ref$isLinkComponent = _ref.isLinkComponent,
36
38
  isLinkComponent = _ref$isLinkComponent === void 0 ? false : _ref$isLinkComponent,
39
+ _ref$enableResolve = _ref.enableResolve,
40
+ enableResolve = _ref$enableResolve === void 0 ? false : _ref$enableResolve,
37
41
  props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
38
42
  var _useLinkWarningModal = (0, _useLinkWarningModal2.useLinkWarningModal)(),
39
43
  isLinkSafe = _useLinkWarningModal.isLinkSafe,
40
44
  showSafetyWarningModal = _useLinkWarningModal.showSafetyWarningModal,
41
45
  linkWarningModalProps = (0, _objectWithoutProperties2.default)(_useLinkWarningModal, _excluded2);
42
46
  var Link = isLinkComponent ? LinkComponent : Anchor;
47
+ var resolveHyperlinkFG = _featureGateJsClient.default.checkGate('platform_editor_resolve_hyperlinks_killswitch');
43
48
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_LinkAnalyticsContext.LinkAnalyticsContext, {
44
49
  url: href,
45
50
  display: "url"
@@ -62,6 +67,8 @@ var LinkUrl = function LinkUrl(_ref) {
62
67
  showSafetyWarningModal(e, href);
63
68
  }
64
69
  }
65
- }, props), children)), checkSafety && /*#__PURE__*/_react.default.createElement(_LinkWarningModal.default, linkWarningModalProps));
70
+ }, props), children)), checkSafety && /*#__PURE__*/_react.default.createElement(_LinkWarningModal.default, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && /*#__PURE__*/_react.default.createElement(_HyperlinkResolver.default, {
71
+ href: href
72
+ }));
66
73
  };
67
74
  var _default = exports.default = (0, _analyticsNext.withAnalyticsContext)(PACKAGE_DATA)(LinkUrl);
@@ -4,6 +4,7 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
4
  import { ActionName, CardAction } from '../../index';
5
5
  import { getExtensionKey } from '../../state/helpers';
6
6
  import { canShowAction } from '../../utils/actions/can-show-action';
7
+ import { isModalWithinPreviewPanelIFrame } from '../../utils/iframe-utils';
7
8
  import { openEmbedModal } from '../../view/EmbedModal/utils';
8
9
  import { extractIsSupportTheming } from '../common/meta/extractIsSupportTheming';
9
10
  import { extractIsTrusted } from '../common/meta/extractIsTrusted';
@@ -30,6 +31,7 @@ export const extractInvokePreviewAction = param => {
30
31
  const hasPreviewPanel = hasPreviewPanelParams && isPreviewPanelAvailable({
31
32
  ari: ari
32
33
  });
34
+ const isInPreviewPanel = expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && isModalWithinPreviewPanelIFrame();
33
35
  const data = response.data;
34
36
  const meta = response.meta;
35
37
  if (!canShowAction(CardAction.PreviewAction, actionOptions)) {
@@ -65,7 +67,10 @@ export const extractInvokePreviewAction = param => {
65
67
  src: (_extractSmartLinkEmbe = extractSmartLinkEmbed(response)) === null || _extractSmartLinkEmbe === void 0 ? void 0 : _extractSmartLinkEmbe.src,
66
68
  title: extractSmartLinkTitle(response),
67
69
  url,
68
- size: fg('platform_linking_enable_card_preview_action_size') ? actionOptions === null || actionOptions === void 0 ? void 0 : (_actionOptions$previe = actionOptions.previewAction) === null || _actionOptions$previe === void 0 ? void 0 : _actionOptions$previe.size : undefined
70
+ size: fg('platform_linking_enable_card_preview_action_size') ? actionOptions === null || actionOptions === void 0 ? void 0 : (_actionOptions$previe = actionOptions.previewAction) === null || _actionOptions$previe === void 0 ? void 0 : _actionOptions$previe.size : undefined,
71
+ ...(expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && {
72
+ isInPreviewPanel
73
+ })
69
74
  });
70
75
  }
71
76
  },
@@ -1,6 +1,7 @@
1
1
  import { useMemo } from 'react';
2
2
  import uuid from 'uuid';
3
3
  import { useSmartLinkContext } from '@atlaskit/link-provider';
4
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
5
  import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
5
6
  import { extractInvokeDownloadAction } from '../../extractors/action/extract-invoke-download-action';
6
7
  import { extractInvokePreviewAction } from '../../extractors/action/extract-invoke-preview-action';
@@ -8,12 +9,14 @@ import { extractInvokeViewAction } from '../../extractors/action/extract-invoke-
8
9
  import { messages } from '../../messages';
9
10
  import { toAction } from '../../utils/actions/to-action';
10
11
  import useInvokeClientAction from '../hooks/use-invoke-client-action';
12
+ import useResolve from '../hooks/use-resolve';
11
13
  import { useSmartCardState as useLinkState } from '../store';
12
14
  export function useSmartLinkActions({
13
15
  url,
14
16
  appearance,
15
17
  origin,
16
- actionOptions
18
+ actionOptions,
19
+ prefetch
17
20
  }) {
18
21
  const id = useMemo(() => uuid(), []);
19
22
  const linkState = useLinkState(url);
@@ -27,6 +30,10 @@ export function useSmartLinkActions({
27
30
  const invokeClientAction = useInvokeClientAction({
28
31
  fireEvent
29
32
  });
33
+ const resolve = useResolve();
34
+ if (expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && prefetch && !linkState.details) {
35
+ resolve(url);
36
+ }
30
37
  if (linkState.details && !(actionOptions !== null && actionOptions !== void 0 && actionOptions.hide)) {
31
38
  const actions = [];
32
39
  const invokeParam = {
@@ -2,7 +2,7 @@ export const ANALYTICS_CHANNEL = 'media';
2
2
  export const context = {
3
3
  componentName: 'smart-cards',
4
4
  packageName: "@atlaskit/smart-card",
5
- packageVersion: "40.17.1"
5
+ packageVersion: "0.0.0-development"
6
6
  };
7
7
  export let TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
8
8
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -0,0 +1,34 @@
1
+ export const isInIframe = () => {
2
+ try {
3
+ return window !== window.top;
4
+ } catch {
5
+ // If we can't access window.top due to cross-origin restrictions, assume we're in an iframe
6
+ return true;
7
+ }
8
+ };
9
+ export const isWithinPreviewPanel = () => {
10
+ try {
11
+ const params = new URLSearchParams(window.location.search);
12
+ return params.has('previewPanels') || params.get('embeddedConfluenceSource') === 'confluence-page-preview-panel';
13
+ } catch {
14
+ return false;
15
+ }
16
+ };
17
+ export const isModalWithinPreviewPanelIFrame = () => {
18
+ return isInIframe() && isWithinPreviewPanel();
19
+ };
20
+
21
+ // Signals parent product to open embed modal via postMessage when in iframe context
22
+ export const openEmbedModalInParent = modalProps => {
23
+ if (!isInIframe()) {
24
+ return;
25
+ }
26
+ window.parent.postMessage({
27
+ type: 'OPEN_EMBED_MODAL',
28
+ payload: {
29
+ modal: {
30
+ url: (modalProps === null || modalProps === void 0 ? void 0 : modalProps.url) || ''
31
+ }
32
+ }
33
+ }, '*');
34
+ };
@@ -1 +1 @@
1
- ._2rko1twn{border-radius:var(--ds-border-radius-circle,9999px)}
1
+ ._2rko1rr0{border-radius:var(--ds-radius-full,9999px)}
@@ -7,7 +7,7 @@ import ImageLoader from 'react-render-image';
7
7
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
8
  import { Image } from './styled';
9
9
  const styles = {
10
- roundedImage: "_2rko1twn"
10
+ roundedImage: "_2rko1rr0"
11
11
  };
12
12
  export const ImageIcon = ({
13
13
  alt = '',
@@ -1,5 +1,5 @@
1
1
 
2
- ._2rko1sit{border-radius:var(--ds-border-radius,3px)}._18m915vq{overflow-y:hidden}
2
+ ._2rkofajl{border-radius:var(--ds-radius-small,3px)}._18m915vq{overflow-y:hidden}
3
3
  ._18u0utpp{margin-left:var(--ds-space-150,9pt)}
4
4
  ._19pk1b66{margin-top:var(--ds-space-050,4px)}
5
5
  ._1aaxusic{float:right}
@@ -26,7 +26,7 @@ export const Image = forwardRef(({
26
26
  "--_rcxkve": ix(getSizeWithUnit(__cmplp.size))
27
27
  },
28
28
  ref: __cmplr,
29
- className: ax(["_2rko1sit _1reo15vq _18m915vq _1bsb17ym _4t3i17ym", __cmplp.className])
29
+ className: ax(["_2rkofajl _1reo15vq _18m915vq _1bsb17ym _4t3i17ym", __cmplp.className])
30
30
  }));
31
31
  });
32
32
 
@@ -45,7 +45,7 @@ export const Thumbnail = forwardRef(({
45
45
  "--_13orr8u": ix(`url(${__cmplp.src})`)
46
46
  },
47
47
  ref: __cmplr,
48
- className: ax(["_2rko1sit _1bsbckbl _4t3ickbl _1aaxusic _19pk1b66 _2hwxidpf _otyrutpp _18u0utpp _bfhkqrzy _1lrw1dfr _1itk2pcs", __cmplp.className])
48
+ className: ax(["_2rkofajl _1bsbckbl _4t3ickbl _1aaxusic _19pk1b66 _2hwxidpf _otyrutpp _18u0utpp _bfhkqrzy _1lrw1dfr _1itk2pcs", __cmplp.className])
49
49
  }));
50
50
  });
51
51
  if (process.env.NODE_ENV !== 'production') {
@@ -2,6 +2,8 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React from 'react';
3
3
  import ReactDOM from 'react-dom';
4
4
  import { IntlProvider } from 'react-intl-next';
5
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
+ import { openEmbedModalInParent } from '../../utils/iframe-utils';
5
7
  const IFRAME_NAME = 'twp-editor-preview-iframe';
6
8
  const POPUP_MOUNT_POINT_ID = 'twp-editor-preview-iframe';
7
9
 
@@ -22,6 +24,16 @@ export async function openEmbedModal({
22
24
  onClose = () => {},
23
25
  ...props
24
26
  } = {}) {
27
+ // If the modal trigger is in an iframe and the user has preview panels enabled, send a message to open modal to the parent product
28
+ if (expValEquals('platform_hover_card_preview_panel', 'cohort', 'test')) {
29
+ if (props.isInPreviewPanel) {
30
+ openEmbedModalInParent({
31
+ onClose,
32
+ ...props
33
+ });
34
+ return;
35
+ }
36
+ }
25
37
  let popupMountPoint;
26
38
  popupMountPoint = document.getElementById(POPUP_MOUNT_POINT_ID);
27
39
  if (!popupMountPoint) {
@@ -1,5 +1,5 @@
1
1
 
2
- ._2rkoglpi{border-radius:var(--ds-border-radius,4px)}._18zr1b66{padding-inline:var(--ds-space-050,4px)}
2
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._18zr1b66{padding-inline:var(--ds-space-050,4px)}
3
3
  ._1rjcv77o{padding-block:var(--ds-space-025,2px)}
4
4
  ._19pkutpp{margin-top:var(--ds-space-150,9pt)}
5
5
  ._2hwxutpp{margin-right:var(--ds-space-150,9pt)}
@@ -11,7 +11,7 @@ import { Box, Inline, Stack } from '@atlaskit/primitives/compiled';
11
11
  import { G50 } from '@atlaskit/theme/colors';
12
12
  import { useAutomationMenu } from '../../menu-context';
13
13
  const styles = {
14
- iconStyle: "_2rkoglpi _18zr1b66 _1rjcv77o _2hwxutpp",
14
+ iconStyle: "_2rko12b0 _18zr1b66 _1rjcv77o _2hwxutpp",
15
15
  modalDescriptionStyle: "_19pkutpp"
16
16
  };
17
17
  const i18n = defineMessages({
@@ -1,5 +1,5 @@
1
1
 
2
- ._2rkoglpi{border-radius:var(--ds-border-radius,4px)}._189e1bk5{border-width:var(--ds-border-width-outline,2px)}
2
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}._189e1bk5{border-width:var(--ds-border-width-outline,2px)}
3
3
  ._189ee4h9{border-width:var(--ds-border-width,1px)}
4
4
  ._1dqonqa1{border-style:solid}
5
5
  ._1h6d15qp{border-color:var(--ds-border-accent-blue,#1d7afc)}
@@ -8,8 +8,8 @@ import { Box, Stack } from '@atlaskit/primitives/compiled';
8
8
  import Spinner from '@atlaskit/spinner';
9
9
  import { useAutomationMenu } from '../../menu-context';
10
10
  const styles = {
11
- ruleButtonStyle: "_2rkoglpi _1h6dmuej _1dqonqa1 _189ee4h9",
12
- selectedRuleButtonStyle: "_2rkoglpi _1h6d15qp _1dqonqa1 _189e1bk5",
11
+ ruleButtonStyle: "_2rko12b0 _1h6dmuej _1dqonqa1 _189ee4h9",
12
+ selectedRuleButtonStyle: "_2rko12b0 _1h6d15qp _1dqonqa1 _189e1bk5",
13
13
  ruleNameStyle: "_4t3i1f4h"
14
14
  };
15
15
  export const AutomationModalRule = ({
@@ -1,6 +1,6 @@
1
1
 
2
2
  ._kkk2n7od{all:unset}._11c8dcr7{font:var(--ds-font-body-UNSAFE_small,normal 400 9pt/1pc ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Ubuntu,"Helvetica Neue",sans-serif)}
3
- ._2rkoglpi{border-radius:var(--ds-border-radius,4px)}
3
+ ._2rko12b0{border-radius:var(--ds-radius-small,4px)}
4
4
  ._18zru2gc{padding-inline:var(--ds-space-100,8px)}
5
5
  ._1rjc12x7{padding-block:var(--ds-space-075,6px)}
6
6
  ._18u0u2gc{margin-left:var(--ds-space-100,8px)}
@@ -6,7 +6,7 @@ import ErrorIcon from '@atlaskit/icon/core/migration/status-error--error';
6
6
  import { Box, Inline } from '@atlaskit/primitives/compiled';
7
7
  import MotionWrapper from '../../../common/motion-wrapper';
8
8
  const styles = {
9
- containerStyles: "_kkk2n7od _2rkoglpi _1rjc12x7 _18zru2gc _19pku2gc _2hwxu2gc _otyrze3t _18u0u2gc _1bsb1osq _fiawglyw",
9
+ containerStyles: "_kkk2n7od _2rko12b0 _1rjc12x7 _18zru2gc _19pku2gc _2hwxu2gc _otyrze3t _18u0u2gc _1bsb1osq _fiawglyw",
10
10
  errorContentStyles: "_bozgv77o",
11
11
  titleStyles: "_11c8dcr7 _syaz1gjq"
12
12
  };
@@ -1 +1 @@
1
- ._2rko1twn{border-radius:var(--ds-border-radius-circle,9999px)}
1
+ ._2rko1rr0{border-radius:var(--ds-radius-full,9999px)}
@@ -6,7 +6,7 @@ import { useEffect, useState } from 'react';
6
6
  import ImageLoader from 'react-render-image';
7
7
  import { LoadingSkeleton } from '../loading-skeleton';
8
8
  const styles = {
9
- roundImg: "_2rko1twn"
9
+ roundImg: "_2rko1rr0"
10
10
  };
11
11
  const ImageIcon = ({
12
12
  defaultIcon,
@@ -1,5 +1,5 @@
1
1
 
2
- ._2rkogqwt{border-radius:var(--ds-border-radius-050,2px)}._19bvze3t{padding-left:var(--ds-space-0,0)}
2
+ ._2rkolb4i{border-radius:var(--ds-radius-xsmall,2px)}._19bvze3t{padding-left:var(--ds-space-0,0)}
3
3
  ._bfhksm61{background-color:var(--ds-background-neutral-subtle,#00000000)}
4
4
  ._ca0qze3t{padding-top:var(--ds-space-0,0)}
5
5
  ._n3tdze3t{padding-bottom:var(--ds-space-0,0)}
@@ -16,7 +16,7 @@ import InlineLozenge from '../common/inline-lozenge';
16
16
  import { Frame } from '../Frame';
17
17
  import { IconAndTitleLayout } from '../IconAndTitleLayout';
18
18
  const styles = {
19
- actionButtonLozengeStyle: "_2rkogqwt _bfhksm61 _ca0qze3t _u5f3ze3t _n3tdze3t _19bvze3t _p12f1osq"
19
+ actionButtonLozengeStyle: "_2rkolb4i _bfhksm61 _ca0qze3t _u5f3ze3t _n3tdze3t _19bvze3t _p12f1osq"
20
20
  };
21
21
  const fallbackForbiddenIcon = () => {
22
22
  return /*#__PURE__*/React.createElement(LockLockedIcon, {
@@ -1,6 +1,5 @@
1
1
  ._11c81o8v{font:var(--ds-font-body-small,normal 400 11px/1pc ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Ubuntu,"Helvetica Neue",sans-serif)}
2
- ._2rko1twn{border-radius:var(--ds-border-radius-circle,9999px)}
3
- ._2rkogqwt{border-radius:var(--ds-border-radius-050,2px)}
2
+ ._2rko1rr0{border-radius:var(--ds-radius-full,9999px)}
4
3
  ._2rkolb4i{border-radius:var(--ds-radius-xsmall,2px)}
5
4
  ._154i1ssb{top:50%}
6
5
  ._16d9qvcn{-webkit-box-decoration-break:clone;box-decoration-break:clone}
@@ -18,9 +18,9 @@ const styles = {
18
18
  iconEmptyStyle: "_1bsb7vkz _4t3i1osq _1e0c1o8l _tzy4idpf",
19
19
  iconOuterWrapperStyle: "_1e0c1o8l _2hwx1b66 _kqswh2mm",
20
20
  iconTitleWrapperStyle: "_o5721jtm _1nmz9jpi _16d9qvcn _ca0qv77o _u5f31b66 _n3tdv77o _19bv1b66",
21
- linkStyle: "_2rkogqwt",
21
+ linkStyle: "_2rkolb4i",
22
22
  noLinkAppearanceStyle: "_syaz131l _18u01b66",
23
- roundImageStyle: "_2rko1twn"
23
+ roundImageStyle: "_2rko1rr0"
24
24
  };
25
25
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-styled,@atlaskit/design-system/no-html-anchor -- Ignored via go/DSP-18766
26
26
  const LinkAppearance = forwardRef(({
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ErrorBoundary } from 'react-error-boundary';
3
+ const withErrorBoundary = Component => props => {
4
+ return /*#__PURE__*/React.createElement(ErrorBoundary, {
5
+ fallback: null
6
+ }, /*#__PURE__*/React.createElement(Component, props));
7
+ };
8
+ export default withErrorBoundary;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * This is a scheduled batched register mechanism for resolving blue hyperlinks while the page is idle.
3
+ * i.e. SharePoint tenants with the same hostname will be grouped together before the register is made.
4
+ */
5
+
6
+ import { useCallback, useRef } from 'react';
7
+ const batchQueue = new Map();
8
+ const batchTimeouts = new Map();
9
+ const BATCH_DELAY = 250;
10
+ const executeBatch = hostname => {
11
+ const items = batchQueue.get(hostname) || [];
12
+ if (items.length === 0) {
13
+ return;
14
+ }
15
+ batchQueue.delete(hostname);
16
+ batchTimeouts.delete(hostname);
17
+ items.forEach(({
18
+ register,
19
+ resolve,
20
+ reject
21
+ }) => {
22
+ register().then(resolve).catch(reject);
23
+ });
24
+ };
25
+ const addToBatch = (hostname, item) => {
26
+ if (!batchQueue.has(hostname)) {
27
+ batchQueue.set(hostname, []);
28
+ }
29
+ batchQueue.get(hostname).push(item);
30
+ if (batchTimeouts.has(hostname)) {
31
+ clearTimeout(batchTimeouts.get(hostname));
32
+ }
33
+ batchTimeouts.set(hostname, setTimeout(() => {
34
+ executeBatch(hostname);
35
+ }, BATCH_DELAY));
36
+ };
37
+ export const useScheduledRegister = (href, register) => {
38
+ const isScheduled = useRef(false);
39
+ const scheduledRegister = useCallback(() => {
40
+ if (!href || !register || isScheduled.current) {
41
+ return Promise.resolve();
42
+ }
43
+ isScheduled.current = true;
44
+ return new Promise((resolve, reject) => {
45
+ const scheduleRegister = () => {
46
+ try {
47
+ const hostname = new URL(href).hostname;
48
+ addToBatch(hostname, {
49
+ href,
50
+ register,
51
+ resolve: value => {
52
+ isScheduled.current = false;
53
+ resolve(value);
54
+ },
55
+ reject: error => {
56
+ isScheduled.current = false;
57
+ reject(error);
58
+ }
59
+ });
60
+ } catch (error) {
61
+ isScheduled.current = false;
62
+ register().then(resolve).catch(reject);
63
+ }
64
+ };
65
+ if (typeof window !== 'undefined') {
66
+ if ('requestIdleCallback' in window) {
67
+ window.requestIdleCallback(scheduleRegister);
68
+ } else {
69
+ setTimeout(scheduleRegister, 0);
70
+ }
71
+ } else {
72
+ scheduleRegister();
73
+ }
74
+ });
75
+ }, [href, register]);
76
+ return scheduledRegister;
77
+ };
@@ -0,0 +1,26 @@
1
+ import React, { useContext } from 'react';
2
+ import FeatureGates from '@atlaskit/feature-gate-js-client';
3
+ import { SmartCardContext } from '../../../state';
4
+ import withErrorBoundary from './error-boundary';
5
+ import { ResolveHyperlink } from './resolve-hyperlink';
6
+ export const isSharePointDomain = href => {
7
+ try {
8
+ const hostname = new URL(href).hostname.toLowerCase();
9
+ return hostname.includes('sharepoint.com') || hostname.includes('onedrive.com') || hostname.includes('.live.com');
10
+ } catch {
11
+ return false;
12
+ }
13
+ };
14
+ const HyperlinkResolver = ({
15
+ href
16
+ }) => {
17
+ const hasSmartCardProvider = !!useContext(SmartCardContext);
18
+ const isHyperlinkResolveExperimentEnabled = FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_confluence', 'isEnabled', false) || FeatureGates.getExperimentValue('platform_editor_resolve_hyperlinks_jira', 'isEnabled', false);
19
+ if (!isSharePointDomain(href) || !hasSmartCardProvider || !isHyperlinkResolveExperimentEnabled) {
20
+ return null;
21
+ }
22
+ return /*#__PURE__*/React.createElement(ResolveHyperlink, {
23
+ href: href
24
+ });
25
+ };
26
+ export default withErrorBoundary(HyperlinkResolver);
@@ -0,0 +1,58 @@
1
+ import { useEffect, useState } from 'react';
2
+ import uuid from 'uuid';
3
+ import { useAnalyticsEvents } from '../../../common/analytics/generated/use-analytics-events';
4
+ import { useSmartCardActions } from '../../../state/actions';
5
+ import { getDefinitionId, getExtensionKey, getResourceType } from '../../../state/helpers';
6
+ import { useSmartCardState } from '../../../state/store';
7
+ import * as measure from '../../../utils/performance';
8
+ import { useScheduledRegister } from './hooks/useScheduledRegister';
9
+ export const ResolveHyperlink = ({
10
+ href
11
+ }) => {
12
+ const [id] = useState(() => uuid());
13
+ const state = useSmartCardState(href);
14
+ const definitionId = getDefinitionId(state.details);
15
+ const extensionKey = getExtensionKey(state.details);
16
+ const resourceType = getResourceType(state.details);
17
+ const {
18
+ register
19
+ } = useSmartCardActions(id, href);
20
+ const scheduledRegister = useScheduledRegister(href, register);
21
+ const {
22
+ fireEvent
23
+ } = useAnalyticsEvents();
24
+ useEffect(() => {
25
+ scheduledRegister().catch(error => {
26
+ throw error;
27
+ });
28
+ }, [scheduledRegister]);
29
+ useEffect(() => {
30
+ measure.mark(id, state.status);
31
+ if (state.status !== 'pending' && state.status !== 'resolving') {
32
+ var _state$error, _state$error2;
33
+ measure.create(id, state.status);
34
+ if (state.status === 'resolved') {
35
+ var _measure$getMeasure$d, _measure$getMeasure;
36
+ fireEvent('operational.hyperlink.resolved', {
37
+ definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null,
38
+ extensionKey: extensionKey !== null && extensionKey !== void 0 ? extensionKey : null,
39
+ resourceType: resourceType !== null && resourceType !== void 0 ? resourceType : null,
40
+ duration: (_measure$getMeasure$d = (_measure$getMeasure = measure.getMeasure(id, state.status)) === null || _measure$getMeasure === void 0 ? void 0 : _measure$getMeasure.duration) !== null && _measure$getMeasure$d !== void 0 ? _measure$getMeasure$d : null
41
+ });
42
+ } else if (((_state$error = state.error) === null || _state$error === void 0 ? void 0 : _state$error.type) !== 'ResolveUnsupportedError' && ((_state$error2 = state.error) === null || _state$error2 === void 0 ? void 0 : _state$error2.type) !== 'UnsupportedError') {
43
+ fireEvent('operational.hyperlink.unresolved', {
44
+ definitionId: definitionId !== null && definitionId !== void 0 ? definitionId : null,
45
+ extensionKey: extensionKey !== null && extensionKey !== void 0 ? extensionKey : null,
46
+ resourceType: resourceType !== null && resourceType !== void 0 ? resourceType : null,
47
+ reason: state.status,
48
+ error: state.error === undefined ? null : {
49
+ name: state.error.name,
50
+ kind: state.error.kind,
51
+ type: state.error.type
52
+ }
53
+ });
54
+ }
55
+ }
56
+ }, [id, state.status, state.error, definitionId, extensionKey, resourceType, fireEvent]);
57
+ return null;
58
+ };
@@ -2,14 +2,16 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React from 'react';
3
3
  import { di } from 'react-magnetic-di';
4
4
  import { withAnalyticsContext } from '@atlaskit/analytics-next';
5
+ import FeatureGates from '@atlaskit/feature-gate-js-client';
5
6
  import AKLink from '@atlaskit/link';
6
7
  import { withLinkClickedEvent } from '../../utils/analytics/click';
7
8
  import { LinkAnalyticsContext } from '../../utils/analytics/LinkAnalyticsContext';
9
+ import HyperlinkResolver from './HyperlinkResolver';
8
10
  import LinkWarningModal from './LinkWarningModal';
9
11
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
10
12
  const PACKAGE_DATA = {
11
13
  packageName: "@atlaskit/smart-card",
12
- packageVersion: "40.17.1",
14
+ packageVersion: "0.0.0-development",
13
15
  componentName: 'linkUrl'
14
16
  };
15
17
  const Anchor = withLinkClickedEvent('a');
@@ -21,6 +23,7 @@ const LinkUrl = ({
21
23
  onClick,
22
24
  testId = 'link-with-safety',
23
25
  isLinkComponent = false,
26
+ enableResolve = false,
24
27
  ...props
25
28
  }) => {
26
29
  const {
@@ -29,6 +32,7 @@ const LinkUrl = ({
29
32
  ...linkWarningModalProps
30
33
  } = useLinkWarningModal();
31
34
  const Link = isLinkComponent ? LinkComponent : Anchor;
35
+ const resolveHyperlinkFG = FeatureGates.checkGate('platform_editor_resolve_hyperlinks_killswitch');
32
36
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LinkAnalyticsContext, {
33
37
  url: href,
34
38
  display: "url"
@@ -51,6 +55,8 @@ const LinkUrl = ({
51
55
  showSafetyWarningModal(e, href);
52
56
  }
53
57
  }
54
- }, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps));
58
+ }, props), children)), checkSafety && /*#__PURE__*/React.createElement(LinkWarningModal, linkWarningModalProps), enableResolve && href && resolveHyperlinkFG && /*#__PURE__*/React.createElement(HyperlinkResolver, {
59
+ href: href
60
+ }));
55
61
  };
56
62
  export default withAnalyticsContext(PACKAGE_DATA)(LinkUrl);
@@ -1,11 +1,15 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
1
2
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
6
  import { extractPreview as extractPreviewData, extractSmartLinkAri, extractSmartLinkEmbed, extractSmartLinkProvider, extractSmartLinkTitle, extractSmartLinkUrl } from '@atlaskit/link-extractors';
4
7
  import { fg } from '@atlaskit/platform-feature-flags';
5
8
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
9
  import { ActionName, CardAction } from '../../index';
7
10
  import { getExtensionKey } from '../../state/helpers';
8
11
  import { canShowAction } from '../../utils/actions/can-show-action';
12
+ import { isModalWithinPreviewPanelIFrame } from '../../utils/iframe-utils';
9
13
  import { openEmbedModal } from '../../view/EmbedModal/utils';
10
14
  import { extractIsSupportTheming } from '../common/meta/extractIsSupportTheming';
11
15
  import { extractIsTrusted } from '../common/meta/extractIsTrusted';
@@ -30,6 +34,7 @@ export var extractInvokePreviewAction = function extractInvokePreviewAction(para
30
34
  var hasPreviewPanel = hasPreviewPanelParams && isPreviewPanelAvailable({
31
35
  ari: ari
32
36
  });
37
+ var isInPreviewPanel = expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && isModalWithinPreviewPanelIFrame();
33
38
  var data = response.data;
34
39
  var meta = response.meta;
35
40
  if (!canShowAction(CardAction.PreviewAction, actionOptions)) {
@@ -60,7 +65,7 @@ export var extractInvokePreviewAction = function extractInvokePreviewAction(para
60
65
  break;
61
66
  case 4:
62
67
  _context.next = 6;
63
- return openEmbedModal({
68
+ return openEmbedModal(_objectSpread({
64
69
  fireEvent: fireEvent,
65
70
  extensionKey: extensionKey,
66
71
  id: id,
@@ -76,7 +81,9 @@ export var extractInvokePreviewAction = function extractInvokePreviewAction(para
76
81
  title: extractSmartLinkTitle(response),
77
82
  url: url,
78
83
  size: fg('platform_linking_enable_card_preview_action_size') ? actionOptions === null || actionOptions === void 0 || (_actionOptions$previe = actionOptions.previewAction) === null || _actionOptions$previe === void 0 ? void 0 : _actionOptions$previe.size : undefined
79
- });
84
+ }, expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && {
85
+ isInPreviewPanel: isInPreviewPanel
86
+ }));
80
87
  case 6:
81
88
  case "end":
82
89
  return _context.stop();
@@ -4,6 +4,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  import { useMemo } from 'react';
5
5
  import uuid from 'uuid';
6
6
  import { useSmartLinkContext } from '@atlaskit/link-provider';
7
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
7
8
  import { useAnalyticsEvents } from '../../common/analytics/generated/use-analytics-events';
8
9
  import { extractInvokeDownloadAction } from '../../extractors/action/extract-invoke-download-action';
9
10
  import { extractInvokePreviewAction } from '../../extractors/action/extract-invoke-preview-action';
@@ -11,12 +12,14 @@ import { extractInvokeViewAction } from '../../extractors/action/extract-invoke-
11
12
  import { messages } from '../../messages';
12
13
  import { toAction } from '../../utils/actions/to-action';
13
14
  import useInvokeClientAction from '../hooks/use-invoke-client-action';
15
+ import useResolve from '../hooks/use-resolve';
14
16
  import { useSmartCardState as useLinkState } from '../store';
15
17
  export function useSmartLinkActions(_ref) {
16
18
  var url = _ref.url,
17
19
  appearance = _ref.appearance,
18
20
  origin = _ref.origin,
19
- actionOptions = _ref.actionOptions;
21
+ actionOptions = _ref.actionOptions,
22
+ prefetch = _ref.prefetch;
20
23
  var id = useMemo(function () {
21
24
  return uuid();
22
25
  }, []);
@@ -29,6 +32,10 @@ export function useSmartLinkActions(_ref) {
29
32
  var invokeClientAction = useInvokeClientAction({
30
33
  fireEvent: fireEvent
31
34
  });
35
+ var resolve = useResolve();
36
+ if (expValEquals('platform_hover_card_preview_panel', 'cohort', 'test') && prefetch && !linkState.details) {
37
+ resolve(url);
38
+ }
32
39
  if (linkState.details && !(actionOptions !== null && actionOptions !== void 0 && actionOptions.hide)) {
33
40
  var actions = [];
34
41
  var invokeParam = {