@atlaskit/modal-dialog 12.15.7 → 12.17.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 (30) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/internal/components/modal-dialog.js +15 -0
  3. package/dist/cjs/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element.js +84 -0
  4. package/dist/cjs/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external.js +31 -0
  5. package/dist/cjs/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/make-fix-for-adapter.js +123 -0
  6. package/dist/cjs/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection.js +104 -0
  7. package/dist/cjs/modal-wrapper.js +1 -1
  8. package/dist/es2019/internal/components/modal-dialog.js +17 -1
  9. package/dist/es2019/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element.js +80 -0
  10. package/dist/es2019/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external.js +27 -0
  11. package/dist/es2019/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/make-fix-for-adapter.js +116 -0
  12. package/dist/es2019/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection.js +100 -0
  13. package/dist/es2019/modal-wrapper.js +1 -1
  14. package/dist/esm/internal/components/modal-dialog.js +17 -1
  15. package/dist/esm/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element.js +78 -0
  16. package/dist/esm/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external.js +25 -0
  17. package/dist/esm/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/make-fix-for-adapter.js +116 -0
  18. package/dist/esm/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection.js +98 -0
  19. package/dist/esm/modal-wrapper.js +1 -1
  20. package/dist/types/internal/components/modal-dialog.d.ts +4 -0
  21. package/dist/types/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element.d.ts +2 -0
  22. package/dist/types/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external.d.ts +2 -0
  23. package/dist/types/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/make-fix-for-adapter.d.ts +11 -0
  24. package/dist/types/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection.d.ts +2 -0
  25. package/dist/types-ts4.5/internal/components/modal-dialog.d.ts +4 -0
  26. package/dist/types-ts4.5/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element.d.ts +2 -0
  27. package/dist/types-ts4.5/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external.d.ts +2 -0
  28. package/dist/types-ts4.5/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/make-fix-for-adapter.d.ts +11 -0
  29. package/dist/types-ts4.5/internal/pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection.d.ts +2 -0
  30. package/package.json +9 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/modal-dialog
2
2
 
3
+ ## 12.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#144047](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/144047)
8
+ [`de70c65e3e5ff`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/de70c65e3e5ff) -
9
+ The Chrome bug workaround shipped in `12.16.0` behind a feature flag is now turned on for everyone
10
+ and is no longer behind a feature flag.
11
+
12
+ ## 12.16.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#141279](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/141279)
17
+ [`a38f3af4bfc79`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a38f3af4bfc79) -
18
+ [ux] Adding a workaround for a Chrome bug where drag and drop cannot occur in an element
19
+ positioned on top of an `<iframe>` on a different origin. The workaround is being added behind a
20
+ feature flag.
21
+
3
22
  ## 12.15.7
4
23
 
5
24
  ### Patch Changes
@@ -17,12 +17,16 @@ var _useAutoFocus = _interopRequireDefault(require("@atlaskit/ds-lib/use-auto-fo
17
17
  var _focusRing = _interopRequireDefault(require("@atlaskit/focus-ring"));
18
18
  var _layering = require("@atlaskit/layering");
19
19
  var _fadeIn = _interopRequireDefault(require("@atlaskit/motion/fade-in"));
20
+ var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
20
21
  var _primitives = require("@atlaskit/primitives");
21
22
  var _colors = require("@atlaskit/theme/colors");
22
23
  var _tokens = require("@atlaskit/tokens");
23
24
  var _constants = require("../constants");
24
25
  var _context = require("../context");
25
26
  var _useOnMotionFinish3 = _interopRequireDefault(require("../hooks/use-on-motion-finish"));
27
+ var _element = require("../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element");
28
+ var _external = require("../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external");
29
+ var _textSelection = require("../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection");
26
30
  var _utils = require("../utils");
27
31
  var _positioner = _interopRequireDefault(require("./positioner"));
28
32
  var _css;
@@ -88,6 +92,17 @@ var ModalDialog = function ModalDialog(props) {
88
92
  testId = props.testId;
89
93
  var id = (0, _reactUid.useId)();
90
94
  var titleId = "modal-dialog-title-".concat(id);
95
+ (0, _react.useEffect)(function () {
96
+ // Modal dialogs can appear on top of iframe elements that are on another domain.
97
+ // There is a Chrome bug where drag and drop in an element on top of a cross domain
98
+ // iframe is not working. We are applying the workaround for this bug in modal so
99
+ // that consumers of our modal don't have to worry about this bug and are free to
100
+ // create whatever drag and drop experience they like inside a modal
101
+ //
102
+ // Chrome bug: https://issues.chromium.org/issues/362301053
103
+
104
+ return (0, _combine.combine)((0, _element.disableDraggingToCrossOriginIFramesForElement)(), (0, _textSelection.disableDraggingToCrossOriginIFramesForTextSelection)(), (0, _external.disableDraggingToCrossOriginIFramesForExternal)());
105
+ }, []);
91
106
  (0, _useAutoFocus.default)((0, _typeof2.default)(autoFocus) === 'object' ? autoFocus : undefined,
92
107
  // When a user supplies a ref to focus we enable this hook
93
108
  (0, _typeof2.default)(autoFocus) === 'object');
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.disableDraggingToCrossOriginIFramesForElement = disableDraggingToCrossOriginIFramesForElement;
7
+ var _bindEventListener = require("bind-event-listener");
8
+ var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
9
+ var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
10
+ var _makeFixForAdapter = require("./make-fix-for-adapter");
11
+ function watchForInteractionEnd(_ref) {
12
+ var stop = _ref.stop;
13
+ var isDragging = false;
14
+ function stopIfNotDragging() {
15
+ if (isDragging) {
16
+ return;
17
+ }
18
+ stop();
19
+ }
20
+ var unbindEvents = (0, _bindEventListener.bindAll)(window, [{
21
+ // Another interaction is starting, this fix should be removed.
22
+ type: 'pointerdown',
23
+ listener: stop
24
+ }, {
25
+ // The user did not start a drag
26
+ type: 'pointerup',
27
+ listener: stopIfNotDragging
28
+ }, {
29
+ // if a "dragstart" occurs and the flag is not set,
30
+ // then a drag has not started.
31
+ // Note: could not use "pointercancel" as it is not
32
+ // published in Safari
33
+ // → https://bugs.webkit.org/show_bug.cgi?id=222632
34
+ type: 'dragstart',
35
+ listener: stopIfNotDragging,
36
+ // Need to come after the element adapter
37
+ options: {
38
+ capture: false
39
+ }
40
+ }], {
41
+ // Listening in the capture phase to increase resilience
42
+ // against events being stopped.
43
+ capture: true,
44
+ // Being super clear these should only run once
45
+ once: true
46
+ });
47
+ var unbindMonitor = (0, _adapter.monitorForElements)({
48
+ onGenerateDragPreview: function onGenerateDragPreview() {
49
+ isDragging = true;
50
+ },
51
+ onDrop: function onDrop() {
52
+ isDragging = false;
53
+ stop();
54
+ }
55
+ });
56
+ return (0, _combine.combine)(unbindEvents, unbindMonitor);
57
+ }
58
+ function watchForInteractionStart(_ref2) {
59
+ var start = _ref2.start;
60
+ return (0, _bindEventListener.bind)(window, {
61
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
62
+ // Safari not publish a "pointerdown" on the interaction after a drag
63
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
64
+ type: 'mousedown',
65
+ listener: function listener(event) {
66
+ // Only starting if pressing down inside a draggable element
67
+ // At this point, we are not sure which if:
68
+ // 1. a text selection drag is starting
69
+ // 2. a draggable managed by pdnd is going to be dragged
70
+ // 3. a draggable not managed by pdnd is going to be dragged
71
+ // 4. The user will be dragging anything at all (might be doing a click)
72
+ if (event.target instanceof HTMLElement && event.target.closest('[draggable="true"]')) {
73
+ start();
74
+ }
75
+ }
76
+ });
77
+ }
78
+ var api = (0, _makeFixForAdapter.makeFixForAdapter)({
79
+ watchForInteractionStart: watchForInteractionStart,
80
+ watchForInteractionEnd: watchForInteractionEnd
81
+ });
82
+ function disableDraggingToCrossOriginIFramesForElement() {
83
+ return api.registerUsage();
84
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.disableDraggingToCrossOriginIFramesForExternal = disableDraggingToCrossOriginIFramesForExternal;
7
+ var _adapter = require("@atlaskit/pragmatic-drag-and-drop/external/adapter");
8
+ var _makeFixForAdapter = require("./make-fix-for-adapter");
9
+ function watchForInteractionStart(_ref) {
10
+ var start = _ref.start;
11
+ return (0, _adapter.monitorForExternal)({
12
+ onDragStart: function onDragStart() {
13
+ start();
14
+ }
15
+ });
16
+ }
17
+ function watchForInteractionEnd(_ref2) {
18
+ var stop = _ref2.stop;
19
+ return (0, _adapter.monitorForExternal)({
20
+ onDrop: function onDrop() {
21
+ stop();
22
+ }
23
+ });
24
+ }
25
+ var api = (0, _makeFixForAdapter.makeFixForAdapter)({
26
+ watchForInteractionStart: watchForInteractionStart,
27
+ watchForInteractionEnd: watchForInteractionEnd
28
+ });
29
+ function disableDraggingToCrossOriginIFramesForExternal() {
30
+ return api.registerUsage();
31
+ }
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.makeFixForAdapter = makeFixForAdapter;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
10
+ /**
11
+ * Set a `style` property on a `HTMLElement`
12
+ *
13
+ * @returns a `cleanup` function to restore the `style` property to it's original state
14
+ */
15
+ function setStyle(el, _ref) {
16
+ var property = _ref.property,
17
+ rule = _ref.rule,
18
+ _ref$priority = _ref.priority,
19
+ priority = _ref$priority === void 0 ? '' : _ref$priority;
20
+ var originalValue = el.style.getPropertyValue(property);
21
+ var originalPriority = el.style.getPropertyPriority(property);
22
+ el.style.setProperty(property, rule, priority);
23
+ return function cleanup() {
24
+ el.style.setProperty(property, originalValue, originalPriority);
25
+ };
26
+ }
27
+ function hasSameOrigin(href1, href2) {
28
+ var url1;
29
+ var url2;
30
+ try {
31
+ url1 = new URL(href1);
32
+ url2 = new URL(href2);
33
+ } catch (error) {
34
+ // failed to parse a href
35
+ return false;
36
+ }
37
+
38
+ // https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
39
+ return url1.protocol === url2.protocol && url1.host === url2.host && url1.port === url2.port;
40
+ }
41
+ function isIframeOnAnotherDomain(iframe) {
42
+ /**
43
+ * iframe with contents defined inline. Runs on the current origin.
44
+ * `<iframe srcdoc="<!doctype html><body>Hello</body>" />`
45
+ */
46
+ if (iframe.srcdoc) {
47
+ return false;
48
+ }
49
+
50
+ /**
51
+ * iframe with contents defined inline. Runs on the current origin.
52
+ * `<iframe src={`data:text/html;charset=utf-8,${encodeURI('<!doctype html><body>Hello</body>')}`} />`
53
+ */
54
+ if (iframe.src.startsWith('data:')) {
55
+ return false;
56
+ }
57
+ return !hasSameOrigin(window.location.href, iframe.src);
58
+ }
59
+ var registry = new Map();
60
+ function applyFix(watchForEndOfInteraction) {
61
+ var iframes = Array.from(document.querySelectorAll('iframe')).filter(isIframeOnAnotherDomain);
62
+ var cleanups = iframes.map(function (iframe) {
63
+ var entry = registry.get(iframe);
64
+ if (!entry) {
65
+ entry = {
66
+ reset: setStyle(iframe, {
67
+ property: 'pointer-events',
68
+ rule: 'none',
69
+ priority: 'important'
70
+ }),
71
+ count: 1
72
+ };
73
+ registry.set(iframe, entry);
74
+ } else {
75
+ // pointer-events:none already applied to the iframe
76
+ // increment how many things requested the fix
77
+ entry.count++;
78
+ }
79
+ return function cleanup() {
80
+ entry.count--;
81
+ if (entry.count < 1) {
82
+ entry.reset();
83
+ registry.delete(iframe);
84
+ }
85
+ };
86
+ });
87
+ function stop() {
88
+ cleanupWatcher();
89
+ _combine.combine.apply(void 0, (0, _toConsumableArray2.default)(cleanups))();
90
+ }
91
+ var cleanupWatcher = watchForEndOfInteraction({
92
+ stop: stop
93
+ });
94
+ }
95
+ function makeFixForAdapter(_ref2) {
96
+ var watchForInteractionStart = _ref2.watchForInteractionStart,
97
+ watchForInteractionEnd = _ref2.watchForInteractionEnd;
98
+ var registrationCount = 0;
99
+ var stopWatchingInteractionStart = null;
100
+ function start() {
101
+ applyFix(watchForInteractionEnd);
102
+ }
103
+ function registerUsage() {
104
+ if (registrationCount === 0) {
105
+ stopWatchingInteractionStart = watchForInteractionStart({
106
+ start: start
107
+ });
108
+ }
109
+ registrationCount++;
110
+ return function unregisterUsage() {
111
+ var _stopWatchingInteract;
112
+ registrationCount--;
113
+ if (registrationCount !== 0) {
114
+ return;
115
+ }
116
+ (_stopWatchingInteract = stopWatchingInteractionStart) === null || _stopWatchingInteract === void 0 || _stopWatchingInteract();
117
+ stopWatchingInteractionStart = null;
118
+ };
119
+ }
120
+ return {
121
+ registerUsage: registerUsage
122
+ };
123
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.disableDraggingToCrossOriginIFramesForTextSelection = disableDraggingToCrossOriginIFramesForTextSelection;
7
+ var _bindEventListener = require("bind-event-listener");
8
+ var _combine = require("@atlaskit/pragmatic-drag-and-drop/combine");
9
+ var _adapter = require("@atlaskit/pragmatic-drag-and-drop/text-selection/adapter");
10
+ var _makeFixForAdapter = require("./make-fix-for-adapter");
11
+ function watchForInteractionEnd(_ref) {
12
+ var stop = _ref.stop;
13
+ var isDragging = false;
14
+ function stopIfNotDragging() {
15
+ if (isDragging) {
16
+ return;
17
+ }
18
+ stop();
19
+ }
20
+ var frameId = null;
21
+ var unbindEvents = (0, _bindEventListener.bindAll)(window, [{
22
+ // User is starting another interaction
23
+ type: 'pointerdown',
24
+ listener: stop
25
+ }, {
26
+ // User did not start a drag.
27
+ // "pointerdown" won't be fired if a drag started
28
+ type: 'pointerup',
29
+ listener: stopIfNotDragging
30
+ }, {
31
+ type: 'dragstart',
32
+ listener: function listener() {
33
+ /**
34
+ * The pdnd `onDragStart()` fires in the frame after "dragstart"
35
+ * So we are delaying our isDragging check to give a chance
36
+ * for `onDragStart()` to set the value correctly.
37
+ *
38
+ * Note: could not use "pointercancel" as it is not
39
+ * published in Safari → https://bugs.webkit.org/show_bug.cgi?id=222632
40
+ */
41
+ frameId = requestAnimationFrame(function () {
42
+ frameId = null;
43
+ stopIfNotDragging();
44
+ });
45
+ },
46
+ // need to schedule our frame after the text-selection
47
+ // adapter queues it's `onDragStart` frame.
48
+ options: {
49
+ capture: false
50
+ }
51
+ }], {
52
+ // Listening in the capture phase to increase resilience
53
+ // against events being stopped.
54
+ capture: true,
55
+ // being super clear these should only run once
56
+ once: true
57
+ });
58
+ var unbindMonitor = (0, _adapter.monitorForTextSelection)({
59
+ onDragStart: function onDragStart() {
60
+ isDragging = true;
61
+ },
62
+ onDrop: function onDrop() {
63
+ isDragging = false;
64
+ stop();
65
+ }
66
+ });
67
+ return (0, _combine.combine)(unbindEvents, unbindMonitor, function abortFrame() {
68
+ if (frameId != null) {
69
+ cancelAnimationFrame(frameId);
70
+ }
71
+ });
72
+ }
73
+ function watchForInteractionStart(_ref2) {
74
+ var start = _ref2.start;
75
+ return (0, _bindEventListener.bind)(window, {
76
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
77
+ // Safari not publish a "pointerdown" on the interaction after a drag
78
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
79
+ type: 'mousedown',
80
+ listener: function listener() {
81
+ // A text selection drag will only start when there is
82
+ // an active text selection.
83
+ var selection = window.getSelection();
84
+
85
+ // No selection object found
86
+ if (!selection) {
87
+ return;
88
+ }
89
+
90
+ // `isCollapsed` is "true" if there is currently no selected text
91
+ if (selection.isCollapsed) {
92
+ return;
93
+ }
94
+ start();
95
+ }
96
+ });
97
+ }
98
+ var api = (0, _makeFixForAdapter.makeFixForAdapter)({
99
+ watchForInteractionStart: watchForInteractionStart,
100
+ watchForInteractionEnd: watchForInteractionEnd
101
+ });
102
+ function disableDraggingToCrossOriginIFramesForTextSelection() {
103
+ return api.registerUsage();
104
+ }
@@ -102,7 +102,7 @@ var ModalWrapper = function ModalWrapper(props) {
102
102
  action: 'closed',
103
103
  componentName: 'modalDialog',
104
104
  packageName: "@atlaskit/modal-dialog",
105
- packageVersion: "12.15.7"
105
+ packageVersion: "12.17.0"
106
106
  });
107
107
  var onBlanketClicked = (0, _react.useCallback)(function (e) {
108
108
  if (shouldCloseOnOverlayClick) {
@@ -3,7 +3,8 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  * @jsxRuntime classic
4
4
  * @jsx jsx
5
5
  */
6
- import { useMemo } from 'react';
6
+
7
+ import { useEffect, useMemo } from 'react';
7
8
  import { css, jsx } from '@emotion/react';
8
9
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
9
10
  import { useId } from '@atlaskit/ds-lib/react-uid';
@@ -11,12 +12,16 @@ import useAutoFocus from '@atlaskit/ds-lib/use-auto-focus';
11
12
  import FocusRing from '@atlaskit/focus-ring';
12
13
  import { UNSAFE_useLayering, useCloseOnEscapePress } from '@atlaskit/layering';
13
14
  import FadeIn from '@atlaskit/motion/fade-in';
15
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
14
16
  import { media } from '@atlaskit/primitives';
15
17
  import { N0, N30A, N60A } from '@atlaskit/theme/colors';
16
18
  import { CURRENT_SURFACE_CSS_VAR } from '@atlaskit/tokens';
17
19
  import { borderRadius, textColor } from '../constants';
18
20
  import { ModalContext, ScrollContext } from '../context';
19
21
  import useOnMotionFinish from '../hooks/use-on-motion-finish';
22
+ import { disableDraggingToCrossOriginIFramesForElement } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element';
23
+ import { disableDraggingToCrossOriginIFramesForExternal } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external';
24
+ import { disableDraggingToCrossOriginIFramesForTextSelection } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection';
20
25
  import { dialogHeight, dialogWidth } from '../utils';
21
26
  import Positioner from './positioner';
22
27
  const dialogStyles = css({
@@ -89,6 +94,17 @@ const ModalDialog = props => {
89
94
  } = props;
90
95
  const id = useId();
91
96
  const titleId = `modal-dialog-title-${id}`;
97
+ useEffect(() => {
98
+ // Modal dialogs can appear on top of iframe elements that are on another domain.
99
+ // There is a Chrome bug where drag and drop in an element on top of a cross domain
100
+ // iframe is not working. We are applying the workaround for this bug in modal so
101
+ // that consumers of our modal don't have to worry about this bug and are free to
102
+ // create whatever drag and drop experience they like inside a modal
103
+ //
104
+ // Chrome bug: https://issues.chromium.org/issues/362301053
105
+
106
+ return combine(disableDraggingToCrossOriginIFramesForElement(), disableDraggingToCrossOriginIFramesForTextSelection(), disableDraggingToCrossOriginIFramesForExternal());
107
+ }, []);
92
108
  useAutoFocus(typeof autoFocus === 'object' ? autoFocus : undefined,
93
109
  // When a user supplies a ref to focus we enable this hook
94
110
  typeof autoFocus === 'object');
@@ -0,0 +1,80 @@
1
+ import { bind, bindAll } from 'bind-event-listener';
2
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
3
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
4
+ import { makeFixForAdapter } from './make-fix-for-adapter';
5
+ function watchForInteractionEnd({
6
+ stop
7
+ }) {
8
+ let isDragging = false;
9
+ function stopIfNotDragging() {
10
+ if (isDragging) {
11
+ return;
12
+ }
13
+ stop();
14
+ }
15
+ const unbindEvents = bindAll(window, [{
16
+ // Another interaction is starting, this fix should be removed.
17
+ type: 'pointerdown',
18
+ listener: stop
19
+ }, {
20
+ // The user did not start a drag
21
+ type: 'pointerup',
22
+ listener: stopIfNotDragging
23
+ }, {
24
+ // if a "dragstart" occurs and the flag is not set,
25
+ // then a drag has not started.
26
+ // Note: could not use "pointercancel" as it is not
27
+ // published in Safari
28
+ // → https://bugs.webkit.org/show_bug.cgi?id=222632
29
+ type: 'dragstart',
30
+ listener: stopIfNotDragging,
31
+ // Need to come after the element adapter
32
+ options: {
33
+ capture: false
34
+ }
35
+ }], {
36
+ // Listening in the capture phase to increase resilience
37
+ // against events being stopped.
38
+ capture: true,
39
+ // Being super clear these should only run once
40
+ once: true
41
+ });
42
+ const unbindMonitor = monitorForElements({
43
+ onGenerateDragPreview() {
44
+ isDragging = true;
45
+ },
46
+ onDrop() {
47
+ isDragging = false;
48
+ stop();
49
+ }
50
+ });
51
+ return combine(unbindEvents, unbindMonitor);
52
+ }
53
+ function watchForInteractionStart({
54
+ start
55
+ }) {
56
+ return bind(window, {
57
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
58
+ // Safari not publish a "pointerdown" on the interaction after a drag
59
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
60
+ type: 'mousedown',
61
+ listener(event) {
62
+ // Only starting if pressing down inside a draggable element
63
+ // At this point, we are not sure which if:
64
+ // 1. a text selection drag is starting
65
+ // 2. a draggable managed by pdnd is going to be dragged
66
+ // 3. a draggable not managed by pdnd is going to be dragged
67
+ // 4. The user will be dragging anything at all (might be doing a click)
68
+ if (event.target instanceof HTMLElement && event.target.closest('[draggable="true"]')) {
69
+ start();
70
+ }
71
+ }
72
+ });
73
+ }
74
+ const api = makeFixForAdapter({
75
+ watchForInteractionStart,
76
+ watchForInteractionEnd
77
+ });
78
+ export function disableDraggingToCrossOriginIFramesForElement() {
79
+ return api.registerUsage();
80
+ }
@@ -0,0 +1,27 @@
1
+ import { monitorForExternal } from '@atlaskit/pragmatic-drag-and-drop/external/adapter';
2
+ import { makeFixForAdapter } from './make-fix-for-adapter';
3
+ function watchForInteractionStart({
4
+ start
5
+ }) {
6
+ return monitorForExternal({
7
+ onDragStart() {
8
+ start();
9
+ }
10
+ });
11
+ }
12
+ function watchForInteractionEnd({
13
+ stop
14
+ }) {
15
+ return monitorForExternal({
16
+ onDrop() {
17
+ stop();
18
+ }
19
+ });
20
+ }
21
+ const api = makeFixForAdapter({
22
+ watchForInteractionStart,
23
+ watchForInteractionEnd
24
+ });
25
+ export function disableDraggingToCrossOriginIFramesForExternal() {
26
+ return api.registerUsage();
27
+ }
@@ -0,0 +1,116 @@
1
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
2
+ /**
3
+ * Set a `style` property on a `HTMLElement`
4
+ *
5
+ * @returns a `cleanup` function to restore the `style` property to it's original state
6
+ */
7
+ function setStyle(el, {
8
+ property,
9
+ rule,
10
+ priority = ''
11
+ }) {
12
+ const originalValue = el.style.getPropertyValue(property);
13
+ const originalPriority = el.style.getPropertyPriority(property);
14
+ el.style.setProperty(property, rule, priority);
15
+ return function cleanup() {
16
+ el.style.setProperty(property, originalValue, originalPriority);
17
+ };
18
+ }
19
+ function hasSameOrigin(href1, href2) {
20
+ let url1;
21
+ let url2;
22
+ try {
23
+ url1 = new URL(href1);
24
+ url2 = new URL(href2);
25
+ } catch (error) {
26
+ // failed to parse a href
27
+ return false;
28
+ }
29
+
30
+ // https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
31
+ return url1.protocol === url2.protocol && url1.host === url2.host && url1.port === url2.port;
32
+ }
33
+ function isIframeOnAnotherDomain(iframe) {
34
+ /**
35
+ * iframe with contents defined inline. Runs on the current origin.
36
+ * `<iframe srcdoc="<!doctype html><body>Hello</body>" />`
37
+ */
38
+ if (iframe.srcdoc) {
39
+ return false;
40
+ }
41
+
42
+ /**
43
+ * iframe with contents defined inline. Runs on the current origin.
44
+ * `<iframe src={`data:text/html;charset=utf-8,${encodeURI('<!doctype html><body>Hello</body>')}`} />`
45
+ */
46
+ if (iframe.src.startsWith('data:')) {
47
+ return false;
48
+ }
49
+ return !hasSameOrigin(window.location.href, iframe.src);
50
+ }
51
+ const registry = new Map();
52
+ function applyFix(watchForEndOfInteraction) {
53
+ const iframes = Array.from(document.querySelectorAll('iframe')).filter(isIframeOnAnotherDomain);
54
+ const cleanups = iframes.map(iframe => {
55
+ let entry = registry.get(iframe);
56
+ if (!entry) {
57
+ entry = {
58
+ reset: setStyle(iframe, {
59
+ property: 'pointer-events',
60
+ rule: 'none',
61
+ priority: 'important'
62
+ }),
63
+ count: 1
64
+ };
65
+ registry.set(iframe, entry);
66
+ } else {
67
+ // pointer-events:none already applied to the iframe
68
+ // increment how many things requested the fix
69
+ entry.count++;
70
+ }
71
+ return function cleanup() {
72
+ entry.count--;
73
+ if (entry.count < 1) {
74
+ entry.reset();
75
+ registry.delete(iframe);
76
+ }
77
+ };
78
+ });
79
+ function stop() {
80
+ cleanupWatcher();
81
+ combine(...cleanups)();
82
+ }
83
+ const cleanupWatcher = watchForEndOfInteraction({
84
+ stop
85
+ });
86
+ }
87
+ export function makeFixForAdapter({
88
+ watchForInteractionStart,
89
+ watchForInteractionEnd
90
+ }) {
91
+ let registrationCount = 0;
92
+ let stopWatchingInteractionStart = null;
93
+ function start() {
94
+ applyFix(watchForInteractionEnd);
95
+ }
96
+ function registerUsage() {
97
+ if (registrationCount === 0) {
98
+ stopWatchingInteractionStart = watchForInteractionStart({
99
+ start
100
+ });
101
+ }
102
+ registrationCount++;
103
+ return function unregisterUsage() {
104
+ var _stopWatchingInteract;
105
+ registrationCount--;
106
+ if (registrationCount !== 0) {
107
+ return;
108
+ }
109
+ (_stopWatchingInteract = stopWatchingInteractionStart) === null || _stopWatchingInteract === void 0 ? void 0 : _stopWatchingInteract();
110
+ stopWatchingInteractionStart = null;
111
+ };
112
+ }
113
+ return {
114
+ registerUsage
115
+ };
116
+ }
@@ -0,0 +1,100 @@
1
+ import { bind, bindAll } from 'bind-event-listener';
2
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
3
+ import { monitorForTextSelection } from '@atlaskit/pragmatic-drag-and-drop/text-selection/adapter';
4
+ import { makeFixForAdapter } from './make-fix-for-adapter';
5
+ function watchForInteractionEnd({
6
+ stop
7
+ }) {
8
+ let isDragging = false;
9
+ function stopIfNotDragging() {
10
+ if (isDragging) {
11
+ return;
12
+ }
13
+ stop();
14
+ }
15
+ let frameId = null;
16
+ const unbindEvents = bindAll(window, [{
17
+ // User is starting another interaction
18
+ type: 'pointerdown',
19
+ listener: stop
20
+ }, {
21
+ // User did not start a drag.
22
+ // "pointerdown" won't be fired if a drag started
23
+ type: 'pointerup',
24
+ listener: stopIfNotDragging
25
+ }, {
26
+ type: 'dragstart',
27
+ listener() {
28
+ /**
29
+ * The pdnd `onDragStart()` fires in the frame after "dragstart"
30
+ * So we are delaying our isDragging check to give a chance
31
+ * for `onDragStart()` to set the value correctly.
32
+ *
33
+ * Note: could not use "pointercancel" as it is not
34
+ * published in Safari → https://bugs.webkit.org/show_bug.cgi?id=222632
35
+ */
36
+ frameId = requestAnimationFrame(() => {
37
+ frameId = null;
38
+ stopIfNotDragging();
39
+ });
40
+ },
41
+ // need to schedule our frame after the text-selection
42
+ // adapter queues it's `onDragStart` frame.
43
+ options: {
44
+ capture: false
45
+ }
46
+ }], {
47
+ // Listening in the capture phase to increase resilience
48
+ // against events being stopped.
49
+ capture: true,
50
+ // being super clear these should only run once
51
+ once: true
52
+ });
53
+ const unbindMonitor = monitorForTextSelection({
54
+ onDragStart() {
55
+ isDragging = true;
56
+ },
57
+ onDrop() {
58
+ isDragging = false;
59
+ stop();
60
+ }
61
+ });
62
+ return combine(unbindEvents, unbindMonitor, function abortFrame() {
63
+ if (frameId != null) {
64
+ cancelAnimationFrame(frameId);
65
+ }
66
+ });
67
+ }
68
+ function watchForInteractionStart({
69
+ start
70
+ }) {
71
+ return bind(window, {
72
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
73
+ // Safari not publish a "pointerdown" on the interaction after a drag
74
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
75
+ type: 'mousedown',
76
+ listener() {
77
+ // A text selection drag will only start when there is
78
+ // an active text selection.
79
+ const selection = window.getSelection();
80
+
81
+ // No selection object found
82
+ if (!selection) {
83
+ return;
84
+ }
85
+
86
+ // `isCollapsed` is "true" if there is currently no selected text
87
+ if (selection.isCollapsed) {
88
+ return;
89
+ }
90
+ start();
91
+ }
92
+ });
93
+ }
94
+ const api = makeFixForAdapter({
95
+ watchForInteractionStart,
96
+ watchForInteractionEnd
97
+ });
98
+ export function disableDraggingToCrossOriginIFramesForTextSelection() {
99
+ return api.registerUsage();
100
+ }
@@ -87,7 +87,7 @@ const ModalWrapper = props => {
87
87
  action: 'closed',
88
88
  componentName: 'modalDialog',
89
89
  packageName: "@atlaskit/modal-dialog",
90
- packageVersion: "12.15.7"
90
+ packageVersion: "12.17.0"
91
91
  });
92
92
  const onBlanketClicked = useCallback(e => {
93
93
  if (shouldCloseOnOverlayClick) {
@@ -7,7 +7,8 @@ var _css;
7
7
  * @jsxRuntime classic
8
8
  * @jsx jsx
9
9
  */
10
- import { useMemo } from 'react';
10
+
11
+ import { useEffect, useMemo } from 'react';
11
12
  import { css, jsx } from '@emotion/react';
12
13
  import mergeRefs from '@atlaskit/ds-lib/merge-refs';
13
14
  import { useId } from '@atlaskit/ds-lib/react-uid';
@@ -15,12 +16,16 @@ import useAutoFocus from '@atlaskit/ds-lib/use-auto-focus';
15
16
  import FocusRing from '@atlaskit/focus-ring';
16
17
  import { UNSAFE_useLayering, useCloseOnEscapePress } from '@atlaskit/layering';
17
18
  import FadeIn from '@atlaskit/motion/fade-in';
19
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
18
20
  import { media } from '@atlaskit/primitives';
19
21
  import { N0, N30A, N60A } from '@atlaskit/theme/colors';
20
22
  import { CURRENT_SURFACE_CSS_VAR } from '@atlaskit/tokens';
21
23
  import { borderRadius, textColor } from '../constants';
22
24
  import { ModalContext, ScrollContext } from '../context';
23
25
  import useOnMotionFinish from '../hooks/use-on-motion-finish';
26
+ import { disableDraggingToCrossOriginIFramesForElement } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/element';
27
+ import { disableDraggingToCrossOriginIFramesForExternal } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/external';
28
+ import { disableDraggingToCrossOriginIFramesForTextSelection } from '../pragmatic-drag-and-drop/disable-dragging-to-cross-origin-iframes/text-selection';
24
29
  import { dialogHeight, dialogWidth } from '../utils';
25
30
  import Positioner from './positioner';
26
31
  var dialogStyles = css((_css = {
@@ -81,6 +86,17 @@ var ModalDialog = function ModalDialog(props) {
81
86
  testId = props.testId;
82
87
  var id = useId();
83
88
  var titleId = "modal-dialog-title-".concat(id);
89
+ useEffect(function () {
90
+ // Modal dialogs can appear on top of iframe elements that are on another domain.
91
+ // There is a Chrome bug where drag and drop in an element on top of a cross domain
92
+ // iframe is not working. We are applying the workaround for this bug in modal so
93
+ // that consumers of our modal don't have to worry about this bug and are free to
94
+ // create whatever drag and drop experience they like inside a modal
95
+ //
96
+ // Chrome bug: https://issues.chromium.org/issues/362301053
97
+
98
+ return combine(disableDraggingToCrossOriginIFramesForElement(), disableDraggingToCrossOriginIFramesForTextSelection(), disableDraggingToCrossOriginIFramesForExternal());
99
+ }, []);
84
100
  useAutoFocus(_typeof(autoFocus) === 'object' ? autoFocus : undefined,
85
101
  // When a user supplies a ref to focus we enable this hook
86
102
  _typeof(autoFocus) === 'object');
@@ -0,0 +1,78 @@
1
+ import { bind, bindAll } from 'bind-event-listener';
2
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
3
+ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
4
+ import { makeFixForAdapter } from './make-fix-for-adapter';
5
+ function watchForInteractionEnd(_ref) {
6
+ var stop = _ref.stop;
7
+ var isDragging = false;
8
+ function stopIfNotDragging() {
9
+ if (isDragging) {
10
+ return;
11
+ }
12
+ stop();
13
+ }
14
+ var unbindEvents = bindAll(window, [{
15
+ // Another interaction is starting, this fix should be removed.
16
+ type: 'pointerdown',
17
+ listener: stop
18
+ }, {
19
+ // The user did not start a drag
20
+ type: 'pointerup',
21
+ listener: stopIfNotDragging
22
+ }, {
23
+ // if a "dragstart" occurs and the flag is not set,
24
+ // then a drag has not started.
25
+ // Note: could not use "pointercancel" as it is not
26
+ // published in Safari
27
+ // → https://bugs.webkit.org/show_bug.cgi?id=222632
28
+ type: 'dragstart',
29
+ listener: stopIfNotDragging,
30
+ // Need to come after the element adapter
31
+ options: {
32
+ capture: false
33
+ }
34
+ }], {
35
+ // Listening in the capture phase to increase resilience
36
+ // against events being stopped.
37
+ capture: true,
38
+ // Being super clear these should only run once
39
+ once: true
40
+ });
41
+ var unbindMonitor = monitorForElements({
42
+ onGenerateDragPreview: function onGenerateDragPreview() {
43
+ isDragging = true;
44
+ },
45
+ onDrop: function onDrop() {
46
+ isDragging = false;
47
+ stop();
48
+ }
49
+ });
50
+ return combine(unbindEvents, unbindMonitor);
51
+ }
52
+ function watchForInteractionStart(_ref2) {
53
+ var start = _ref2.start;
54
+ return bind(window, {
55
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
56
+ // Safari not publish a "pointerdown" on the interaction after a drag
57
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
58
+ type: 'mousedown',
59
+ listener: function listener(event) {
60
+ // Only starting if pressing down inside a draggable element
61
+ // At this point, we are not sure which if:
62
+ // 1. a text selection drag is starting
63
+ // 2. a draggable managed by pdnd is going to be dragged
64
+ // 3. a draggable not managed by pdnd is going to be dragged
65
+ // 4. The user will be dragging anything at all (might be doing a click)
66
+ if (event.target instanceof HTMLElement && event.target.closest('[draggable="true"]')) {
67
+ start();
68
+ }
69
+ }
70
+ });
71
+ }
72
+ var api = makeFixForAdapter({
73
+ watchForInteractionStart: watchForInteractionStart,
74
+ watchForInteractionEnd: watchForInteractionEnd
75
+ });
76
+ export function disableDraggingToCrossOriginIFramesForElement() {
77
+ return api.registerUsage();
78
+ }
@@ -0,0 +1,25 @@
1
+ import { monitorForExternal } from '@atlaskit/pragmatic-drag-and-drop/external/adapter';
2
+ import { makeFixForAdapter } from './make-fix-for-adapter';
3
+ function watchForInteractionStart(_ref) {
4
+ var start = _ref.start;
5
+ return monitorForExternal({
6
+ onDragStart: function onDragStart() {
7
+ start();
8
+ }
9
+ });
10
+ }
11
+ function watchForInteractionEnd(_ref2) {
12
+ var stop = _ref2.stop;
13
+ return monitorForExternal({
14
+ onDrop: function onDrop() {
15
+ stop();
16
+ }
17
+ });
18
+ }
19
+ var api = makeFixForAdapter({
20
+ watchForInteractionStart: watchForInteractionStart,
21
+ watchForInteractionEnd: watchForInteractionEnd
22
+ });
23
+ export function disableDraggingToCrossOriginIFramesForExternal() {
24
+ return api.registerUsage();
25
+ }
@@ -0,0 +1,116 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
3
+ /**
4
+ * Set a `style` property on a `HTMLElement`
5
+ *
6
+ * @returns a `cleanup` function to restore the `style` property to it's original state
7
+ */
8
+ function setStyle(el, _ref) {
9
+ var property = _ref.property,
10
+ rule = _ref.rule,
11
+ _ref$priority = _ref.priority,
12
+ priority = _ref$priority === void 0 ? '' : _ref$priority;
13
+ var originalValue = el.style.getPropertyValue(property);
14
+ var originalPriority = el.style.getPropertyPriority(property);
15
+ el.style.setProperty(property, rule, priority);
16
+ return function cleanup() {
17
+ el.style.setProperty(property, originalValue, originalPriority);
18
+ };
19
+ }
20
+ function hasSameOrigin(href1, href2) {
21
+ var url1;
22
+ var url2;
23
+ try {
24
+ url1 = new URL(href1);
25
+ url2 = new URL(href2);
26
+ } catch (error) {
27
+ // failed to parse a href
28
+ return false;
29
+ }
30
+
31
+ // https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
32
+ return url1.protocol === url2.protocol && url1.host === url2.host && url1.port === url2.port;
33
+ }
34
+ function isIframeOnAnotherDomain(iframe) {
35
+ /**
36
+ * iframe with contents defined inline. Runs on the current origin.
37
+ * `<iframe srcdoc="<!doctype html><body>Hello</body>" />`
38
+ */
39
+ if (iframe.srcdoc) {
40
+ return false;
41
+ }
42
+
43
+ /**
44
+ * iframe with contents defined inline. Runs on the current origin.
45
+ * `<iframe src={`data:text/html;charset=utf-8,${encodeURI('<!doctype html><body>Hello</body>')}`} />`
46
+ */
47
+ if (iframe.src.startsWith('data:')) {
48
+ return false;
49
+ }
50
+ return !hasSameOrigin(window.location.href, iframe.src);
51
+ }
52
+ var registry = new Map();
53
+ function applyFix(watchForEndOfInteraction) {
54
+ var iframes = Array.from(document.querySelectorAll('iframe')).filter(isIframeOnAnotherDomain);
55
+ var cleanups = iframes.map(function (iframe) {
56
+ var entry = registry.get(iframe);
57
+ if (!entry) {
58
+ entry = {
59
+ reset: setStyle(iframe, {
60
+ property: 'pointer-events',
61
+ rule: 'none',
62
+ priority: 'important'
63
+ }),
64
+ count: 1
65
+ };
66
+ registry.set(iframe, entry);
67
+ } else {
68
+ // pointer-events:none already applied to the iframe
69
+ // increment how many things requested the fix
70
+ entry.count++;
71
+ }
72
+ return function cleanup() {
73
+ entry.count--;
74
+ if (entry.count < 1) {
75
+ entry.reset();
76
+ registry.delete(iframe);
77
+ }
78
+ };
79
+ });
80
+ function stop() {
81
+ cleanupWatcher();
82
+ combine.apply(void 0, _toConsumableArray(cleanups))();
83
+ }
84
+ var cleanupWatcher = watchForEndOfInteraction({
85
+ stop: stop
86
+ });
87
+ }
88
+ export function makeFixForAdapter(_ref2) {
89
+ var watchForInteractionStart = _ref2.watchForInteractionStart,
90
+ watchForInteractionEnd = _ref2.watchForInteractionEnd;
91
+ var registrationCount = 0;
92
+ var stopWatchingInteractionStart = null;
93
+ function start() {
94
+ applyFix(watchForInteractionEnd);
95
+ }
96
+ function registerUsage() {
97
+ if (registrationCount === 0) {
98
+ stopWatchingInteractionStart = watchForInteractionStart({
99
+ start: start
100
+ });
101
+ }
102
+ registrationCount++;
103
+ return function unregisterUsage() {
104
+ var _stopWatchingInteract;
105
+ registrationCount--;
106
+ if (registrationCount !== 0) {
107
+ return;
108
+ }
109
+ (_stopWatchingInteract = stopWatchingInteractionStart) === null || _stopWatchingInteract === void 0 || _stopWatchingInteract();
110
+ stopWatchingInteractionStart = null;
111
+ };
112
+ }
113
+ return {
114
+ registerUsage: registerUsage
115
+ };
116
+ }
@@ -0,0 +1,98 @@
1
+ import { bind, bindAll } from 'bind-event-listener';
2
+ import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
3
+ import { monitorForTextSelection } from '@atlaskit/pragmatic-drag-and-drop/text-selection/adapter';
4
+ import { makeFixForAdapter } from './make-fix-for-adapter';
5
+ function watchForInteractionEnd(_ref) {
6
+ var stop = _ref.stop;
7
+ var isDragging = false;
8
+ function stopIfNotDragging() {
9
+ if (isDragging) {
10
+ return;
11
+ }
12
+ stop();
13
+ }
14
+ var frameId = null;
15
+ var unbindEvents = bindAll(window, [{
16
+ // User is starting another interaction
17
+ type: 'pointerdown',
18
+ listener: stop
19
+ }, {
20
+ // User did not start a drag.
21
+ // "pointerdown" won't be fired if a drag started
22
+ type: 'pointerup',
23
+ listener: stopIfNotDragging
24
+ }, {
25
+ type: 'dragstart',
26
+ listener: function listener() {
27
+ /**
28
+ * The pdnd `onDragStart()` fires in the frame after "dragstart"
29
+ * So we are delaying our isDragging check to give a chance
30
+ * for `onDragStart()` to set the value correctly.
31
+ *
32
+ * Note: could not use "pointercancel" as it is not
33
+ * published in Safari → https://bugs.webkit.org/show_bug.cgi?id=222632
34
+ */
35
+ frameId = requestAnimationFrame(function () {
36
+ frameId = null;
37
+ stopIfNotDragging();
38
+ });
39
+ },
40
+ // need to schedule our frame after the text-selection
41
+ // adapter queues it's `onDragStart` frame.
42
+ options: {
43
+ capture: false
44
+ }
45
+ }], {
46
+ // Listening in the capture phase to increase resilience
47
+ // against events being stopped.
48
+ capture: true,
49
+ // being super clear these should only run once
50
+ once: true
51
+ });
52
+ var unbindMonitor = monitorForTextSelection({
53
+ onDragStart: function onDragStart() {
54
+ isDragging = true;
55
+ },
56
+ onDrop: function onDrop() {
57
+ isDragging = false;
58
+ stop();
59
+ }
60
+ });
61
+ return combine(unbindEvents, unbindMonitor, function abortFrame() {
62
+ if (frameId != null) {
63
+ cancelAnimationFrame(frameId);
64
+ }
65
+ });
66
+ }
67
+ function watchForInteractionStart(_ref2) {
68
+ var start = _ref2.start;
69
+ return bind(window, {
70
+ // Note: Using "mousedown" rather than "pointerdown" due to a Safari bug.
71
+ // Safari not publish a "pointerdown" on the interaction after a drag
72
+ // → https://bugs.webkit.org/show_bug.cgi?id=279749
73
+ type: 'mousedown',
74
+ listener: function listener() {
75
+ // A text selection drag will only start when there is
76
+ // an active text selection.
77
+ var selection = window.getSelection();
78
+
79
+ // No selection object found
80
+ if (!selection) {
81
+ return;
82
+ }
83
+
84
+ // `isCollapsed` is "true" if there is currently no selected text
85
+ if (selection.isCollapsed) {
86
+ return;
87
+ }
88
+ start();
89
+ }
90
+ });
91
+ }
92
+ var api = makeFixForAdapter({
93
+ watchForInteractionStart: watchForInteractionStart,
94
+ watchForInteractionEnd: watchForInteractionEnd
95
+ });
96
+ export function disableDraggingToCrossOriginIFramesForTextSelection() {
97
+ return api.registerUsage();
98
+ }
@@ -92,7 +92,7 @@ var ModalWrapper = function ModalWrapper(props) {
92
92
  action: 'closed',
93
93
  componentName: 'modalDialog',
94
94
  packageName: "@atlaskit/modal-dialog",
95
- packageVersion: "12.15.7"
95
+ packageVersion: "12.17.0"
96
96
  });
97
97
  var onBlanketClicked = useCallback(function (e) {
98
98
  if (shouldCloseOnOverlayClick) {
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
1
5
  import { jsx } from '@emotion/react';
2
6
  import type { KeyboardOrMouseEvent, ModalDialogProps } from '../../types';
3
7
  declare const ModalDialog: (props: ModalDialogProps & {
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForElement(): CleanupFn;
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForExternal(): CleanupFn;
@@ -0,0 +1,11 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function makeFixForAdapter({ watchForInteractionStart, watchForInteractionEnd, }: {
3
+ watchForInteractionStart: ({ start }: {
4
+ start: () => void;
5
+ }) => CleanupFn;
6
+ watchForInteractionEnd: ({ stop }: {
7
+ stop: () => void;
8
+ }) => CleanupFn;
9
+ }): {
10
+ registerUsage: () => CleanupFn;
11
+ };
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForTextSelection(): CleanupFn;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
1
5
  import { jsx } from '@emotion/react';
2
6
  import type { KeyboardOrMouseEvent, ModalDialogProps } from '../../types';
3
7
  declare const ModalDialog: (props: ModalDialogProps & {
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForElement(): CleanupFn;
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForExternal(): CleanupFn;
@@ -0,0 +1,11 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function makeFixForAdapter({ watchForInteractionStart, watchForInteractionEnd, }: {
3
+ watchForInteractionStart: ({ start }: {
4
+ start: () => void;
5
+ }) => CleanupFn;
6
+ watchForInteractionEnd: ({ stop }: {
7
+ stop: () => void;
8
+ }) => CleanupFn;
9
+ }): {
10
+ registerUsage: () => CleanupFn;
11
+ };
@@ -0,0 +1,2 @@
1
+ import { type CleanupFn } from '@atlaskit/pragmatic-drag-and-drop/types';
2
+ export declare function disableDraggingToCrossOriginIFramesForTextSelection(): CleanupFn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/modal-dialog",
3
- "version": "12.15.7",
3
+ "version": "12.17.0",
4
4
  "description": "A modal dialog displays content that requires user interaction, in a layer above the page.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -29,16 +29,17 @@
29
29
  "@atlaskit/analytics-next": "^10.1.0",
30
30
  "@atlaskit/blanket": "^13.3.0",
31
31
  "@atlaskit/codemod-utils": "^4.2.0",
32
- "@atlaskit/ds-lib": "^2.5.0",
32
+ "@atlaskit/ds-lib": "^2.6.0",
33
33
  "@atlaskit/focus-ring": "^1.6.0",
34
- "@atlaskit/icon": "^22.17.0",
34
+ "@atlaskit/icon": "^22.18.0",
35
35
  "@atlaskit/layering": "^0.4.0",
36
36
  "@atlaskit/motion": "^1.9.0",
37
37
  "@atlaskit/platform-feature-flags": "^0.3.0",
38
38
  "@atlaskit/portal": "^4.9.0",
39
- "@atlaskit/primitives": "^12.1.0",
39
+ "@atlaskit/pragmatic-drag-and-drop": "^1.3.0",
40
+ "@atlaskit/primitives": "^12.2.0",
40
41
  "@atlaskit/theme": "^13.0.0",
41
- "@atlaskit/tokens": "^1.59.0",
42
+ "@atlaskit/tokens": "^1.61.0",
42
43
  "@babel/runtime": "^7.0.0",
43
44
  "@emotion/react": "^11.7.1",
44
45
  "bind-event-listener": "^3.0.0",
@@ -57,9 +58,9 @@
57
58
  "@atlaskit/button": "*",
58
59
  "@atlaskit/checkbox": "^14.0.0",
59
60
  "@atlaskit/dropdown-menu": "^12.18.0",
60
- "@atlaskit/popup": "^1.25.0",
61
+ "@atlaskit/popup": "^1.27.0",
61
62
  "@atlaskit/radio": "^6.5.0",
62
- "@atlaskit/select": "^17.17.0",
63
+ "@atlaskit/select": "^17.19.0",
63
64
  "@atlaskit/ssr": "*",
64
65
  "@atlaskit/textfield": "^6.5.0",
65
66
  "@atlaskit/tooltip": "^18.7.0",
@@ -74,6 +75,7 @@
74
75
  "react-dom": "^16.8.0",
75
76
  "react-lorem-component": "^0.13.0",
76
77
  "storybook-addon-performance": "^0.16.0",
78
+ "tiny-invariant": "^1.2.0",
77
79
  "typescript": "~5.4.2",
78
80
  "wait-for-expect": "^1.2.0"
79
81
  },