Skip to content

Commit e105791

Browse files
committed
fix(gesture): fix overzealous preventDefault on label+input clicks.
Fixes angular#4110
1 parent f98e851 commit e105791

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

src/core/services/gesture/gesture.js

+36-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
*/
77
var pointer, lastPointer, forceSkipClickHijack = false;
88

9+
/**
10+
* The position of the most recent click if that click was on a label element.
11+
* @type {{x: number, y: number}?}
12+
*/
13+
var lastLabelClickPos = null;
14+
915
// Used to attach event listeners once when multiple ng-apps are running.
1016
var isInitialized = false;
1117

@@ -448,9 +454,16 @@
448454
*/
449455
document.addEventListener('click', function clickHijacker(ev) {
450456
var isKeyClick = ev.clientX === 0 && ev.clientY === 0;
451-
if (!isKeyClick && !ev.$material && !ev.isIonicTap) {
457+
if (!isKeyClick && !ev.$material && !ev.isIonicTap
458+
&& !isInputEventFromLabelClick(ev)) {
452459
ev.preventDefault();
453460
ev.stopPropagation();
461+
lastLabelClickPos = null;
462+
} else {
463+
lastLabelClickPos = null;
464+
if (ev.target.tagName.toLowerCase() == 'label') {
465+
lastLabelClickPos = {x: ev.x, y: ev.y};
466+
}
454467
}
455468
}, true);
456469

@@ -570,6 +583,28 @@
570583
return ev && pointer && ev.type.charAt(0) === pointer.type;
571584
}
572585

586+
/**
587+
* Gets whether the given event is an input event that was caused by clicking on an
588+
* associated label element.
589+
*
590+
* This is necessary because the browser will, upon clicking on a label element, fire an
591+
* *extra* click event on its associated input (if any). mdGesture is able to flag the label
592+
* click as with `$material` correctly, but not the second input click.
593+
*
594+
* In order to determine whether an input event is from a label click, we compare the (x, y) for
595+
* the event to the (x, y) for the most recent label click (which is cleared whenever a non-label
596+
* click occurs). Unfortunately, there are no event properties that tie the input and the label
597+
* together (such as relatedTarget).
598+
*
599+
* @param {MouseEvent} event
600+
* @returns {boolean}
601+
*/
602+
function isInputEventFromLabelClick(event) {
603+
return lastLabelClickPos
604+
&& lastLabelClickPos.x == event.x
605+
&& lastLabelClickPos.y == event.y;
606+
}
607+
573608
/*
574609
* Update the given pointer based upon the given DOMEvent.
575610
* Distance, velocity, direction, duration, etc

0 commit comments

Comments
 (0)