зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1493659 - Skip the click event handler if touch event has occurred. r=birtles
Tapping the menu button during the panel has shown make the menu button to be unopenable. This cause reason is removing the pointer-events property before the mouse event happens. The tapping event will happen many the event like the following: 1) touchstart 2) touchmove (Long tap only) 3) touchend 4) mousedown 5) mouseup 6) click This patch will detect the touchend event to eat the click event. Differential Revision: https://phabricator.services.mozilla.com/D7827 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
4865990e1a
Коммит
4c95ba0b3d
|
@ -70,6 +70,7 @@ class MenuButton extends PureComponent {
|
||||||
this.onHidden = this.onHidden.bind(this);
|
this.onHidden = this.onHidden.bind(this);
|
||||||
this.onClick = this.onClick.bind(this);
|
this.onClick = this.onClick.bind(this);
|
||||||
this.onKeyDown = this.onKeyDown.bind(this);
|
this.onKeyDown = this.onKeyDown.bind(this);
|
||||||
|
this.onTouchStart = this.onTouchStart.bind(this);
|
||||||
|
|
||||||
this.buttonRef = createRef();
|
this.buttonRef = createRef();
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ class MenuButton extends PureComponent {
|
||||||
isMenuInitialized: flags.testing || false,
|
isMenuInitialized: flags.testing || false,
|
||||||
win: props.doc.defaultView.top,
|
win: props.doc.defaultView.top,
|
||||||
};
|
};
|
||||||
|
this.ignoreNextClick = false;
|
||||||
|
|
||||||
this.initializeTooltip();
|
this.initializeTooltip();
|
||||||
}
|
}
|
||||||
|
@ -196,6 +198,44 @@ class MenuButton extends PureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When we are closing the menu we will get a 'hidden' event before we get
|
||||||
|
// a 'click' event. We want to re-enable the pointer-events: auto setting we
|
||||||
|
// use on the button while the menu is visible, but we don't want to do it
|
||||||
|
// until after the subsequent click event since otherwise we will end up
|
||||||
|
// re-opening the menu.
|
||||||
|
//
|
||||||
|
// For mouse events, we achieve this by using setTimeout(..., 0) to schedule
|
||||||
|
// a separate task to run after the click event, but in the case of touch
|
||||||
|
// events the event order differs and the setTimeout callback will run before
|
||||||
|
// the click event.
|
||||||
|
//
|
||||||
|
// In order to prevent that we detect touch events and set a flag to ignore
|
||||||
|
// the next click event. However, we need to differentiate between touch drag
|
||||||
|
// events and long press events (which don't generate a 'click') and "taps"
|
||||||
|
// (which do). We do that by looking for a 'touchmove' event and clearing the
|
||||||
|
// flag if we get one.
|
||||||
|
onTouchStart(evt) {
|
||||||
|
const touchend = () => {
|
||||||
|
const anchorRect = this.buttonRef.current.getClientRects()[0];
|
||||||
|
const { clientX, clientY } = evt.changedTouches[0];
|
||||||
|
// We need to check that the click is inside the bounds since when the
|
||||||
|
// menu is being closed the button will currently have
|
||||||
|
// pointer-events: none (and if we don't check the bounds we will end up
|
||||||
|
// ignoring unrelated clicks).
|
||||||
|
if (anchorRect.x <= clientX && clientX <= anchorRect.x + anchorRect.width &&
|
||||||
|
anchorRect.y <= clientY && clientY <= anchorRect.y + anchorRect.height) {
|
||||||
|
this.ignoreNextClick = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const touchmove = () => {
|
||||||
|
this.state.win.removeEventListener("touchend", touchend);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.state.win.addEventListener("touchend", touchend, { once: true });
|
||||||
|
this.state.win.addEventListener("touchmove", touchmove, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
onHidden() {
|
onHidden() {
|
||||||
this.setState({ expanded: false });
|
this.setState({ expanded: false });
|
||||||
// While the menu is open, if we click _anywhere_ outside the menu, it will
|
// While the menu is open, if we click _anywhere_ outside the menu, it will
|
||||||
|
@ -213,14 +253,24 @@ class MenuButton extends PureComponent {
|
||||||
if (this.buttonRef.current) {
|
if (this.buttonRef.current) {
|
||||||
this.buttonRef.current.style.pointerEvents = "auto";
|
this.buttonRef.current.style.pointerEvents = "auto";
|
||||||
}
|
}
|
||||||
|
this.state.win.removeEventListener("touchstart",
|
||||||
|
this.onTouchStart,
|
||||||
|
true);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
this.state.win.addEventListener("touchstart", this.onTouchStart, true);
|
||||||
|
|
||||||
if (this.props.onCloseButton) {
|
if (this.props.onCloseButton) {
|
||||||
this.props.onCloseButton();
|
this.props.onCloseButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClick(e) {
|
async onClick(e) {
|
||||||
|
if (this.ignoreNextClick) {
|
||||||
|
this.ignoreNextClick = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.target === this.buttonRef.current) {
|
if (e.target === this.buttonRef.current) {
|
||||||
// On Mac, even after clicking the button it doesn't get focus.
|
// On Mac, even after clicking the button it doesn't get focus.
|
||||||
// Force focus to the button so that our keydown handlers get called.
|
// Force focus to the button so that our keydown handlers get called.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче