Title: [208537] trunk
Revision
208537
Author
commit-qu...@webkit.org
Date
2016-11-10 07:43:53 -0800 (Thu, 10 Nov 2016)

Log Message

[Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS
https://bugs.webkit.org/show_bug.cgi?id=164554
<rdar://problem/29183439>

Patch by Antoine Quint <grao...@apple.com> on 2016-11-10
Reviewed by Dean Jackson.

Source/WebCore:

When toggling fullscreen on macOS, toggle between MacOSInlineMediaControls and MacOSFullscreenMediaControls.
To facilitate this, support objects are created and destroyed when changing the controls in order for the
right control objects to be hooked up to the media controller. A new destroy() method on MediaControllerSupport
subclasses can be overridden to remove event listeners added by support objects in their constructor.

Test: media/modern-media-controls/media-controller/media-controller-fullscreen-change.html

* Modules/modern-media-controls/media/fullscreen-support.js:
(FullscreenSupport.prototype.destroy):
* Modules/modern-media-controls/media/media-controller-support.js:
(MediaControllerSupport.prototype.destroy):
* Modules/modern-media-controls/media/media-controller.js:
(MediaController):
(MediaController.prototype.get layoutTraits):
(MediaController.prototype.handleEvent):
(MediaController.prototype._updateControlsIfNeeded):
(MediaController.prototype._controlsClass):

LayoutTests:

Adding a new test to check that we use fullscreen controls on macOS once we've entered fullscreen.

* media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt: Added.
* media/modern-media-controls/media-controller/media-controller-fullscreen-change.html: Added.
* platform/ios-simulator/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208536 => 208537)


--- trunk/LayoutTests/ChangeLog	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/LayoutTests/ChangeLog	2016-11-10 15:43:53 UTC (rev 208537)
@@ -1,3 +1,17 @@
+2016-11-10  Antoine Quint  <grao...@apple.com>
+
+        [Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS
+        https://bugs.webkit.org/show_bug.cgi?id=164554
+        <rdar://problem/29183439>
+
+        Reviewed by Dean Jackson.
+
+        Adding a new test to check that we use fullscreen controls on macOS once we've entered fullscreen.
+
+        * media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt: Added.
+        * media/modern-media-controls/media-controller/media-controller-fullscreen-change.html: Added.
+        * platform/ios-simulator/TestExpectations:
+
 2016-11-08  Sergio Villar Senin  <svil...@igalia.com>
 
         [css-grid] Fix fr tracks sizing under min|max-size constraints

Added: trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt (0 => 208537)


--- trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt	2016-11-10 15:43:53 UTC (rev 208537)
@@ -0,0 +1,17 @@
+Testing the MediaController behavior when entering and leaving fullscreen.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Media entered fullscreen
+PASS mediaController.layoutTraits is LayoutTraits.macOS | LayoutTraits.Fullscreen
+PASS mediaController.controls instanceof MacOSFullscreenMediaControls is true
+
+Media exited fullscreen
+PASS mediaController.layoutTraits is LayoutTraits.macOS
+PASS mediaController.controls instanceof MacOSInlineMediaControls is true
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html (0 => 208537)


--- trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html	                        (rev 0)
+++ trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html	2016-11-10 15:43:53 UTC (rev 208537)
@@ -0,0 +1,64 @@
+<script src=""
+<script src="" type="text/_javascript_"></script>
+<body>
+<video src="" style="width: 320px; height: 240px;"></video>
+<div id="shadow"></div>
+<script type="text/_javascript_">
+
+window.jsTestIsAsync = true;
+
+description("Testing the <code>MediaController</code> behavior when entering and leaving fullscreen.");
+
+const shadowRoot = document.querySelector("div#shadow").attachShadow({ mode: "open" });
+const media = document.querySelector("video");
+const mediaController = createControls(shadowRoot, media, null);
+
+const button = document.body.appendChild(document.createElement("button"));
+
+function enterFullscreen()
+{
+    if (!("eventSender" in window)) {
+        debug("This test is designed to run in DRT");
+        return;
+    }
+
+    // Click a button so we may enter fullscreen.
+    button.addEventListener("click", event => {
+        try {
+            media.webkitEnterFullscreen();
+        } catch(e) {
+            debug("Toggling fullscreen failed");
+            finishJSTest();
+        }
+    });
+
+    eventSender.mouseMoveTo(button.offsetLeft + 1, button.offsetTop + 1);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+media.addEventListener("webkitfullscreenchange", function() {
+    if (media.webkitDisplayingFullscreen) {
+        debug("Media entered fullscreen");
+        shouldBe("mediaController.layoutTraits", "LayoutTraits.macOS | LayoutTraits.Fullscreen");
+        shouldBeTrue("mediaController.controls instanceof MacOSFullscreenMediaControls");
+        debug("");
+        media.webkitExitFullscreen()
+    } else {
+        debug("Media exited fullscreen");
+        shouldBe("mediaController.layoutTraits", "LayoutTraits.macOS");
+        shouldBeTrue("mediaController.controls instanceof MacOSInlineMediaControls");
+
+        debug("");
+        shadowRoot.host.remove();
+        media.remove();
+        button.remove();
+        finishJSTest();
+    }
+});
+
+media.addEventListener("loadedmetadata", enterFullscreen);
+
+</script>
+<script src=""
+</body>

Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (208536 => 208537)


--- trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations	2016-11-10 15:43:53 UTC (rev 208537)
@@ -2748,3 +2748,6 @@
 media/modern-media-controls/airplay-support/airplay-support.html [ Skip ]
 media/modern-media-controls/pip-support [ Skip ]
 media/modern-media-controls/placard-support [ Skip ]
+
+# This test is Mac-specific since it checks that we have custom controls in fullscreen.
+media/modern-media-controls/media-controller/media-controller-fullscreen-change.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (208536 => 208537)


--- trunk/Source/WebCore/ChangeLog	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/Source/WebCore/ChangeLog	2016-11-10 15:43:53 UTC (rev 208537)
@@ -1,3 +1,29 @@
+2016-11-10  Antoine Quint  <grao...@apple.com>
+
+        [Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS
+        https://bugs.webkit.org/show_bug.cgi?id=164554
+        <rdar://problem/29183439>
+
+        Reviewed by Dean Jackson.
+
+        When toggling fullscreen on macOS, toggle between MacOSInlineMediaControls and MacOSFullscreenMediaControls.
+        To facilitate this, support objects are created and destroyed when changing the controls in order for the
+        right control objects to be hooked up to the media controller. A new destroy() method on MediaControllerSupport
+        subclasses can be overridden to remove event listeners added by support objects in their constructor.
+
+        Test: media/modern-media-controls/media-controller/media-controller-fullscreen-change.html
+
+        * Modules/modern-media-controls/media/fullscreen-support.js:
+        (FullscreenSupport.prototype.destroy):
+        * Modules/modern-media-controls/media/media-controller-support.js:
+        (MediaControllerSupport.prototype.destroy):
+        * Modules/modern-media-controls/media/media-controller.js:
+        (MediaController):
+        (MediaController.prototype.get layoutTraits):
+        (MediaController.prototype.handleEvent):
+        (MediaController.prototype._updateControlsIfNeeded):
+        (MediaController.prototype._controlsClass):
+
 2016-11-10  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [Linux] Memory values shown by memory pressure handler logger are not useful

Modified: trunk/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js (208536 => 208537)


--- trunk/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js	2016-11-10 15:43:53 UTC (rev 208537)
@@ -35,6 +35,17 @@
             videoTracks.addEventListener(eventType, this);
     }
 
+    // Public
+
+    destroy()
+    {
+        super.destroy();
+
+        const videoTracks = this.mediaController.media.videoTracks;
+        for (let eventType of ["change", "addtrack", "removetrack"])
+            videoTracks.removeEventListener(eventType, this);
+    }
+
     // Protected
 
     get control()

Modified: trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js (208536 => 208537)


--- trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js	2016-11-10 15:43:53 UTC (rev 208537)
@@ -41,6 +41,18 @@
         this.syncControl();
     }
 
+    // Public
+
+    destroy()
+    {
+        const media = this.mediaController.media;
+        for (let eventType of this.mediaEvents)
+            media.removeEventListener(eventType, this);
+
+        if (this.control)
+            this.control.uiDelegate = null;
+    }
+
     // Protected
 
     get control()

Modified: trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller.js (208536 => 208537)


--- trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller.js	2016-11-10 15:02:08 UTC (rev 208536)
+++ trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller.js	2016-11-10 15:43:53 UTC (rev 208537)
@@ -32,28 +32,19 @@
         this.media = media;
         this.host = host;
 
-        // FIXME: This should get set dynamically based on the current environment.
-        this.layoutTraits = LayoutTraits.macOS;
+        this._updateControlsIfNeeded();
 
-        this.controls = new MacOSInlineMediaControls
-        shadowRoot.appendChild(this.controls.element);        
+        media.addEventListener("resize", this);
 
-        new AirplaySupport(this);
-        new ElapsedTimeSupport(this);
-        new FullscreenSupport(this);
-        new MuteSupport(this);
-        new PiPSupport(this);
-        new PlacardSupport(this);
-        new PlaybackSupport(this);
-        new RemainingTimeSupport(this);
-        new ScrubbingSupport(this);
-        new SkipBackSupport(this);
-        new StartSupport(this);
-        new StatusSupport(this);
-        new VolumeSupport(this);
+        media.addEventListener("webkitfullscreenchange", this);
+    }
 
-        this._updateControlsSize();
-        media.addEventListener("resize", this);
+    get layoutTraits()
+    {
+        let traits = window.navigator.platform === "MacIntel" ? LayoutTraits.macOS : LayoutTraits.iOS;
+        if (this.media.webkitDisplayingFullscreen)
+            traits = traits | LayoutTraits.Fullscreen;
+        return traits;
     }
 
     // Protected
@@ -72,10 +63,40 @@
     {
         if (event.type === "resize" && event.currentTarget === this.media)
             this._updateControlsSize();
+        else if (event.type === "webkitfullscreenchange" && event.currentTarget === this.media)
+            this._updateControlsIfNeeded();
     }
 
     // Private
 
+    _updateControlsIfNeeded()
+    {
+        const previousControls = this.controls;
+        const ControlsClass = this._controlsClass();
+        if (previousControls && previousControls.constructor === ControlsClass)
+            return;
+
+        // Before we reset the .controls property, we need to destroy the previous
+        // supporting objects so we don't leak.
+        if (this._supportingObjects) {
+            for (let supportingObject of this._supportingObjects)
+                supportingObject.destroy();
+        }
+
+        this.controls = new ControlsClass;
+
+        if (previousControls)
+            this.shadowRoot.replaceChild(this.controls.element, previousControls.element);
+        else
+            this.shadowRoot.appendChild(this.controls.element);        
+
+        this._updateControlsSize();
+
+        this._supportingObjects = [AirplaySupport, ElapsedTimeSupport, FullscreenSupport, MuteSupport, PiPSupport, PlacardSupport, PlaybackSupport, RemainingTimeSupport, ScrubbingSupport, SkipBackSupport, StartSupport, StatusSupport, VolumeSupport].map(SupportClass => {
+            return new SupportClass(this);
+        }, this);
+    }
+
     _updateControlsSize()
     {
         this.controls.width = this.media.offsetWidth;
@@ -82,4 +103,12 @@
         this.controls.height = this.media.offsetHeight;
     }
 
+    _controlsClass()
+    {
+        const layoutTraits = this.layoutTraits;
+        if (layoutTraits & LayoutTraits.Fullscreen)
+            return MacOSFullscreenMediaControls;
+        return MacOSInlineMediaControls;
+    }
+
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to