Title: [257705] trunk/Source/WebCore
Revision
257705
Author
[email protected]
Date
2020-03-02 02:27:42 -0800 (Mon, 02 Mar 2020)

Log Message

[GTK][WPE] Stop using mediaControlsBase.js
https://bugs.webkit.org/show_bug.cgi?id=208374

Reviewed by Xabier Rodriguez-Calvar.

Move the required base functionality to mediaControlsAdwaita.js and use that single file.

* Modules/mediacontrols/mediaControlsAdwaita.js:
(createControls):
(Controller):
(Controller.prototype.listenFor):
(Controller.prototype.stopListeningFor):
(Controller.prototype.addVideoListeners):
(Controller.prototype.removeVideoListeners):
(Controller.prototype.handleEvent):
(Controller.prototype.createBase):
(Controller.prototype.isAudio):
(Controller.prototype.isFullScreen):
(Controller.prototype.shouldHaveControls):
(Controller.prototype.updateBase):
(Controller.prototype.createControls):
(Controller.prototype.configureControls):
(Controller.prototype.disconnectControls):
(Controller.prototype.reconnectControls):
(Controller.prototype.showControls):
(Controller.prototype.hideControls):
(Controller.prototype.resetHideControlsTimer):
(Controller.prototype.clearHideControlsTimer):
(Controller.prototype.controlsAreAlwaysVisible):
(Controller.prototype.controlsAreHidden):
(Controller.prototype.addControls):
(Controller.prototype.removeControls):
(Controller.prototype.updateControls):
(Controller.prototype.setIsLive):
(Controller.prototype.updateDuration):
(Controller.prototype.formatTime):
(Controller.prototype.setPlaying):
(Controller.prototype.updatePlaying):
(Controller.prototype.updateCaptionButton):
(Controller.prototype.updateCaptionContainer):
(Controller.prototype.updateFullscreenButton):
(Controller.prototype.updateVolume):
(Controller.prototype.updateHasVideo):
(Controller.prototype.handleReadyStateChange):
(Controller.prototype.handleTimeUpdate):
(Controller.prototype.handleDurationChange):
(Controller.prototype.handlePlay):
(Controller.prototype.handlePause):
(Controller.prototype.handleVolumeChange):
(Controller.prototype.handleFullscreenChange):
(Controller.prototype.handleTextTrackChange):
(Controller.prototype.handleTextTrackAdd):
(Controller.prototype.handleTextTrackRemove):
(Controller.prototype.handleControlsChange):
(Controller.prototype.handleWrapperMouseMove):
(Controller.prototype.handleWrapperMouseOut):
(Controller.prototype.handleWrapperMouseUp):
(Controller.prototype.handlePanelMouseDown):
(Controller.prototype.handlePanelTransitionEnd):
(Controller.prototype.handlePanelClick):
(Controller.prototype.canPlay):
(Controller.prototype.handlePlayButtonClicked):
(Controller.prototype.handleTimelineChange):
(Controller.prototype.handleTimelineMouseUp):
(Controller.prototype.handleMuteButtonClicked):
(Controller.prototype.handleMuteButtonMouseOver):
(Controller.prototype.handleVolumeBoxMouseOut):
(Controller.prototype.handleVolumeSliderInput):
(Controller.prototype.handleFullscreenButtonClicked):
(Controller.prototype.buildCaptionMenu):
(Controller.prototype.captionItemSelected):
(Controller.prototype.focusSiblingCaptionItem):
(Controller.prototype.handleCaptionItemKeyUp):
(Controller.prototype.showCaptionMenu):
(Controller.prototype.captionMenuTransitionEnd):
(Controller.prototype.captionMenuContainsNode):
(Controller.prototype.handleCaptionButtonClicked):
(Controller.prototype.handleCaptionButtonMouseOver):
(Controller.prototype.handleCaptionButtonMouseOut):
(Controller.prototype.handleCaptionMenuMouseOut):
(ControllerAdwaita): Deleted.
(contains): Deleted.
(ControllerAdwaita.prototype.createControls): Deleted.
(ControllerAdwaita.prototype.configureInlineControls): Deleted.
(ControllerAdwaita.prototype.shouldHaveControls): Deleted.
(ControllerAdwaita.prototype.reconnectControls): Deleted.
(ControllerAdwaita.prototype.setStatusHidden): Deleted.
(ControllerAdwaita.prototype.updateTime): Deleted.
(ControllerAdwaita.prototype.handleTimeUpdate): Deleted.
(ControllerAdwaita.prototype.updateHasAudio): Deleted.
(ControllerAdwaita.prototype.handleMuteButtonMouseOver): Deleted.
(ControllerAdwaita.prototype.handleVolumeBoxMouseOut): Deleted.
(ControllerAdwaita.prototype.removeControls): Deleted.
(ControllerAdwaita.prototype.addControls): Deleted.
(ControllerAdwaita.prototype.updateFullscreenButton): Deleted.
(ControllerAdwaita.prototype.updateReadyState): Deleted.
(ControllerAdwaita.prototype.updateDuration): Deleted.
(ControllerAdwaita.prototype.setIsLive): Deleted.
(ControllerAdwaita.prototype.updatePlaying): Deleted.
(ControllerAdwaita.prototype.updateProgress): Deleted.
(ControllerAdwaita.prototype.handleCaptionButtonClicked): Deleted.
(ControllerAdwaita.prototype.buildCaptionMenu): Deleted.
(ControllerAdwaita.prototype.destroyCaptionMenu): Deleted.
(ControllerAdwaita.prototype.showCaptionMenu): Deleted.
(ControllerAdwaita.prototype.hideCaptionMenu): Deleted.
(ControllerAdwaita.prototype.captionMenuTransitionEnd): Deleted.
(ControllerAdwaita.prototype.handleCaptionButtonMouseOver): Deleted.
(ControllerAdwaita.prototype.handleCaptionButtonShowMenu): Deleted.
(ControllerAdwaita.prototype.handleCaptionButtonMouseOut): Deleted.
(ControllerAdwaita.prototype.handleCaptionMouseOut): Deleted.
* Modules/mediacontrols/mediaControlsBase.js:
(Controller.prototype.createControls):
* PlatformGTK.cmake:
* PlatformWPE.cmake:
* rendering/RenderThemeAdwaita.cpp:
(WebCore::RenderThemeAdwaita::mediaControlsScript):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (257704 => 257705)


--- trunk/Source/WebCore/ChangeLog	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/ChangeLog	2020-03-02 10:27:42 UTC (rev 257705)
@@ -1,3 +1,122 @@
+2020-03-02  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][WPE] Stop using mediaControlsBase.js
+        https://bugs.webkit.org/show_bug.cgi?id=208374
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Move the required base functionality to mediaControlsAdwaita.js and use that single file.
+
+        * Modules/mediacontrols/mediaControlsAdwaita.js:
+        (createControls):
+        (Controller):
+        (Controller.prototype.listenFor):
+        (Controller.prototype.stopListeningFor):
+        (Controller.prototype.addVideoListeners):
+        (Controller.prototype.removeVideoListeners):
+        (Controller.prototype.handleEvent):
+        (Controller.prototype.createBase):
+        (Controller.prototype.isAudio):
+        (Controller.prototype.isFullScreen):
+        (Controller.prototype.shouldHaveControls):
+        (Controller.prototype.updateBase):
+        (Controller.prototype.createControls):
+        (Controller.prototype.configureControls):
+        (Controller.prototype.disconnectControls):
+        (Controller.prototype.reconnectControls):
+        (Controller.prototype.showControls):
+        (Controller.prototype.hideControls):
+        (Controller.prototype.resetHideControlsTimer):
+        (Controller.prototype.clearHideControlsTimer):
+        (Controller.prototype.controlsAreAlwaysVisible):
+        (Controller.prototype.controlsAreHidden):
+        (Controller.prototype.addControls):
+        (Controller.prototype.removeControls):
+        (Controller.prototype.updateControls):
+        (Controller.prototype.setIsLive):
+        (Controller.prototype.updateDuration):
+        (Controller.prototype.formatTime):
+        (Controller.prototype.setPlaying):
+        (Controller.prototype.updatePlaying):
+        (Controller.prototype.updateCaptionButton):
+        (Controller.prototype.updateCaptionContainer):
+        (Controller.prototype.updateFullscreenButton):
+        (Controller.prototype.updateVolume):
+        (Controller.prototype.updateHasVideo):
+        (Controller.prototype.handleReadyStateChange):
+        (Controller.prototype.handleTimeUpdate):
+        (Controller.prototype.handleDurationChange):
+        (Controller.prototype.handlePlay):
+        (Controller.prototype.handlePause):
+        (Controller.prototype.handleVolumeChange):
+        (Controller.prototype.handleFullscreenChange):
+        (Controller.prototype.handleTextTrackChange):
+        (Controller.prototype.handleTextTrackAdd):
+        (Controller.prototype.handleTextTrackRemove):
+        (Controller.prototype.handleControlsChange):
+        (Controller.prototype.handleWrapperMouseMove):
+        (Controller.prototype.handleWrapperMouseOut):
+        (Controller.prototype.handleWrapperMouseUp):
+        (Controller.prototype.handlePanelMouseDown):
+        (Controller.prototype.handlePanelTransitionEnd):
+        (Controller.prototype.handlePanelClick):
+        (Controller.prototype.canPlay):
+        (Controller.prototype.handlePlayButtonClicked):
+        (Controller.prototype.handleTimelineChange):
+        (Controller.prototype.handleTimelineMouseUp):
+        (Controller.prototype.handleMuteButtonClicked):
+        (Controller.prototype.handleMuteButtonMouseOver):
+        (Controller.prototype.handleVolumeBoxMouseOut):
+        (Controller.prototype.handleVolumeSliderInput):
+        (Controller.prototype.handleFullscreenButtonClicked):
+        (Controller.prototype.buildCaptionMenu):
+        (Controller.prototype.captionItemSelected):
+        (Controller.prototype.focusSiblingCaptionItem):
+        (Controller.prototype.handleCaptionItemKeyUp):
+        (Controller.prototype.showCaptionMenu):
+        (Controller.prototype.captionMenuTransitionEnd):
+        (Controller.prototype.captionMenuContainsNode):
+        (Controller.prototype.handleCaptionButtonClicked):
+        (Controller.prototype.handleCaptionButtonMouseOver):
+        (Controller.prototype.handleCaptionButtonMouseOut):
+        (Controller.prototype.handleCaptionMenuMouseOut):
+        (ControllerAdwaita): Deleted.
+        (contains): Deleted.
+        (ControllerAdwaita.prototype.createControls): Deleted.
+        (ControllerAdwaita.prototype.configureInlineControls): Deleted.
+        (ControllerAdwaita.prototype.shouldHaveControls): Deleted.
+        (ControllerAdwaita.prototype.reconnectControls): Deleted.
+        (ControllerAdwaita.prototype.setStatusHidden): Deleted.
+        (ControllerAdwaita.prototype.updateTime): Deleted.
+        (ControllerAdwaita.prototype.handleTimeUpdate): Deleted.
+        (ControllerAdwaita.prototype.updateHasAudio): Deleted.
+        (ControllerAdwaita.prototype.handleMuteButtonMouseOver): Deleted.
+        (ControllerAdwaita.prototype.handleVolumeBoxMouseOut): Deleted.
+        (ControllerAdwaita.prototype.removeControls): Deleted.
+        (ControllerAdwaita.prototype.addControls): Deleted.
+        (ControllerAdwaita.prototype.updateFullscreenButton): Deleted.
+        (ControllerAdwaita.prototype.updateReadyState): Deleted.
+        (ControllerAdwaita.prototype.updateDuration): Deleted.
+        (ControllerAdwaita.prototype.setIsLive): Deleted.
+        (ControllerAdwaita.prototype.updatePlaying): Deleted.
+        (ControllerAdwaita.prototype.updateProgress): Deleted.
+        (ControllerAdwaita.prototype.handleCaptionButtonClicked): Deleted.
+        (ControllerAdwaita.prototype.buildCaptionMenu): Deleted.
+        (ControllerAdwaita.prototype.destroyCaptionMenu): Deleted.
+        (ControllerAdwaita.prototype.showCaptionMenu): Deleted.
+        (ControllerAdwaita.prototype.hideCaptionMenu): Deleted.
+        (ControllerAdwaita.prototype.captionMenuTransitionEnd): Deleted.
+        (ControllerAdwaita.prototype.handleCaptionButtonMouseOver): Deleted.
+        (ControllerAdwaita.prototype.handleCaptionButtonShowMenu): Deleted.
+        (ControllerAdwaita.prototype.handleCaptionButtonMouseOut): Deleted.
+        (ControllerAdwaita.prototype.handleCaptionMouseOut): Deleted.
+        * Modules/mediacontrols/mediaControlsBase.js:
+        (Controller.prototype.createControls):
+        * PlatformGTK.cmake:
+        * PlatformWPE.cmake:
+        * rendering/RenderThemeAdwaita.cpp:
+        (WebCore::RenderThemeAdwaita::mediaControlsScript):
+
 2020-03-01  Zalan Bujtas  <[email protected]>
 
         Unreviewed build fix for non-unified builds after r257507.

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsAdwaita.js (257704 => 257705)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsAdwaita.js	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsAdwaita.js	2020-03-02 10:27:42 UTC (rev 257705)
@@ -1,43 +1,303 @@
 function createControls(root, video, host)
 {
-    return new ControllerAdwaita(root, video, host);
+    return new Controller(root, video, host);
 };
 
-function ControllerAdwaita(root, video, host)
+function Controller(root, video, host)
 {
-    Controller.call(this, root, video, host);
+    this.video = video;
+    this.root = root;
+    this.host = host;
+    this.controls = {};
+    this.listeners = {};
+    this.isLive = false;
+    this.hasVisualMedia = false;
+
+    this.addVideoListeners();
+    this.createBase();
+    this.createControls();
+    this.updateBase();
+    this.updateControls();
+    this.updateDuration();
+    this.updateTime();
+    this.updatePlaying();
+    this.updateCaptionButton();
+    this.updateCaptionContainer();
+    this.updateFullscreenButton();
+    this.updateVolume();
+    this.updateHasAudio();
+    this.updateHasVideo();
 };
 
-function contains(list, obj)
-{
-    var i = list.length;
-    while (i--)
-        if (list[i] === obj)
+Controller.prototype = {
+
+    /* Constants */
+    HandledVideoEvents: {
+        emptied: 'handleReadyStateChange',
+        loadedmetadata: 'handleReadyStateChange',
+        loadeddata: 'handleReadyStateChange',
+        canplay: 'handleReadyStateChange',
+        canplaythrough: 'handleReadyStateChange',
+        timeupdate: 'handleTimeUpdate',
+        durationchange: 'handleDurationChange',
+        playing: 'handlePlay',
+        pause: 'handlePause',
+        volumechange: 'handleVolumeChange',
+        webkitfullscreenchange: 'handleFullscreenChange',
+        webkitbeginfullscreen: 'handleFullscreenChange',
+        webkitendfullscreen: 'handleFullscreenChange',
+    },
+    HideControlsDelay: 4 * 1000,
+    ClassNames: {
+        hidden: 'hidden',
+        hiding: 'hiding',
+        muteBox: 'mute-box',
+        muted: 'muted',
+        paused: 'paused',
+        selected: 'selected',
+        show: 'show',
+        noVideo: 'no-video',
+        noDuration: 'no-duration',
+        down: 'down',
+        out: 'out',
+    },
+    KeyCodes: {
+        enter: 13,
+        escape: 27,
+        space: 32,
+        left: 37,
+        up: 38,
+        right: 39,
+        down: 40
+    },
+
+    listenFor: function(element, eventName, handler, useCapture)
+    {
+        if (typeof useCapture === 'undefined')
+            useCapture = false;
+
+        if (!(this.listeners[eventName] instanceof Array))
+            this.listeners[eventName] = [];
+        this.listeners[eventName].push({element:element, handler:handler, useCapture:useCapture});
+        element.addEventListener(eventName, this, useCapture);
+    },
+
+    stopListeningFor: function(element, eventName, handler, useCapture)
+    {
+        if (typeof useCapture === 'undefined')
+            useCapture = false;
+
+        if (!(this.listeners[eventName] instanceof Array))
+            return;
+
+        this.listeners[eventName] = this.listeners[eventName].filter(function(entry) {
+            return !(entry.element === element && entry.handler === handler && entry.useCapture === useCapture);
+        });
+        element.removeEventListener(eventName, this, useCapture);
+    },
+
+    addVideoListeners: function()
+    {
+        for (var name in this.HandledVideoEvents) {
+            this.listenFor(this.video, name, this.HandledVideoEvents[name]);
+        };
+
+        /* text tracks */
+        this.listenFor(this.video.textTracks, 'change', this.handleTextTrackChange);
+        this.listenFor(this.video.textTracks, 'addtrack', this.handleTextTrackAdd);
+        this.listenFor(this.video.textTracks, 'removetrack', this.handleTextTrackRemove);
+
+        /* audio tracks */
+        this.listenFor(this.video.audioTracks, 'change', this.updateHasAudio);
+        this.listenFor(this.video.audioTracks, 'addtrack', this.updateHasAudio);
+        this.listenFor(this.video.audioTracks, 'removetrack', this.updateHasAudio);
+
+        /* video tracks */
+        this.listenFor(this.video.videoTracks, 'change', this.updateHasVideo);
+        this.listenFor(this.video.videoTracks, 'addtrack', this.updateHasVideo);
+        this.listenFor(this.video.videoTracks, 'removetrack', this.updateHasVideo);
+
+        /* controls attribute */
+        this.controlsObserver = new MutationObserver(this.handleControlsChange.bind(this));
+        this.controlsObserver.observe(this.video, { attributes: true, attributeFilter: ['controls'] });
+    },
+
+    removeVideoListeners: function()
+    {
+        for (var name in this.HandledVideoEvents) {
+            this.stopListeningFor(this.video, name, this.HandledVideoEvents[name]);
+        };
+
+        /* text tracks */
+        this.stopListeningFor(this.video.textTracks, 'change', this.handleTextTrackChange);
+        this.stopListeningFor(this.video.textTracks, 'addtrack', this.handleTextTrackAdd);
+        this.stopListeningFor(this.video.textTracks, 'removetrack', this.handleTextTrackRemove);
+
+        /* audio tracks */
+        this.stopListeningFor(this.video.audioTracks, 'change', this.updateHasAudio);
+        this.stopListeningFor(this.video.audioTracks, 'addtrack', this.updateHasAudio);
+        this.stopListeningFor(this.video.audioTracks, 'removetrack', this.updateHasAudio);
+
+        /* video tracks */
+        this.stopListeningFor(this.video.videoTracks, 'change', this.updateHasVideo);
+        this.stopListeningFor(this.video.videoTracks, 'addtrack', this.updateHasVideo);
+        this.stopListeningFor(this.video.videoTracks, 'removetrack', this.updateHasVideo);
+
+        /* controls attribute */
+        this.controlsObserver.disconnect();
+        delete(this.controlsObserver);
+    },
+
+    handleEvent: function(event)
+    {
+        var preventDefault = false;
+
+        try {
+            if (event.target === this.video) {
+                var handlerName = this.HandledVideoEvents[event.type];
+                var handler = this[handlerName];
+                if (handler && handler instanceof Function)
+                    handler.call(this, event);
+            }
+
+            if (!(this.listeners[event.type] instanceof Array))
+                return;
+
+            this.listeners[event.type].forEach(function(entry) {
+                if (entry.element === event.currentTarget && entry.handler instanceof Function)
+                    preventDefault |= entry.handler.call(this, event);
+            }, this);
+        } catch(e) {
+            if (window.console)
+                console.error(e);
+        }
+
+        if (preventDefault) {
+            event.stopPropagation();
+            event.preventDefault();
+        }
+    },
+
+    createBase: function()
+    {
+        var base = this.base = document.createElement('div');
+        base.setAttribute('pseudo', '-webkit-media-controls');
+        this.listenFor(base, 'mousemove', this.handleWrapperMouseMove);
+        this.listenFor(base, 'mouseout', this.handleWrapperMouseOut);
+        if (this.host.textTrackContainer)
+            base.appendChild(this.host.textTrackContainer);
+    },
+
+    isAudio: function()
+    {
+        return this.video instanceof HTMLAudioElement;
+    },
+
+    isFullScreen: function()
+    {
+        return this.video.webkitDisplayingFullscreen;
+    },
+
+    shouldHaveControls: function()
+    {
+        if (!this.isAudio() && !this.host.allowsInlineMediaPlayback)
             return true;
-    return false;
-};
 
-ControllerAdwaita.prototype = {
+        return this.video.controls || this.isFullScreen();
+    },
 
+    updateBase: function()
+    {
+        if (this.shouldHaveControls() || (this.video.textTracks && this.video.textTracks.length)) {
+            if (!this.base.parentNode) {
+                this.root.appendChild(this.base);
+            }
+        } else {
+            if (this.base.parentNode) {
+                this.base.parentNode.removeChild(this.base);
+            }
+        }
+    },
+
     createControls: function()
     {
-        Controller.prototype.createControls.apply(this);
+        var enclosure = this.controls.enclosure = document.createElement('div');
+        enclosure.setAttribute('pseudo', '-webkit-media-controls-enclosure');
 
-        this.controls.volumeBox.classList.add(this.ClassNames.hiding);
-        this.controls.fullscreenButton.disabled = true;
+        var panel = this.controls.panel = document.createElement('div');
+        panel.setAttribute('pseudo', '-webkit-media-controls-panel');
+        panel.setAttribute('aria-label', (this.isAudio() ? 'Audio Playback' : 'Video Playback'));
+        panel.setAttribute('role', 'toolbar');
+        this.listenFor(panel, 'mousedown', this.handlePanelMouseDown);
+        this.listenFor(panel, 'transitionend', this.handlePanelTransitionEnd);
+        this.listenFor(panel, 'click', this.handlePanelClick);
+        this.listenFor(panel, 'dblclick', this.handlePanelClick);
 
-        this.listenFor(this.controls.muteBox, 'mouseout', this.handleVolumeBoxMouseOut);
-        this.listenFor(this.controls.muteButton, 'mouseover', this.handleMuteButtonMouseOver);
-        this.listenFor(this.controls.volumeBox, 'mouseover', this.handleMuteButtonMouseOver);
-        this.listenFor(this.controls.volume, 'mouseover', this.handleMuteButtonMouseOver);
-        this.listenFor(this.controls.captionButton, 'mouseover', this.handleCaptionButtonMouseOver);
-        this.listenFor(this.controls.captionButton, 'mouseout', this.handleCaptionButtonMouseOut);
+        var playButton = this.controls.playButton = document.createElement('button');
+        playButton.setAttribute('pseudo', '-webkit-media-controls-play-button');
+        playButton.setAttribute('aria-label', 'Play');
+        this.listenFor(playButton, 'click', this.handlePlayButtonClicked);
 
-        var enclosure = this.controls.enclosure = document.createElement('div');
-        enclosure.setAttribute('pseudo', '-webkit-media-controls-enclosure');
+        var timelineBox = this.controls.timelineBox = document.createElement('div');
+        timelineBox.setAttribute('pseudo', '-webkit-media-controls-timeline-container');
+
+        var currentTime = this.controls.currentTime = document.createElement('div');
+        currentTime.setAttribute('pseudo', '-webkit-media-controls-current-time-display');
+        currentTime.setAttribute('aria-label', 'Elapsed');
+        currentTime.setAttribute('role', 'timer');
+
+        var timeline = this.controls.timeline = document.createElement('input');
+        timeline.setAttribute('pseudo', '-webkit-media-controls-timeline');
+        timeline.setAttribute('aria-label', 'Duration');
+        timeline.type = 'range';
+        timeline.value = 0;
+        timeline.step = .01;
+        this.listenFor(timeline, 'input', this.handleTimelineChange);
+        this.listenFor(timeline, 'mouseup', this.handleTimelineMouseUp);
+
+        var muteBox = this.controls.muteBox = document.createElement('div');
+        muteBox.classList.add(this.ClassNames.muteBox);
+        this.listenFor(muteBox, 'mouseout', this.handleVolumeBoxMouseOut);
+
+        var muteButton = this.controls.muteButton = document.createElement('button');
+        muteButton.setAttribute('pseudo', '-webkit-media-controls-mute-button');
+        muteButton.setAttribute('aria-label', 'Mute');
+        this.listenFor(muteButton, 'click', this.handleMuteButtonClicked);
+        this.listenFor(muteButton, 'mouseover', this.handleMuteButtonMouseOver);
+
+        var volumeBox = this.controls.volumeBox = document.createElement('div');
+        volumeBox.setAttribute('pseudo', '-webkit-media-controls-volume-slider-container');
+        volumeBox.classList.add(this.ClassNames.hiding);
+        volumeBox.classList.add(this.ClassNames.volumeBox);
+        this.listenFor(volumeBox, 'mouseover', this.handleMuteButtonMouseOver);
+
+        var volume = this.controls.volume = document.createElement('input');
+        volume.setAttribute('pseudo', '-webkit-media-controls-volume-slider');
+        volume.setAttribute('aria-label', 'Volume');
+        volume.type = 'range';
+        volume.min = 0;
+        volume.max = 1;
+        volume.step = .01;
+        this.listenFor(volume, 'input', this.handleVolumeSliderInput);
+        this.listenFor(volume, 'mouseover', this.handleMuteButtonMouseOver);
+
+        var captionButton = this.controls.captionButton = document.createElement('button');
+        captionButton.setAttribute('pseudo', '-webkit-media-controls-toggle-closed-captions-button');
+        captionButton.setAttribute('aria-label', 'Captions');
+        captionButton.setAttribute('aria-haspopup', 'true');
+        captionButton.setAttribute('aria-owns', 'audioTrackMenu');
+        this.listenFor(captionButton, 'click', this.handleCaptionButtonClicked);
+        this.listenFor(captionButton, 'mouseover', this.handleCaptionButtonMouseOver);
+        this.listenFor(captionButton, 'mouseout', this.handleCaptionButtonMouseOut);
+
+        var fullscreenButton = this.controls.fullscreenButton = document.createElement('button');
+        fullscreenButton.setAttribute('pseudo', '-webkit-media-controls-fullscreen-button');
+        fullscreenButton.setAttribute('aria-label', 'Display Full Screen');
+        fullscreenButton.disabled = true;
+        this.listenFor(fullscreenButton, 'click', this.handleFullscreenButtonClicked);
     },
 
-    configureInlineControls: function()
+    configureControls: function()
     {
         this.controls.panel.appendChild(this.controls.playButton);
         this.controls.panel.appendChild(this.controls.timeline);
@@ -52,28 +312,117 @@
         this.controls.enclosure.appendChild(this.controls.panel);
     },
 
-    shouldHaveControls: function()
+    disconnectControls: function(event)
     {
-        if (!this.isAudio() && !this.host.allowsInlineMediaPlayback)
-            return true;
-
-        return this.video.controls || this.isFullScreen();
+        for (var item in this.controls) {
+            var control = this.controls[item];
+            if (control && control.parentNode)
+                control.parentNode.removeChild(control);
+       }
     },
 
     reconnectControls: function()
     {
-        Controller.prototype.disconnectControls.apply(this, arguments);
+        this.disconnectControls();
+        this.configureControls();
 
-        this.configureInlineControls();
-
         if (this.shouldHaveControls())
             this.addControls();
     },
 
-    setStatusHidden: function(hidden)
+    showControls: function()
     {
+        this.controls.panel.classList.remove(this.ClassNames.hidden);
+        this.controls.panel.classList.add(this.ClassNames.show);
+
+        this.updateTime();
     },
 
+    hideControls: function()
+    {
+        this.controls.panel.classList.remove(this.ClassNames.show);
+    },
+
+    resetHideControlsTimer: function()
+    {
+        if (this.hideTimer)
+            clearTimeout(this.hideTimer);
+        this.hideTimer = setTimeout(this.hideControls.bind(this), this.HideControlsDelay);
+    },
+
+    clearHideControlsTimer: function()
+    {
+        if (this.hideTimer)
+            clearTimeout(this.hideTimer);
+        this.hideTimer = null;
+    },
+
+    controlsAreAlwaysVisible: function()
+    {
+        return this.controls.panel.classList.contains(this.ClassNames.noVideo);
+    },
+
+    controlsAreHidden: function()
+    {
+        if (this.controlsAreAlwaysVisible())
+            return false;
+
+        var panel = this.controls.panel;
+        return (!panel.classList.contains(this.ClassNames.show) || panel.classList.contains(this.ClassNames.hidden))
+            && (panel.parentElement.querySelector(':hover') !== panel);
+    },
+
+    addControls: function()
+    {
+        this.base.appendChild(this.controls.enclosure);
+    },
+
+    removeControls: function()
+    {
+        if (this.controls.enclosure.parentNode)
+            this.controls.enclosure.parentNode.removeChild(this.controls.enclosure);
+        this.hideCaptionMenu();
+    },
+
+    updateControls: function()
+    {
+        this.reconnectControls();
+    },
+
+    setIsLive: function(live)
+    {
+        if (live === this.isLive)
+            return;
+        this.isLive = live;
+
+        this.reconnectControls();
+        this.controls.timeline.disabled = this.isLive;
+    },
+
+    updateDuration: function()
+    {
+        var duration = this.video.duration;
+        this.setIsLive(duration === Number.POSITIVE_INFINITY);
+        this.controls.timeline.min = 0;
+        this.controls.timeline.max = this.isLive ? 0 : duration;
+    },
+
+    formatTime: function(time)
+    {
+        if (isNaN(time))
+            time = 0;
+        var absTime = Math.abs(time);
+        var intSeconds = Math.floor(absTime % 60).toFixed(0);
+        var intMinutes = Math.floor((absTime / 60) % 60).toFixed(0);
+        var intHours = Math.floor(absTime / (60 * 60)).toFixed(0);
+        var sign = time < 0 ? '-' : String();
+
+        if (intHours > 0)
+            return sign + intHours + ':' + String('00' + intMinutes).slice(-2) + ":" + String('00' + intSeconds).slice(-2);
+
+        return sign + String('00' + intMinutes).slice(-2) + ":" + String('00' + intSeconds).slice(-2)
+    },
+
     updateTime: function(forceUpdate)
     {
         if (!forceUpdate && this.controlsAreHidden())
@@ -90,103 +439,389 @@
         }
     },
 
-    handleTimeUpdate: function(event)
+    setPlaying: function(isPlaying)
     {
-        this.updateTime();
+        if (this.isPlaying === isPlaying)
+            return;
+        this.isPlaying = isPlaying;
+
+        if (!isPlaying) {
+            this.controls.panel.classList.add(this.ClassNames.paused);
+            this.controls.playButton.classList.add(this.ClassNames.paused);
+            this.controls.playButton.setAttribute('aria-label', 'Play');
+            this.showControls();
+        } else {
+            this.controls.panel.classList.remove(this.ClassNames.paused);
+            this.controls.playButton.classList.remove(this.ClassNames.paused);
+            this.controls.playButton.setAttribute('aria-label', 'Pause');
+
+            this.hideControls();
+            this.resetHideControlsTimer();
+        }
     },
 
+    updatePlaying: function()
+    {
+        this.setPlaying(!this.canPlay());
+        if (!this.canPlay())
+            this.showControls();
+    },
+
+    updateCaptionButton: function()
+    {
+        if (this.video.webkitHasClosedCaptions)
+            this.controls.captionButton.classList.remove(this.ClassNames.hidden);
+        else
+            this.controls.captionButton.classList.add(this.ClassNames.hidden);
+    },
+
+    updateCaptionContainer: function()
+    {
+        if (!this.host.textTrackContainer)
+            return;
+
+        var hasClosedCaptions = this.video.webkitHasClosedCaptions;
+        var hasHiddenClass = this.host.textTrackContainer.classList.contains(this.ClassNames.hidden);
+
+        if (hasClosedCaptions && hasHiddenClass)
+            this.host.textTrackContainer.classList.remove(this.ClassNames.hidden);
+        else if (!hasClosedCaptions && !hasHiddenClass)
+            this.host.textTrackContainer.classList.add(this.ClassNames.hidden);
+
+        this.updateBase();
+        this.host.updateTextTrackContainer();
+    },
+
+    updateFullscreenButton: function()
+    {
+        if (this.video.readyState > HTMLMediaElement.HAVE_NOTHING && !this.hasVisualMedia) {
+            this.controls.fullscreenButton.classList.add(this.ClassNames.hidden);
+            return;
+        }
+
+        this.controls.fullscreenButton.disabled = !this.host.supportsFullscreen;
+    },
+
+    updateVolume: function()
+    {
+        if (this.video.muted || !this.video.volume) {
+            this.controls.muteButton.classList.add(this.ClassNames.muted);
+            this.controls.volume.value = 0;
+        } else {
+            this.controls.muteButton.classList.remove(this.ClassNames.muted);
+            this.controls.volume.value = this.video.volume;
+        }
+    },
+
     updateHasAudio: function()
     {
         this.controls.muteButton.disabled = this.video.audioTracks.length == 0;
     },
 
-    handleMuteButtonMouseOver: function(event)
+    updateHasVideo: function()
     {
-        if (this.video.offsetTop + this.controls.enclosure.offsetTop < 105) {
-            this.controls.volumeBox.classList.add(this.ClassNames.down);
-            this.controls.panel.classList.add(this.ClassNames.down);
+        if (this.video.videoTracks.length)
+            this.controls.panel.classList.remove(this.ClassNames.noVideo);
+        else
+            this.controls.panel.classList.add(this.ClassNames.noVideo);
+    },
+
+    handleReadyStateChange: function(event)
+    {
+        this.hasVisualMedia = this.video.videoTracks && this.video.videoTracks.length > 0;
+        this.updateVolume();
+        this.updateDuration();
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
+        this.updateFullscreenButton();
+    },
+
+    handleTimeUpdate: function(event)
+    {
+        this.updateTime();
+    },
+
+    handleDurationChange: function(event)
+    {
+        this.updateDuration();
+        this.updateTime(true);
+    },
+
+    handlePlay: function(event)
+    {
+        this.setPlaying(true);
+    },
+
+    handlePause: function(event)
+    {
+        this.setPlaying(false);
+    },
+
+    handleVolumeChange: function(event)
+    {
+        this.updateVolume();
+    },
+
+    handleFullscreenChange: function(event)
+    {
+        this.updateBase();
+        this.updateControls();
+
+        if (this.isFullScreen()) {
+            this.controls.fullscreenButton.setAttribute('aria-label', 'Exit Full Screen');
+            this.host.enteredFullscreen();
         } else {
-            this.controls.volumeBox.classList.remove(this.ClassNames.down);
-            this.controls.panel.classList.remove(this.ClassNames.down);
+            this.controls.fullscreenButton.setAttribute('aria-label', 'Display Full Screen');
+            this.host.exitedFullscreen();
         }
-        this.controls.volumeBox.classList.remove(this.ClassNames.hiding);
+    },
 
-        return true;
+    handleTextTrackChange: function(event)
+    {
+        this.updateCaptionContainer();
     },
 
-    handleVolumeBoxMouseOut: function(event)
+    handleTextTrackAdd: function(event)
     {
-        this.controls.volumeBox.classList.add(this.ClassNames.hiding);
-        return true;
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
     },
 
-    removeControls: function()
+    handleTextTrackRemove: function(event)
     {
-        if (this.controls.enclosure.parentNode)
-            this.controls.enclosure.parentNode.removeChild(this.controls.enclosure);
-        this.destroyCaptionMenu();
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
     },
 
-    addControls: function()
+    handleControlsChange: function()
     {
-        this.base.appendChild(this.controls.enclosure);
+        try {
+            this.updateBase();
+
+            if (this.shouldHaveControls())
+                this.addControls();
+            else
+                this.removeControls();
+        } catch(e) {
+            if (window.console)
+                console.error(e);
+        }
     },
 
-    updateFullscreenButton: function()
+    handleWrapperMouseMove: function(event)
     {
-        if (this.video.readyState > HTMLMediaElement.HAVE_NOTHING && !this.hasVisualMedia) {
-            this.controls.fullscreenButton.classList.add(this.ClassNames.hidden);
+        this.showControls();
+        this.resetHideControlsTimer();
+
+        if (!this.isDragging)
             return;
-        }
+        var delta = new WebKitPoint(event.clientX - this.initialDragLocation.x, event.clientY - this.initialDragLocation.y);
+        this.controls.panel.style.left = this.initialOffset.x + delta.x + 'px';
+        this.controls.panel.style.top = this.initialOffset.y + delta.y + 'px';
+        event.stopPropagation()
+    },
 
-        this.controls.fullscreenButton.disabled = !this.host.supportsFullscreen;
+    handleWrapperMouseOut: function(event)
+    {
+        this.hideControls();
+        this.clearHideControlsTimer();
     },
 
-    updateReadyState: function()
+    handleWrapperMouseUp: function(event)
     {
-        this.updateVolume();
+        this.isDragging = false;
+        this.stopListeningFor(this.base, 'mouseup', 'handleWrapperMouseUp', true);
     },
 
-    updateDuration: function()
+    handlePanelMouseDown: function(event)
     {
-        Controller.prototype.updateDuration.apply(this, arguments);
-        if (this.isLive)
-            this.controls.timeline.max = 0;
+        if (event.target != this.controls.panel)
+            return;
+
+        if (!this.isFullScreen())
+            return;
+
+        this.listenFor(this.base, 'mouseup', this.handleWrapperMouseUp, true);
+        this.isDragging = true;
+        this.initialDragLocation = new WebKitPoint(event.clientX, event.clientY);
+        this.initialOffset = new WebKitPoint(
+            parseInt(this.controls.panel.style.left) | 0,
+            parseInt(this.controls.panel.style.top) | 0
+        );
     },
 
-    setIsLive: function(live)
+    handlePanelTransitionEnd: function(event)
     {
-        Controller.prototype.setIsLive.apply(this, arguments);
-        this.controls.timeline.disabled = this.isLive;
+        var opacity = window.getComputedStyle(this.controls.panel).opacity;
+        if (parseInt(opacity) > 0)
+            this.controls.panel.classList.remove(this.ClassNames.hidden);
+        else
+            this.controls.panel.classList.add(this.ClassNames.hidden);
     },
 
-    updatePlaying: function()
+    handlePanelClick: function(event)
     {
-        Controller.prototype.updatePlaying.apply(this, arguments);
-        if (!this.canPlay())
-            this.showControls();
+        /* Prevent clicks in the panel from playing or pausing the video in a MediaDocument. */
+        event.preventDefault();
     },
 
-    updateProgress: function(forceUpdate)
+    canPlay: function()
     {
+        return this.video.paused || this.video.ended || this.video.readyState < HTMLMediaElement.HAVE_METADATA;
     },
 
-    handleCaptionButtonClicked: function(event)
+    handlePlayButtonClicked: function(event)
     {
-        this.handleCaptionButtonShowMenu(event)
+        if (this.canPlay())
+            this.video.play();
+        else
+            this.video.pause();
         return true;
     },
 
+    handleTimelineChange: function(event)
+    {
+        this.video.fastSeek(this.controls.timeline.value);
+    },
+
+    handleTimelineMouseUp: function(event)
+    {
+        /* Do a precise seek when we lift the mouse. */
+        this.video.currentTime = this.controls.timeline.value;
+    },
+
+    handleMuteButtonClicked: function(event)
+    {
+        this.video.muted = !this.video.muted;
+        if (this.video.muted)
+            this.controls.muteButton.setAttribute('aria-label', 'Unmute');
+        return true;
+    },
+
+    handleMuteButtonMouseOver: function(event)
+    {
+        if (this.video.offsetTop + this.controls.enclosure.offsetTop < 105) {
+            this.controls.volumeBox.classList.add(this.ClassNames.down);
+            this.controls.panel.classList.add(this.ClassNames.down);
+        } else {
+            this.controls.volumeBox.classList.remove(this.ClassNames.down);
+            this.controls.panel.classList.remove(this.ClassNames.down);
+        }
+        this.controls.volumeBox.classList.remove(this.ClassNames.hiding);
+
+        return true;
+    },
+
+    handleVolumeBoxMouseOut: function(event)
+    {
+        this.controls.volumeBox.classList.add(this.ClassNames.hiding);
+        return true;
+    },
+
+    handleVolumeSliderInput: function(event)
+    {
+        if (this.video.muted) {
+            this.video.muted = false;
+            this.controls.muteButton.setAttribute('aria-label', 'Mute');
+        }
+        this.video.volume = this.controls.volume.value;
+    },
+
+    handleFullscreenButtonClicked: function(event)
+    {
+        if (this.isFullScreen())
+            this.video.webkitExitFullscreen();
+        else
+            this.video.webkitEnterFullscreen();
+        return true;
+    },
+
     buildCaptionMenu: function()
     {
-        Controller.prototype.buildCaptionMenu.apply(this, arguments);
+        var tracks = this.host.sortedTrackListForMenu(this.video.textTracks);
+        if (!tracks || !tracks.length)
+            return;
 
-        this.listenFor(this.captionMenu, 'mouseout', this.handleCaptionMouseOut);
+        this.captionMenu = document.createElement('div');
+        this.captionMenu.setAttribute('pseudo', '-webkit-media-controls-closed-captions-container');
+        this.captionMenu.setAttribute('id', 'audioTrackMenu');
+        this.listenFor(this.captionMenu, 'mouseout', this.handleCaptionMenuMouseOut);
         this.listenFor(this.captionMenu, 'transitionend', this.captionMenuTransitionEnd);
+        this.base.appendChild(this.captionMenu);
+        this.captionMenu.captionMenuTreeElements = [];
+        this.captionMenuItems = [];
 
-        this.captionMenu.captionMenuTreeElements = this.captionMenu.getElementsByTagName("*");
+        var offItem = this.host.captionMenuOffItem;
+        var automaticItem = this.host.captionMenuAutomaticItem;
+        var displayMode = this.host.captionDisplayMode;
 
-        // Caption menu has to be centered to the caption button.
+        var list = document.createElement('div');
+        this.captionMenu.appendChild(list);
+        this.captionMenu.captionMenuTreeElements.push(list);
+
+        var heading = document.createElement('h3');
+        heading.id = 'webkitMediaControlsClosedCaptionsHeading';
+        list.appendChild(heading);
+        heading.innerText = 'Subtitles';
+        this.captionMenu.captionMenuTreeElements.push(heading);
+
+        var ul = document.createElement('ul');
+        ul.setAttribute('role', 'menu');
+        ul.setAttribute('aria-labelledby', 'webkitMediaControlsClosedCaptionsHeading');
+        list.appendChild(ul);
+        this.captionMenu.captionMenuTreeElements.push(ul);
+
+        for (var i = 0; i < tracks.length; ++i) {
+            var menuItem = document.createElement('li');
+            menuItem.setAttribute('role', 'menuitemradio');
+            menuItem.setAttribute('tabindex', '-1');
+            this.captionMenuItems.push(menuItem);
+            this.listenFor(menuItem, 'click', this.captionItemSelected);
+            this.listenFor(menuItem, 'keyup', this.handleCaptionItemKeyUp);
+            ul.appendChild(menuItem);
+
+            var track = tracks[i];
+            menuItem.innerText = this.host.displayNameForTrack(track);
+            menuItem.track = track;
+
+            if (track === offItem) {
+                var offMenu = menuItem;
+                continue;
+            }
+
+            if (track === automaticItem) {
+                if (displayMode === 'automatic') {
+                    menuItem.classList.add(this.ClassNames.selected);
+                    menuItem.setAttribute('tabindex', '0');
+                    menuItem.setAttribute('aria-checked', 'true');
+                }
+                continue;
+            }
+
+            if (displayMode != 'automatic' && track.mode === 'showing') {
+                var trackMenuItemSelected = true;
+                menuItem.classList.add(this.ClassNames.selected);
+                menuItem.setAttribute('tabindex', '0');
+                menuItem.setAttribute('aria-checked', 'true');
+            }
+        }
+
+        if (offMenu && displayMode === 'forced-only' && !trackMenuItemSelected) {
+            offMenu.classList.add(this.ClassNames.selected);
+            menuItem.setAttribute('tabindex', '0');
+            menuItem.setAttribute('aria-checked', 'true');
+        }
+
+        /* Focus first selected menuitem. */
+        for (var i = 0, c = this.captionMenuItems.length; i < c; i++) {
+            var item = this.captionMenuItems[i];
+            if (item.classList.contains(this.ClassNames.selected)) {
+                item.focus();
+                break;
+            }
+        }
+
+        /* Caption menu has to be centered to the caption button. */
         var captionButtonCenter =  this.controls.panel.offsetLeft + this.controls.captionButton.offsetLeft +
             this.controls.captionButton.offsetWidth / 2;
         var captionMenuLeft = (captionButtonCenter - this.captionMenu.offsetWidth / 2);
@@ -193,18 +828,66 @@
         if (captionMenuLeft + this.captionMenu.offsetWidth > this.controls.panel.offsetLeft + this.controls.panel.offsetWidth)
             this.captionMenu.classList.add(this.ClassNames.out);
         this.captionMenu.style.left = captionMenuLeft + 'px';
-        // As height is not in the css, it needs to be specified to animate it.
+        /* As height is not in the css, it needs to be specified to animate it. */
         this.captionMenu.height = this.captionMenu.offsetHeight;
         this.captionMenu.style.height = 0;
     },
 
-    destroyCaptionMenu: function()
+    captionItemSelected: function(event)
     {
+        this.host.setSelectedTextTrack(event.target.track);
         this.hideCaptionMenu();
     },
 
+    focusSiblingCaptionItem: function(event)
+    {
+        var currentItem = event.target;
+        var pendingItem = false;
+        switch(event.keyCode) {
+        case this.KeyCodes.left:
+        case this.KeyCodes.up:
+            pendingItem = currentItem.previousSibling;
+            break;
+        case this.KeyCodes.right:
+        case this.KeyCodes.down:
+            pendingItem = currentItem.nextSibling;
+            break;
+        }
+        if (pendingItem) {
+            currentItem.setAttribute('tabindex', '-1');
+            pendingItem.setAttribute('tabindex', '0');
+            pendingItem.focus();
+        }
+    },
+
+    handleCaptionItemKeyUp: function(event)
+    {
+        switch (event.keyCode) {
+        case this.KeyCodes.enter:
+        case this.KeyCodes.space:
+            this.captionItemSelected(event);
+            break;
+        case this.KeyCodes.escape:
+            this.hideCaptionMenu();
+            break;
+        case this.KeyCodes.left:
+        case this.KeyCodes.up:
+        case this.KeyCodes.right:
+        case this.KeyCodes.down:
+            this.focusSiblingCaptionItem(event);
+            break;
+        default:
+            return;
+        }
+
+        event.stopPropagation();
+        event.preventDefault();
+    },
+
     showCaptionMenu: function()
     {
+        if (!this.captionMenu)
+            this.buildCaptionMenu();
         this.captionMenu.style.height = this.captionMenu.height + 'px';
     },
 
@@ -215,40 +898,53 @@
 
     captionMenuTransitionEnd: function(event)
     {
-        if (this.captionMenu.offsetHeight === 0)
-            Controller.prototype.destroyCaptionMenu.apply(this, arguments);
+        if (this.captionMenu.offsetHeight !== 0)
+            return;
+
+        this.captionMenuItems.forEach(function(item) {
+            this.stopListeningFor(item, 'click', this.captionItemSelected);
+            this.stopListeningFor(item, 'keyup', this.handleCaptionItemKeyUp);
+        }, this);
+
+        /* FKA and AX: focus the trigger before destroying the element with focus. */
+        if (this.controls.captionButton)
+            this.controls.captionButton.focus();
+
+        if (this.captionMenu.parentNode)
+            this.captionMenu.parentNode.removeChild(this.captionMenu);
+        delete this.captionMenu;
+        delete this.captionMenuItems;
     },
 
-    handleCaptionButtonMouseOver: function(event)
+    captionMenuContainsNode: function(node)
     {
-        this.handleCaptionButtonShowMenu(event);
+        return this.captionMenu.captionMenuTreeElements.find((item) => item == node)
+            || this.captionMenuItems.find((item) => item == node);
+    },
+
+    handleCaptionButtonClicked: function(event)
+    {
+        this.showCaptionMenu();
         return true;
     },
 
-    handleCaptionButtonShowMenu: function(event)
+    handleCaptionButtonMouseOver: function(event)
     {
-        if (!this.captionMenu)
-            this.buildCaptionMenu();
-        if (!contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget))
-            this.showCaptionMenu();
+        this.showCaptionMenu();
         return true;
     },
 
     handleCaptionButtonMouseOut: function(event)
     {
-        if (this.captionMenu && !contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget))
+        if (this.captionMenu && !this.captionMenuContainsNode(event.relatedTarget))
             this.hideCaptionMenu();
         return true;
     },
 
-    handleCaptionMouseOut: function(event)
+    handleCaptionMenuMouseOut: function(event)
     {
-        if (event.relatedTarget != this.controls.captionButton &&
-            !contains(this.captionMenu.captionMenuTreeElements, event.relatedTarget))
+        if (event.relatedTarget != this.controls.captionButton && !this.captionMenuContainsNode(event.relatedTarget))
             this.hideCaptionMenu();
         return true;
     },
 };
-
-Object.create(Controller.prototype).extend(ControllerAdwaita.prototype);
-Object.defineProperty(ControllerAdwaita.prototype, 'constructor', { enumerable:false, value:ControllerAdwaita });

Modified: trunk/Source/WebCore/Modules/mediacontrols/mediaControlsBase.js (257704 => 257705)


--- trunk/Source/WebCore/Modules/mediacontrols/mediaControlsBase.js	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/Modules/mediacontrols/mediaControlsBase.js	2020-03-02 10:27:42 UTC (rev 257705)
@@ -91,7 +91,6 @@
         thumbnailTrack: 'thumbnail-track',
         volumeBox: 'volume-box',
         noVideo: 'no-video',
-        noDuration: 'no-duration',
         down: 'down',
         out: 'out',
     },

Modified: trunk/Source/WebCore/PlatformGTK.cmake (257704 => 257705)


--- trunk/Source/WebCore/PlatformGTK.cmake	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2020-03-02 10:27:42 UTC (rev 257705)
@@ -70,9 +70,7 @@
 )
 
 set(WebCore_USER_AGENT_SCRIPTS
-    ${WEBCORE_DIR}/en.lproj/mediaControlsLocalizedStrings.js
     ${WEBCORE_DIR}/Modules/mediacontrols/mediaControlsAdwaita.js
-    ${WEBCORE_DIR}/Modules/mediacontrols/mediaControlsBase.js
 )
 
 set(WebCore_USER_AGENT_SCRIPTS_DEPENDENCIES ${WEBCORE_DIR}/rendering/RenderThemeAdwaita.cpp)

Modified: trunk/Source/WebCore/PlatformWPE.cmake (257704 => 257705)


--- trunk/Source/WebCore/PlatformWPE.cmake	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/PlatformWPE.cmake	2020-03-02 10:27:42 UTC (rev 257705)
@@ -45,8 +45,6 @@
 )
 
 set(WebCore_USER_AGENT_SCRIPTS
-    ${WEBCORE_DIR}/en.lproj/mediaControlsLocalizedStrings.js
-    ${WEBCORE_DIR}/Modules/mediacontrols/mediaControlsBase.js
     ${WEBCORE_DIR}/Modules/mediacontrols/mediaControlsAdwaita.js
 )
 

Modified: trunk/Source/WebCore/rendering/RenderThemeAdwaita.cpp (257704 => 257705)


--- trunk/Source/WebCore/rendering/RenderThemeAdwaita.cpp	2020-03-02 08:41:07 UTC (rev 257704)
+++ trunk/Source/WebCore/rendering/RenderThemeAdwaita.cpp	2020-03-02 10:27:42 UTC (rev 257705)
@@ -41,7 +41,6 @@
 #include "TimeRanges.h"
 #include "UserAgentScripts.h"
 #include "UserAgentStyleSheets.h"
-#include <wtf/text/StringBuilder.h>
 
 namespace WebCore {
 
@@ -175,11 +174,7 @@
 
 String RenderThemeAdwaita::mediaControlsScript()
 {
-    StringBuilder scriptBuilder;
-    scriptBuilder.appendCharacters(mediaControlsLocalizedStringsJavaScript, sizeof(mediaControlsLocalizedStringsJavaScript));
-    scriptBuilder.appendCharacters(mediaControlsBaseJavaScript, sizeof(mediaControlsBaseJavaScript));
-    scriptBuilder.appendCharacters(mediaControlsAdwaitaJavaScript, sizeof(mediaControlsAdwaitaJavaScript));
-    return scriptBuilder.toString();
+    return String(mediaControlsAdwaitaJavaScript, sizeof(mediaControlsAdwaitaJavaScript));
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to