Bug 1350191 - Change keypress event propagation to capture to correctly preventDefault if control is focused. r=jaws a=jcristau

We could not avoid controls being focused after De-XUL, in order
to preventDefault before event propagate to focused control, we should
change the way of keypress event propagation in media controls.

MozReview-Commit-ID: 4KNPU4XlSDJ

--HG--
extra : source : 85866d2aa9f52c385e73324557e8e56436d9440a
This commit is contained in:
Ray Lin 2017-03-25 11:48:30 +08:00
parent 4d8a169247
commit 19275699e2
4 changed files with 84 additions and 5 deletions

View file

@ -1,5 +1,7 @@
"use strict";
var tests = [];
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
@ -30,3 +32,9 @@ function getAnonElementWithinVideoByAttribute(video, aName, aValue) {
return SpecialPowers.wrap(videoControl.ownerDocument)
.getAnonymousElementByAttribute(videoControl, aName, aValue);
}
function executeTests() {
return tests
.map(fn => () => new Promise(fn))
.reduce((promise, task) => promise.then(task), Promise.resolve());
}

View file

@ -27,6 +27,8 @@ skip-if = toolkit == 'android'
[test_videocontrols.html]
tags = fullscreen
skip-if = toolkit == 'android' #TIMED_OUT
[test_videocontrols_keyhandler.html]
skip-if = toolkit == 'android'
[test_videocontrols_vtt.html]
skip-if = toolkit == 'android'
[test_videocontrols_iframe_fullscreen.html]

View file

@ -0,0 +1,69 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test - KeyHandler</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video id="video" controls preload="auto"></video>
</div>
<pre id="test">
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
const video = document.getElementById("video");
const playButton = getAnonElementWithinVideoByAttribute(video, "anonid", "playButton");
const scrubber = getAnonElementWithinVideoByAttribute(video, "anonid", "scrubber");
const volumeStack = getAnonElementWithinVideoByAttribute(video, "anonid", "volumeStack");
// Setup video
tests.push(done => {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, done);
}, done => {
video.src = "seek_with_sound.ogg";
video.addEventListener("loadedmetadata", done);
});
// Bug 1350191, video should not seek while changing volume by
// pressing up/down arrow key.
tests.push(done => {
video.addEventListener("play", done, { once: true });
synthesizeMouseAtCenter(playButton, {});
}, done => {
video.addEventListener("seeked", done, { once: true });
synthesizeMouseAtCenter(scrubber, {});
}, done => {
let counter = 0;
let keyCodes = ["VK_DOWN", "VK_DOWN", "VK_UP", "VK_DOWN", "VK_UP", "VK_UP"];
video.addEventListener("seeked", () => ok(false, "should not trigger seeked event"));
video.addEventListener("volumechange", () => {
if (++counter === keyCodes.length) {
ok(true, "change volume by up/down arrow key without trigger 'seeked' event");
done();
}
if (counter > keyCodes.length) {
ok(false, "trigger too much volumechange events");
}
});
for (let keyCode of keyCodes) {
synthesizeKey(keyCode, {});
}
});
tests.push(SimpleTest.finish);
window.addEventListener("load", executeTests);
</script>
</pre>
</body>
</html>

View file

@ -686,7 +686,7 @@
if (this.controlListeners) {
for (let element of this.controlListeners) {
element.item.removeEventListener(element.event, element.func,
{ mozSystemGroup: true });
{ mozSystemGroup: true, capture: element.capture });
}
delete this.controlListeners;
@ -1799,10 +1799,10 @@
// Due to this helper function, "Utils" is made available to the event
// listener functions. Hence declare it as a global for ESLint.
/* global Utils */
function addListener(elem, eventName, func) {
function addListener(elem, eventName, func, capture = false) {
let boundFunc = func.bind(self);
self.controlListeners.push({ item: elem, event: eventName, func: boundFunc });
elem.addEventListener(eventName, boundFunc, { mozSystemGroup: true });
self.controlListeners.push({ item: elem, event: eventName, func: boundFunc, capture });
elem.addEventListener(eventName, boundFunc, { mozSystemGroup: true, capture });
}
addListener(this.muteButton, "click", this.toggleMute);
@ -1818,7 +1818,7 @@
addListener(this.video.ownerDocument, "mozfullscreenchange", this.onFullscreenChange);
addListener(this.controlBar, "transitionend", this.onControlBarTransitioned);
addListener(this.video.ownerDocument, "fullscreenchange", this.onFullscreenChange);
addListener(this.video, "keypress", this.keyHandler);
addListener(this.video, "keypress", this.keyHandler, true);
addListener(this.videocontrols, "dragstart", function(event) {
event.preventDefault(); // prevent dragging of controls image (bug 517114)