Bug 202143 - [iOS] iOS 13 does not send proper events in Safari, such as double tap and long touch, possibly​ influencing Leaflet JS apps​
Summary: [iOS] iOS 13 does not send proper events in Safari, such as double tap and lo...
Alias: None
Product: WebKit
Classification: Unclassified
Component: UI Events (show other bugs)
Version: WebKit Nightly Build
Hardware: iPhone / iPad Other
: P2 Normal
Assignee: Nobody
Keywords: InRadar
Depends on:
Reported: 2019-09-24 07:40 PDT by Tomas Slavkovsky
Modified: 2019-10-01 00:43 PDT (History)
2 users (show)

See Also:

Leaflet test (1.11 KB, text/html)
2019-09-30 06:43 PDT, Antoine Quint
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tomas Slavkovsky 2019-09-24 07:40:48 PDT
Long tap in iOS 13 Safari does not send any event to the Leaflet library and is handled by iOS itself.

Double click emits following events: mouseover, mousemove, mousedown, mouseup, click, which results in leaflet's event click.

Might be tested on test map on https://leafletjs.com, if you use long-press it will trigger the copy-paste. Double click does not trigger anything. 

Comment 1 Radar WebKit Bug Importer 2019-09-25 15:37:20 PDT
Comment 2 Antoine Quint 2019-09-30 06:18:28 PDT
The change in behavior seems tied to the availability of Pointer Events in iOS 13.

With Pointer Events enabled (the default setting):

- double-tap: nothing happens
- long press: plus icon gets selected

With Pointer Events disabled (Settings > Safari > Advanced > Experimental Features > Pointer Events set to off):

- double-tap: map zooms to tapped location
- long press: nothing happens

Both of those behaviors match those of iOS 12.4.1 so Pointer Events introduced a regression for LeafletJS.
Comment 3 Antoine Quint 2019-09-30 06:43:43 PDT
Created attachment 379833 [details]
Leaflet test

Attached a simple test case for LeafletJS which includes the full JS source which may make it easier to diagnose issues.
Comment 4 Antoine Quint 2019-09-30 07:13:19 PDT
So, first, the "contextmenu" Leaflet event is not triggered because the Leaflet code uses "pointerdown" and "touchstart" events interchangeably and the availability of the former excludes the other. In Map.Tap.js the `_onDown` method has this check `if (!e.touches) { return; }` which will always lead to an early return since a PointerEvent event is not the same as a TouchEvent and does not have a `touches` property.

So the lack of a Leaflet "contextmenu" event being triggered is a Leaflet issue specifically.
Comment 5 Antoine Quint 2019-09-30 07:31:24 PDT
Actually, the "contextmenu"-related code is never initialized because Leaflet only enables it if touch events are supported but pointer events aren't:

    if (Browser.touch && !Browser.pointer) {
    	Map.addInitHook('addHandler', 'tap', Tap);

This makes sense since the code up there is specific to touch events. This code is simply not designed to work with Pointer Events at all.

Now to diagnose why double-tap-to-zoom the map doesn't work…
Comment 6 Antoine Quint 2019-09-30 07:43:12 PDT
OK, the double-tap issue is also a Leaflet issue. Consider this code in DomEvent.DoubleTap.js:

	function onTouchStart(e) {
		var count;

		if (Browser.pointer) {
			if ((!Browser.edge) || e.pointerType === 'mouse') { return; }
			count = _pointersCount;
		} else {
			count = e.touches.length;

		if (count > 1) { return; }

		var now = Date.now(),
		    delta = now - (last || now);

		touch = e.touches ? e.touches[0] : e;
		doubleTap = (delta > 0 && delta <= delay);
		last = now;

The function branches early between user agents that support Pointer Events and those that don't (based on `Browser.pointer`), but if `Browser.edge` is false it returns early. That property is false in iOS 13 and thus this function returns early and a "dblclick" event is never dispatched on the Leaflet Map object.

So all reported issues are Leaflet issues, there is nothing for us to do here.
Comment 7 Tomas Slavkovsky 2019-10-01 00:43:03 PDT
Thanks for looking into this. Confirming that it is a bug on Leaflet JS side. Will follow the track on Leaflet's Github.