haikuwebkit/LayoutTests/media/replaceChild-should-not-pau...

59 lines
1.3 KiB
HTML
Raw Permalink Normal View History

Media elements should not be paused right away when removed from the document https://bugs.webkit.org/show_bug.cgi?id=157347 <rdar://problem/25888758> Reviewed by Alex Christensen. LayoutTests/imported/w3c: Rebaseline now that more W3C tests are passing. * web-platform-tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document-expected.txt: * web-platform-tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document-expected.txt: * web-platform-tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-expected.txt: Source/WebCore: Media elements should not be paused right away when removed from the document. Instead we should allow the task that removed the media element from the document to finish because considering pausing. This avoid inadvertently pausing media elements when the JS merely moves them on the page (e.g. using Node.replaceChild()). Text from the HTML specification: """ When a media element is removed from a Document, the user agent must run the following steps: 1. Await a stable state, allowing the task that removed the media element from the Document to continue. The synchronous section consists of all the remaining steps of this algorithm. (Steps in the synchronous section are marked with ⌛.) 2. ⌛ If the media element is in a Document, abort these steps. 3. ⌛ Run the internal pause steps for the media element. """ c.f. https://html.spec.whatwg.org/multipage/embedded-content.html#htmlmediaelement Test: media/replaceChild-should-not-pause-video.html * dom/GenericEventQueue.cpp: (WebCore::GenericEventQueue::sharedTimerFired): Copy the queue of events before processing it so that we don't fire events that get scheduled by the event handlers as a result of us firing the pending events. Otherwise, we end up firing events synchronously right after they've been queued, which is wrong. This was causing several W3C tests to fail. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): (WebCore::HTMLMediaElement::pauseAfterDetachedTimerFired): (WebCore::HTMLMediaElement::removedFrom): * html/HTMLMediaElement.h: After the media element gets removed from the document, schedule a 0 timer before pausing the media element, to give the task that removed us a chance to finish. When the timer fires, we check if we were added back into an active document and avoid pausing in such case. LayoutTests: * media/remove-from-document-expected.txt: * media/remove-from-document.html: Check asynchronously if the video has been paused after removing it from the document instead of synchronously as we no longer pause the video synchronously in this case. * media/replaceChild-should-not-pause-video-expected.txt: Added. * media/replaceChild-should-not-pause-video.html: Added. Add test case to make sure that calling replaceChild() on with a video element as newChild does not pause the video if it is already playing. This is a regression test for <rdar://problem/25888758>. * webaudio/audiocontext-state-interrupted-expected.txt: * webaudio/audiocontext-state-interrupted.html: Add a missing call to internals.setMediaSessionRestrictions("WebAudio", "InterruptedPlaybackNotPermitted") before the fourth test. The fourth test was previously passing by chance, due to a bug in GenericEventQueue sometimes firing events synchronously after they are scheduled. Canonical link: https://commits.webkit.org/175464@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200431 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-05-04 21:33:45 +00:00
<!DOCTYPE html>
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
<script src="media-file.js"></script>
</head>
<body onload="start()">
<div id="parentA">
<div id="childToReplace"></div>
</div>
<div id="parentB">
<video id="vid"></video>
</div>
<script>
description("Test that a video element does not get paused when moved using replaceChild().");
jsTestIsAsync = true;
var video = document.getElementsByTagName('video')[0];
function paused()
{
testFailed("Video was paused");
}
video.addEventListener("pause", paused);
function playing()
{
debug("EVENT(playing)");
shouldBeFalse("video.paused");
parentA = document.getElementById("parentA");
childToReplace = document.getElementById("childToReplace");
evalAndLog("parentA.replaceChild(video, childToReplace)");
shouldBeFalse("video.paused");
setTimeout(function() {
shouldBeFalse("video.paused");
finishJSTest();
}, 0);
}
function canplay()
{
debug("EVENT(canplay)");
video.addEventListener("playing", playing);
evalAndLog("video.play()");
}
function start()
{
video.addEventListener("canplay", canplay);
video.src = findMediaFile("video", "content/test");
}
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>