From 3fc84876c82bdd4b600f97093deda4e8539204e9 Mon Sep 17 00:00:00 2001 From: "commit-queue@webkit.org" Date: Thu, 10 Nov 2016 15:43:53 +0000 Subject: [PATCH] [Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS https://bugs.webkit.org/show_bug.cgi?id=164554 Patch by Antoine Quint 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: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208537 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 14 +++++ ...media-controller-fullscreen-change-expected.txt | 17 ++++++ .../media-controller-fullscreen-change.html | 64 ++++++++++++++++++++ .../platform/ios-simulator/TestExpectations | 3 + Source/WebCore/ChangeLog | 26 ++++++++ .../media/fullscreen-support.js | 11 ++++ .../media/media-controller-support.js | 12 ++++ .../media/media-controller.js | 69 +++++++++++++++------- 8 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt create mode 100644 LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 0334088..a0057a0 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,17 @@ +2016-11-10 Antoine Quint + + [Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS + https://bugs.webkit.org/show_bug.cgi?id=164554 + + + 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 [css-grid] Fix fr tracks sizing under min|max-size constraints diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt b/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt new file mode 100644 index 0000000..7004bb3 --- /dev/null +++ b/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change-expected.txt @@ -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 + diff --git a/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html b/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html new file mode 100644 index 0000000..28e4196 --- /dev/null +++ b/LayoutTests/media/modern-media-controls/media-controller/media-controller-fullscreen-change.html @@ -0,0 +1,64 @@ + + + + +
+ + + diff --git a/LayoutTests/platform/ios-simulator/TestExpectations b/LayoutTests/platform/ios-simulator/TestExpectations index 4c9460b..8922419 100644 --- a/LayoutTests/platform/ios-simulator/TestExpectations +++ b/LayoutTests/platform/ios-simulator/TestExpectations @@ -2748,3 +2748,6 @@ fast/layers/prevent-hit-test-during-layout.html [ Skip ] 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 ] diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index d849877..6f181ea 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,29 @@ +2016-11-10 Antoine Quint + + [Modern Media Controls] Media Controller: update controls based on fullscreen playback on macOS + https://bugs.webkit.org/show_bug.cgi?id=164554 + + + 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 [Linux] Memory values shown by memory pressure handler logger are not useful diff --git a/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js b/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js index 1b29ecb..b178679 100644 --- a/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js +++ b/Source/WebCore/Modules/modern-media-controls/media/fullscreen-support.js @@ -35,6 +35,17 @@ class FullscreenSupport extends MediaControllerSupport 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() diff --git a/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js b/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js index 3d4e1a7..d8272e3 100644 --- a/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js +++ b/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js @@ -41,6 +41,18 @@ class MediaControllerSupport 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() diff --git a/Source/WebCore/Modules/modern-media-controls/media/media-controller.js b/Source/WebCore/Modules/modern-media-controls/media/media-controller.js index 83bef53..01558bc 100644 --- a/Source/WebCore/Modules/modern-media-controls/media/media-controller.js +++ b/Source/WebCore/Modules/modern-media-controls/media/media-controller.js @@ -32,28 +32,19 @@ class MediaController this.media = media; this.host = host; - // FIXME: This should get set dynamically based on the current environment. - this.layoutTraits = LayoutTraits.macOS; - - this.controls = new MacOSInlineMediaControls - shadowRoot.appendChild(this.controls.element); - - 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); + this._updateControlsIfNeeded(); - this._updateControlsSize(); media.addEventListener("resize", this); + + media.addEventListener("webkitfullscreenchange", 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,14 +63,52 @@ class MediaController { 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; this.controls.height = this.media.offsetHeight; } + _controlsClass() + { + const layoutTraits = this.layoutTraits; + if (layoutTraits & LayoutTraits.Fullscreen) + return MacOSFullscreenMediaControls; + return MacOSInlineMediaControls; + } + } -- 1.8.3.1