Skip to content
This repository was archived by the owner on Aug 18, 2025. It is now read-only.

Commit 8858522

Browse files
committed
changing webkit hack
1 parent ca8287f commit 8858522

1 file changed

Lines changed: 28 additions & 72 deletions

File tree

src/view/use-drag-handle/sensor/use-touch-sensor.js

Lines changed: 28 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import supportedPageVisibilityEventName from '../util/supported-page-visibility-
1515
import createPostDragEventPreventer, {
1616
type EventPreventer,
1717
} from '../util/create-post-drag-event-preventer';
18+
import useLayoutEffect from '../../use-isomorphic-layout-effect';
1819

1920
export type Args = {|
2021
callbacks: Callbacks,
@@ -36,75 +37,13 @@ type TouchWithForce = Touch & {
3637
force: number,
3738
};
3839

39-
type WebkitHack = {|
40-
preventTouchMove: () => void,
41-
releaseTouchMove: () => void,
42-
|};
43-
44-
export const timeForLongPress: number = 150;
40+
// Decreased from 150 as a work around for an issue for forcepress on iOS
41+
// https://github.com/atlassian/react-beautiful-dnd/issues/1401
42+
export const timeForLongPress: number = 120;
4543
export const forcePressThreshold: number = 0.15;
4644
const touchStartMarshal: EventMarshal = createEventMarshal();
4745
const noop = (): void => {};
4846

49-
// Webkit does not allow event.preventDefault() in dynamically added handlers
50-
// So we add an always listening event handler to get around this :(
51-
// webkit bug: https://bugs.webkit.org/show_bug.cgi?id=184250
52-
const webkitHack: WebkitHack = (() => {
53-
const stub: WebkitHack = {
54-
preventTouchMove: noop,
55-
releaseTouchMove: noop,
56-
};
57-
58-
// Do nothing when server side rendering
59-
if (typeof window === 'undefined') {
60-
return stub;
61-
}
62-
63-
// Device has no touch support - no point adding the touch listener
64-
if (!('ontouchstart' in window)) {
65-
return stub;
66-
}
67-
68-
// Not adding any user agent testing as everything pretends to be webkit
69-
70-
let isBlocking: boolean = false;
71-
72-
// Adding a persistent event handler
73-
window.addEventListener(
74-
'touchmove',
75-
(event: TouchEvent) => {
76-
// We let the event go through as normal as nothing
77-
// is blocking the touchmove
78-
if (!isBlocking) {
79-
return;
80-
}
81-
82-
// Our event handler would have worked correctly if the browser
83-
// was not webkit based, or an older version of webkit.
84-
if (event.defaultPrevented) {
85-
return;
86-
}
87-
88-
// Okay, now we need to step in and fix things
89-
event.preventDefault();
90-
91-
// Forcing this to be non-passive so we can get every touchmove
92-
// Not activating in the capture phase like the dynamic touchmove we add.
93-
// Technically it would not matter if we did this in the capture phase
94-
},
95-
{ passive: false, capture: false },
96-
);
97-
98-
const preventTouchMove = () => {
99-
isBlocking = true;
100-
};
101-
const releaseTouchMove = () => {
102-
isBlocking = false;
103-
};
104-
105-
return { preventTouchMove, releaseTouchMove };
106-
})();
107-
10847
export default function useTouchSensor(args: Args): OnTouchStart {
10948
const {
11049
callbacks,
@@ -143,7 +82,6 @@ export default function useTouchSensor(args: Args): OnTouchStart {
14382
schedule.cancel();
14483
unbindWindowEventsRef.current();
14584
touchStartMarshal.reset();
146-
webkitHack.releaseTouchMove();
14785
hasMovedRef.current = false;
14886
onCaptureEnd();
14987

@@ -196,11 +134,15 @@ export default function useTouchSensor(args: Args): OnTouchStart {
196134
hasMovedRef.current = true;
197135
}
198136

199-
const { clientX, clientY } = event.touches[0];
137+
const touch: ?Touch = event.touches[0];
138+
139+
if (!touch) {
140+
return;
141+
}
200142

201143
const point: Position = {
202-
x: clientX,
203-
y: clientY,
144+
x: touch.clientX,
145+
y: touch.clientY,
204146
};
205147

206148
// We need to prevent the default event in order to block native scrolling
@@ -437,11 +379,25 @@ export default function useTouchSensor(args: Args): OnTouchStart {
437379
// browser interactions as possible.
438380
// This includes navigation on anchors which we want to preserve
439381
touchStartMarshal.handle();
440-
441-
// A webkit only hack to prevent touch move events
442-
webkitHack.preventTouchMove();
443382
startPendingDrag(event);
444383
};
445384

385+
// This is needed for safari
386+
// Simply adding a non capture, non passive 'touchmove' listener.
387+
// This forces event.preventDefault() in dynamically added
388+
// touchmove event handlers to actually work
389+
// https://github.com/atlassian/react-beautiful-dnd/issues/1374
390+
useLayoutEffect(function webkitHack() {
391+
const unbind = bindEvents(window, [
392+
{
393+
eventName: 'touchmove',
394+
fn: noop,
395+
options: { capture: false, passive: false },
396+
},
397+
]);
398+
399+
return unbind;
400+
}, []);
401+
446402
return onTouchStart;
447403
}

0 commit comments

Comments
 (0)