[Mac] Implement the media controls in JavaScript.
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2013 16:05:05 +0000 (16:05 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2013 16:05:05 +0000 (16:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=120895

Reviewed by Dean Jackson.

Source/JavaScriptCore:

Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.

* Configurations/FeatureDefines.xcconfig:

Source/WebCore:

Re-implement the existing MediaControls constellation of classes in JavaScript
and CSS. This will allow different ports to configure their controls without
dependencies on the layout requirements of any other port's controls.

Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT:
* Configurations/FeatureDefines.xcconfig:

Add new source files to the project:
* DerivedSources.cpp:
* DerivedSources.make:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:

Add a new class MediaControlsHost which the script controls can use to
communicate with the HTMLMediaElement without exposing private interfaces
to web facing scripts:
* Modules/mediacontrols/MediaControlsHost.cpp: Added.
(WebCore::MediaControlsHost::automaticKeyword): Static method.
(WebCore::MediaControlsHost::forcedOnlyKeyword): Ditto.
(WebCore::MediaControlsHost::alwaysOnKeyword): Ditto.
(WebCore::MediaControlsHost::create): Simple factory.
(WebCore::MediaControlsHost::MediaControlsHost): Simple constructor.
(WebCore::MediaControlsHost::~MediaControlsHost): Simple destructor.
(WebCore::MediaControlsHost::sortedTrackListForMenu): Pass through to CaptionUserPreferences.
(WebCore::MediaControlsHost::displayNameForTrack): Ditto.
(WebCore::MediaControlsHost::captionMenuOffItem): Pass through to TextTrack.
(WebCore::MediaControlsHost::captionMenuAutomaticItem): Ditto.
(WebCore::MediaControlsHost::captionDisplayMode): Pass through to CaptionUserPreferences.
(WebCore::MediaControlsHost::setSelectedTextTrack): Pass through to HTMLMediaElement.
(WebCore::MediaControlsHost::textTrackContainer): Lazily create a MediaControlTextTrackContainerElement.
(WebCore::MediaControlsHost::updateTextTrackContainer): Pass through to MediaControlTextTrackContainerElement.
* Modules/mediacontrols/MediaControlsHost.h: Added.
* Modules/mediacontrols/MediaControlsHost.idl: Added.
* Modules/mediacontrols/mediaControlsApple.css: Added.

Add convenience methods for adding a MediaControlsHost to a VM.
* bindings/js/ScriptObject.cpp:
(WebCore::ScriptGlobalObject::set):
* bindings/js/ScriptObject.h:

Add the new controller .js implementation:
* Modules/mediacontrols/mediaControlsApple.js: Added.
(createControls): Global method to create a new Controller object.
(Controller): Constructor. Create and configure the default set of controls.
(Controller.prototype.addListeners): Adds event listeners to the this.video object.
(Controller.prototype.removeListeners): Removes listeners from same.
(Controller.prototype.handleEvent): Makes Controller an EventHandler, making registration and
        deregistration simpler.
(Controller.prototype.createBase): Creates the base controls object and the text track container.
(Controller.prototype.createControls): Creates the controls panel object and controller UI.
(Controller.prototype.setControlsType): Switches between Full Screen and Inline style of controller.
(Controller.prototype.disconnectControls): Disconnects all UI elements from the DOM.
(Controller.prototype.configureInlineControls): Configures existing controls for Inline mode.
(Controller.prototype.configureFullScreenControls): Ditto, for Full Screen Mode.

Add listeners for HTMLMediaElement events:
(Controller.prototype.onloadstart): Update the status display.
(Controller.prototype.onerror): Ditto.
(Controller.prototype.onabort): Ditto.
(Controller.prototype.onsuspend): Ditto.
(Controller.prototype.onprogress): Ditto.
(Controller.prototype.onstalled): Ditto.
(Controller.prototype.onwaiting): Ditto.
(Controller.prototype.onreadystatechange): Ditto.
(Controller.prototype.ontimeupdate): Update the timeline and time displays.
(Controller.prototype.ondurationchange): Ditto.
(Controller.prototype.onplaying): Update the play button.
(Controller.prototype.onplay): Ditto.
(Controller.prototype.onpause): Ditto.
(Controller.prototype.onratechange): Ditto.
(Controller.prototype.onvolumechange): Update the volume and mute UI.
(Controller.prototype.ontexttrackchange): Update the text track container and captions button.
(Controller.prototype.ontexttrackadd): Ditto.
(Controller.prototype.ontexttrackremove): Ditto.
(Controller.prototype.ontexttrackcuechange): Ditto.
(Controller.prototype.onfullscreenchange): Reconfigure the controls.

Add listeners for UI element events:
(Controller.prototype.onwrappermousemove): Show the controls and start the hide timer.
(Controller.prototype.onwrappermouseout): Hide the controls and stop the hide timer.
(Controller.prototype.onrewindbuttonclicked): Rewind.
(Controller.prototype.onplaybuttonclicked): Toggle pause.
(Controller.prototype.ontimelinechange): Update the currentTime.
(Controller.prototype.ontimelinedown):
(Controller.prototype.ontimelineup):
(Controller.prototype.ontimelinemouseover): Show the thumbnail view if available.
(Controller.prototype.ontimelinemouseout): Hide same.
(Controller.prototype.ontimelinemousemove): Move the thumbnail view.
(Controller.prototype.onmutebuttonclicked): Mute audio.
(Controller.prototype.onminbuttonclicked): Increase volume to max.
(Controller.prototype.onmaxbuttonclicked): Decrease volume to min.
(Controller.prototype.onvolumesliderchange): Update the current volume.
(Controller.prototype.oncaptionbuttonclicked): Show or hide the track menu.
(Controller.prototype.onfullscreenbuttonclicked): Enter or exit fullscreen.
(Controller.prototype.oncontrolschange): Show or hide the controls panel.
(Controller.prototype.onseekbackmousedown): Start seeking and enable the seek timer.
(Controller.prototype.onseekbackmouseup): Stop seeking and disable the seek timer.
(Controller.prototype.onseekforwardmousedown): Start seekind and enable the seek timer.
(Controller.prototype.onseekforwardmouseup): Stop seekind and disable the seek timer.

Add action methods (which are mostly self explanatory):
(Controller.prototype.updateDuration):
(Controller.prototype.updatePlaying):
(Controller.prototype.showControls):
(Controller.prototype.hideControls):
(Controller.prototype.removeControls):
(Controller.prototype.addControls):
(Controller.prototype.updateTime):
(Controller.prototype.updateReadyState):
(Controller.prototype.setStatusHidden):
(Controller.prototype.updateThumbnailTrack):
(Controller.prototype.updateCaptionButton):
(Controller.prototype.updateCaptionContainer):
(Controller.prototype.buildCaptionMenu):
(Controller.prototype.captionItemSelected):
(Controller.prototype.destroyCaptionMenu):
(Controller.prototype.updateVolume):

Add utility methods:
(Controller.prototype.isFullScreen):
(Controller.prototype.canPlay):
(Controller.prototype.nextRate):
(Controller.prototype.seekBackFaster):
(Controller.prototype.seekForwardFaster):
(Controller.prototype.formatTime):
(Controller.prototype.trackHasThumbnails):

Add the stylesheet for the javascript controls (which are mostly) copied from
the (deleted) mediaControlsQuickTime.css and fullscreenQuickTime.css files:
* Modules/mediacontrols/mediaControlsApple.css: Added.
* css/fullscreenQuickTime.css: Removed.
* css/mediaControlsQuickTime.css: Removed.

Inject new stylesheets into UA sheets:
* css/CSSDefaultStyleSheets.cpp:
(WebCore::CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement):

Use the new javascript controls rather than MediaControls:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::childShouldCreateRenderer): Use the javascript controls if available.
(WebCore::HTMLMediaElement::updateTextTrackDisplay): Ditto.
(WebCore::HTMLMediaElement::mediaControls): Ditto.
(WebCore::HTMLMediaElement::hasMediaControls): Ditto.
(WebCore::HTMLMediaElement::createMediaControls): Ditto.
(WebCore::HTMLMediaElement::configureMediaControls): Ditto.
(WebCore::HTMLMediaElement::configureTextTrackDisplay): Ditto.
(WebCore::HTMLMediaElement::ensureIsolatedWorld): Create a new VM for the controls script.
(WebCore::HTMLMediaElement::ensureMediaControlsInjectedScript): Inject the media controls script into the VM.
(WebCore::HTMLMediaElement::didAddUserAgentShadowRoot): Inject the MediaControlsHost into the VM and call
        the scripts global factory function.
* html/HTMLMediaElement.h:

Remove most of the drawing code from RenderThemeMac and RenderThemeWin and
add accessors for the new .js and .css file data:
* rendering/RenderTheme.h:
(WebCore::RenderTheme::mediaControlsStyleSheet): Empty virtual method.
(WebCore::RenderTheme::mediaControlsScript): Ditto.
* rendering/RenderThemeMac.h:
* rendering/RenderThemeMac.mm:
(WebCore::RenderThemeMac::mediaControlsStyleSheet): Add accessor for mediaControlsApple.css.
(WebCore::RenderThemeMac::mediaControlsScript): Add accessor for mediaControlsApple.js.
(WebCore::RenderThemeMac::adjustSliderThumbSize): Remove the call to adjustMediaSliderThumbSize.
* rendering/RenderThemeWin.cpp:
(WebCore::RenderThemeWin::mediaControlsStyleSheet):
(WebCore::RenderThemeWin::mediaControlsScript):
* rendering/RenderThemeWin.h:

Source/WebKit/mac:

Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.

* Configurations/FeatureDefines.xcconfig:

Source/WebKit2:

Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.

* Configurations/FeatureDefines.xcconfig:

Source/WTF:

Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.

* wtf/FeatureDefines.h:

LayoutTests:

Rebaseline changed tests and add new (failing) tests to
TestExpectations.

* media/audio-delete-while-slider-thumb-clicked.html:
* platform/mac/TestExpectations:
* platform/mac/fast/hidpi/video-controls-in-hidpi-expected.png:
* platform/mac/fast/hidpi/video-controls-in-hidpi-expected.txt:
* platform/mac/fast/layers/video-layer-expected.png:
* platform/mac/fast/layers/video-layer-expected.txt:
* platform/mac/fullscreen/video-controls-override-expected.txt: Added.
* platform/mac/media/audio-controls-rendering-expected.png:
* platform/mac/media/audio-controls-rendering-expected.txt:
* platform/mac/media/controls-after-reload-expected.png:
* platform/mac/media/controls-after-reload-expected.txt:
* platform/mac/media/controls-strict-expected.png:
* platform/mac/media/controls-strict-expected.txt:
* platform/mac/media/controls-styling-strict-expected.png:
* platform/mac/media/controls-styling-strict-expected.txt:
* platform/mac/media/controls-without-preload-expected.png:
* platform/mac/media/controls-without-preload-expected.txt:
* platform/mac/media/media-controls-clone-expected.png:
* platform/mac/media/media-controls-clone-expected.txt:
* webarchive/loading/video-in-webarchive-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@156546 268f45cc-cd09-0410-ab3c-d52691b4dbfc

54 files changed:
LayoutTests/ChangeLog
LayoutTests/media/audio-delete-while-slider-thumb-clicked.html
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/mac/fast/hidpi/video-controls-in-hidpi-expected.png
LayoutTests/platform/mac/fast/hidpi/video-controls-in-hidpi-expected.txt
LayoutTests/platform/mac/fast/layers/video-layer-expected.png
LayoutTests/platform/mac/fast/layers/video-layer-expected.txt
LayoutTests/platform/mac/fullscreen/video-controls-override-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/media/audio-controls-rendering-expected.png
LayoutTests/platform/mac/media/audio-controls-rendering-expected.txt
LayoutTests/platform/mac/media/controls-after-reload-expected.png
LayoutTests/platform/mac/media/controls-after-reload-expected.txt
LayoutTests/platform/mac/media/controls-strict-expected.png
LayoutTests/platform/mac/media/controls-strict-expected.txt
LayoutTests/platform/mac/media/controls-styling-strict-expected.png
LayoutTests/platform/mac/media/controls-styling-strict-expected.txt
LayoutTests/platform/mac/media/controls-without-preload-expected.png
LayoutTests/platform/mac/media/controls-without-preload-expected.txt
LayoutTests/platform/mac/media/media-controls-clone-expected.png
LayoutTests/platform/mac/media/media-controls-clone-expected.txt
LayoutTests/platform/mac/webarchive/loading/video-in-webarchive-expected.txt [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
Source/WTF/ChangeLog
Source/WTF/wtf/FeatureDefines.h
Source/WebCore/ChangeLog
Source/WebCore/Configurations/FeatureDefines.xcconfig
Source/WebCore/DerivedSources.cpp
Source/WebCore/DerivedSources.make
Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp [new file with mode: 0644]
Source/WebCore/Modules/mediacontrols/MediaControlsHost.h [new file with mode: 0644]
Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl [new file with mode: 0644]
Source/WebCore/Modules/mediacontrols/mediaControlsApple.css [new file with mode: 0644]
Source/WebCore/Modules/mediacontrols/mediaControlsApple.js [new file with mode: 0644]
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/ScriptObject.cpp
Source/WebCore/bindings/js/ScriptObject.h
Source/WebCore/css/CSSDefaultStyleSheets.cpp
Source/WebCore/css/fullscreenQuickTime.css [deleted file]
Source/WebCore/css/mediaControlsQuickTime.css [deleted file]
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/rendering/RenderTextTrackCue.cpp
Source/WebCore/rendering/RenderTheme.h
Source/WebCore/rendering/RenderThemeMac.h
Source/WebCore/rendering/RenderThemeMac.mm
Source/WebCore/rendering/RenderThemeWin.cpp
Source/WebCore/rendering/RenderThemeWin.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Configurations/FeatureDefines.xcconfig
Source/WebKit2/ChangeLog
Source/WebKit2/Configurations/FeatureDefines.xcconfig

index ed190b1..036bfac 100644 (file)
@@ -1,3 +1,34 @@
+2013-09-27  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Rebaseline changed tests and add new (failing) tests to
+        TestExpectations.
+
+        * media/audio-delete-while-slider-thumb-clicked.html:
+        * platform/mac/TestExpectations:
+        * platform/mac/fast/hidpi/video-controls-in-hidpi-expected.png:
+        * platform/mac/fast/hidpi/video-controls-in-hidpi-expected.txt:
+        * platform/mac/fast/layers/video-layer-expected.png:
+        * platform/mac/fast/layers/video-layer-expected.txt:
+        * platform/mac/fullscreen/video-controls-override-expected.txt: Added.
+        * platform/mac/media/audio-controls-rendering-expected.png:
+        * platform/mac/media/audio-controls-rendering-expected.txt:
+        * platform/mac/media/controls-after-reload-expected.png:
+        * platform/mac/media/controls-after-reload-expected.txt:
+        * platform/mac/media/controls-strict-expected.png:
+        * platform/mac/media/controls-strict-expected.txt:
+        * platform/mac/media/controls-styling-strict-expected.png:
+        * platform/mac/media/controls-styling-strict-expected.txt:
+        * platform/mac/media/controls-without-preload-expected.png:
+        * platform/mac/media/controls-without-preload-expected.txt:
+        * platform/mac/media/media-controls-clone-expected.png:
+        * platform/mac/media/media-controls-clone-expected.txt:
+        * webarchive/loading/video-in-webarchive-expected.txt:
+
 2013-09-27  Bem Jones-Bey  <bjonesbe@adobe.com>
 
         [css-shapes] Shapes are not resolved the same way in shape-inside and clip-path
index 052dadf..f5b5e3c 100644 (file)
 
                 // click the button
                 var button = document.getElementById('button');
-                eventSender.mouseMoveTo(button.offsetLeft + 20, button.offsetTop + 7);
-                eventSender.mouseDown();
-                eventSender.mouseUp();
 
-                testRunner.notifyDone();
+                if (window.eventSender) {
+                    eventSender.mouseMoveTo(button.offsetLeft + 20, button.offsetTop + 7);
+                    eventSender.mouseDown();
+                    eventSender.mouseUp();
+                }
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
             }
             
             function deleteAudio()
                 log("clicking on thumb");
                 eventSender.mouseDown();
                 eventSender.mouseMoveTo(x, y + 20);
-
-                // Remove the element after seeking started
-                audio.addEventListener("seeking", deleteAudio);
             }
 
 
             function start()
             {
                 setSrcByTagName("audio", findMediaFile("audio", "content/test"));
+
+                // Remove the element after seeking started
+                audio.addEventListener("seeking", deleteAudio);
             }
 
         </script>
index 053abfe..39436c7 100644 (file)
@@ -1338,3 +1338,11 @@ webkit.org/b/96642 loader/go-back-to-different-window-size.html [ Pass Failure T
 webkit.org/b/114193 transitions/cancel-transition.html [ Pass Failure ]
 
 webkit.org/b/121998 http/tests/inspector/network/network-iframe-load-and-delete.html [ Pass Failure ]
+
+webkit.org/b/121990 accessibility/media-element.html [ Failure ]
+webkit.org/b/121992 media/media-volume-slider-rendered-below.html [ Failure ]
+webkit.org/b/121992 media/media-volume-slider-rendered-normal.html [ Timeout Failure ]
+webkit.org/b/121995 media/video-controls-captions-trackmenu-hide-on-click-outside.html [ Timeout Failure ]
+webkit.org/b/121995 media/video-controls-captions-trackmenu-hide-on-click.html [ Timeout Failure ]
+webkit.org/b/121995 media/video-controls-captions-trackmenu-includes-enabled-track.html [ Timeout Failure ]
+
index 60db138..36535fb 100644 (file)
Binary files a/LayoutTests/platform/mac/fast/hidpi/video-controls-in-hidpi-expected.png and b/LayoutTests/platform/mac/fast/hidpi/video-controls-in-hidpi-expected.png differ
index 78d2d8f..1bbaa4c 100644 (file)
@@ -14,6 +14,17 @@ layer at (8,26) size 300x150
   RenderFlexibleBox {DIV} at (0,0) size 300x150
 layer at (8,151) size 300x25
   RenderFlexibleBox {DIV} at (0,125) size 300x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (14,155) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,156) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,159) size 197x9
+  RenderFlexibleBox {DIV} at (49,8) size 197x9
+layer at (59,159) size 193x9
+  RenderFlexibleBox {DIV} at (2,0) size 193x9
+layer at (254,153) size 22x22
+  RenderFlexibleBox {DIV} at (246,2) size 22x22
+layer at (257,156) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (285,156) size 16x16
+  RenderButton {BUTTON} at (277,5) size 16x16 [color=#FFFFFF]
index 297df5b..0b521ff 100644 (file)
Binary files a/LayoutTests/platform/mac/fast/layers/video-layer-expected.png and b/LayoutTests/platform/mac/fast/layers/video-layer-expected.png differ
index c1bdb5e..13d6d80 100644 (file)
@@ -19,6 +19,17 @@ layer at (59,111) size 300x150
   RenderFlexibleBox {DIV} at (1,1) size 300x150
 layer at (59,236) size 300x25
   RenderFlexibleBox {DIV} at (0,125) size 300x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (65,240) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (91,241) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (108,244) size 197x9
+  RenderFlexibleBox {DIV} at (49,8) size 197x9
+layer at (110,244) size 193x9
+  RenderFlexibleBox {DIV} at (2,0) size 193x9
+layer at (305,238) size 22x22
+  RenderFlexibleBox {DIV} at (246,2) size 22x22
+layer at (308,241) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (336,241) size 16x16
+  RenderButton {BUTTON} at (277,5) size 16x16 [color=#FFFFFF]
diff --git a/LayoutTests/platform/mac/fullscreen/video-controls-override-expected.txt b/LayoutTests/platform/mac/fullscreen/video-controls-override-expected.txt
new file mode 100644 (file)
index 0000000..43ae989
--- /dev/null
@@ -0,0 +1,12 @@
+This tests that the video element's "controls" attribute is overridden in full screen mode, and that the controls are correctly hidden upon exiting full screen. Press any key to continue.
+
+EVENT(webkitfullscreenchange)
+EXPECTED (shadowRoot = internals.shadowRoot(video) != 'null') OK
+EXPECTED (panel = mediaControlsElement(shadowRoot.firstChild, '-webkit-media-controls-panel') != 'null') OK
+EXPECTED (internals.shadowPseudoId(panel) == '-webkit-media-controls-panel') OK
+EXPECTED (document.defaultView.getComputedStyle(panel)['display'] != 'none') OK
+EXPECTED (document.defaultView.getComputedStyle(panel)['height'] >= '20px') OK
+EVENT(webkitfullscreenchange)
+EXPECTED (document.defaultView.getComputedStyle(panel)['display'] == 'none'), OBSERVED '' FAIL
+END OF TEST
+
index 37b3529..863e688 100644 (file)
Binary files a/LayoutTests/platform/mac/media/audio-controls-rendering-expected.png and b/LayoutTests/platform/mac/media/audio-controls-rendering-expected.png differ
index b835b1f..58a6324 100644 (file)
@@ -18,63 +18,94 @@ layer at (8,42) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
 layer at (8,42) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 126x15
-      RenderSlider {INPUT} at (0,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderBlock {DIV} at (175,6) size 25x12
-layer at (185,48) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (14,46) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,47) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,49) size 127x11
+  RenderFlexibleBox {DIV} at (49,7) size 127x11
+layer at (57,49) size 45x11
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
+    RenderBlock (anonymous) at (9,0) size 26x11
+      RenderText {#text} at (0,0) size 26x11
+        text run at (0,0) width 26: "00:00"
+layer at (139,49) size 45x11
+  RenderFlexibleBox {DIV} at (82,0) size 45x11 [color=#FFFFFF]
+    RenderBlock (anonymous) at (7,0) size 31x11
+      RenderText {#text} at (0,0) size 31x11
+        text run at (0,0) width 31: "-00:07"
+layer at (104,50) size 33x9
+  RenderFlexibleBox {DIV} at (47,1) size 33x9
+    RenderSlider {INPUT} at (0,0) size 33x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 33x9
+        RenderBlock {DIV} at (0,1) size 33x6
+layer at (104,51) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (184,44) size 22x22
+  RenderFlexibleBox {DIV} at (176,2) size 22x22
+layer at (187,47) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
 layer at (8,85) size 320x25
   RenderFlexibleBox {DIV} at (0,0) size 320x25
 layer at (8,85) size 320x25
   RenderFlexibleBox {DIV} at (0,0) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 246x15
-      RenderSlider {INPUT} at (45,2) size 156x13
-        RenderFlexibleBox {DIV} at (0,0) size 156x13
-          RenderBlock {DIV} at (0,2) size 156x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderBlock {DIV} at (295,6) size 25x12
+layer at (14,89) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,90) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,92) size 247x11
+  RenderFlexibleBox {DIV} at (49,7) size 247x11
 layer at (57,92) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (258,92) size 45x11
-  RenderFlexibleBox {DIV} at (201,2) size 45x11 [color=#FFFFFF]
+layer at (259,92) size 45x11
+  RenderFlexibleBox {DIV} at (202,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:07"
-layer at (305,91) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,93) size 153x9
+  RenderFlexibleBox {DIV} at (47,1) size 153x9
+    RenderSlider {INPUT} at (0,0) size 153x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 153x9
+        RenderBlock {DIV} at (0,1) size 153x6
+layer at (104,94) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (304,87) size 22x22
+  RenderFlexibleBox {DIV} at (296,2) size 22x22
+layer at (307,90) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
 layer at (8,128) size 320x100
   RenderMedia {AUDIO} at (8,128) size 320x100 [bgcolor=#0000FF]
 layer at (8,128) size 320x100
   RenderFlexibleBox {DIV} at (0,0) size 320x100
 layer at (8,203) size 320x25
   RenderFlexibleBox {DIV} at (0,75) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 246x15
-      RenderSlider {INPUT} at (45,2) size 156x13
-        RenderFlexibleBox {DIV} at (0,0) size 156x13
-          RenderBlock {DIV} at (0,2) size 156x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderBlock {DIV} at (295,6) size 25x12
+layer at (14,207) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,208) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,210) size 247x11
+  RenderFlexibleBox {DIV} at (49,7) size 247x11
 layer at (57,210) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (258,210) size 45x11
-  RenderFlexibleBox {DIV} at (201,2) size 45x11 [color=#FFFFFF]
+layer at (259,210) size 45x11
+  RenderFlexibleBox {DIV} at (202,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:07"
-layer at (305,209) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,211) size 153x9
+  RenderFlexibleBox {DIV} at (47,1) size 153x9
+    RenderSlider {INPUT} at (0,0) size 153x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 153x9
+        RenderBlock {DIV} at (0,1) size 153x6
+layer at (104,212) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (304,205) size 22x22
+  RenderFlexibleBox {DIV} at (296,2) size 22x22
+layer at (307,208) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
index 32280a6..f15aa96 100644 (file)
Binary files a/LayoutTests/platform/mac/media/controls-after-reload-expected.png and b/LayoutTests/platform/mac/media/controls-after-reload-expected.png differ
index 1c3ad10..daa7f21 100644 (file)
@@ -14,24 +14,32 @@ layer at (8,42) size 320x240
   RenderFlexibleBox {DIV} at (0,0) size 320x240
 layer at (8,257) size 320x25
   RenderFlexibleBox {DIV} at (0,215) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 216x15
-      RenderSlider {INPUT} at (45,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderButton {INPUT} at (297,4) size 16x16
-    RenderBlock {DIV} at (265,6) size 25x12
+layer at (14,261) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,262) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,264) size 217x11
+  RenderFlexibleBox {DIV} at (49,7) size 217x11
 layer at (57,264) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (228,264) size 45x11
-  RenderFlexibleBox {DIV} at (171,2) size 45x11 [color=#FFFFFF]
+layer at (229,264) size 45x11
+  RenderFlexibleBox {DIV} at (172,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:06"
-layer at (275,263) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,265) size 123x9
+  RenderFlexibleBox {DIV} at (47,1) size 123x9
+    RenderSlider {INPUT} at (0,0) size 123x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 123x9
+        RenderBlock {DIV} at (0,1) size 123x6
+layer at (104,266) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (274,259) size 22x22
+  RenderFlexibleBox {DIV} at (266,2) size 22x22
+layer at (277,262) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (305,262) size 16x16
+  RenderButton {BUTTON} at (297,5) size 16x16 [color=#FFFFFF]
index 3d2c69c..168ead9 100644 (file)
Binary files a/LayoutTests/platform/mac/media/controls-strict-expected.png and b/LayoutTests/platform/mac/media/controls-strict-expected.png differ
index 191f6a8..3bc1af4 100644 (file)
@@ -14,24 +14,32 @@ layer at (8,50) size 320x240
   RenderFlexibleBox {DIV} at (0,0) size 320x240
 layer at (8,265) size 320x25
   RenderFlexibleBox {DIV} at (0,215) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 216x15
-      RenderSlider {INPUT} at (45,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderButton {INPUT} at (297,4) size 16x16
-    RenderBlock {DIV} at (265,6) size 25x12
+layer at (14,269) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,270) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,272) size 217x11
+  RenderFlexibleBox {DIV} at (49,7) size 217x11
 layer at (57,272) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (228,272) size 45x11
-  RenderFlexibleBox {DIV} at (171,2) size 45x11 [color=#FFFFFF]
+layer at (229,272) size 45x11
+  RenderFlexibleBox {DIV} at (172,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:06"
-layer at (275,271) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,273) size 123x9
+  RenderFlexibleBox {DIV} at (47,1) size 123x9
+    RenderSlider {INPUT} at (0,0) size 123x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 123x9
+        RenderBlock {DIV} at (0,1) size 123x6
+layer at (104,274) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (274,267) size 22x22
+  RenderFlexibleBox {DIV} at (266,2) size 22x22
+layer at (277,270) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (305,270) size 16x16
+  RenderButton {BUTTON} at (297,5) size 16x16 [color=#FFFFFF]
index a30be7f..478e5d1 100644 (file)
Binary files a/LayoutTests/platform/mac/media/controls-styling-strict-expected.png and b/LayoutTests/platform/mac/media/controls-styling-strict-expected.png differ
index eb7bb1b..a8d31e7 100644 (file)
@@ -18,49 +18,65 @@ layer at (8,50) size 320x240
   RenderFlexibleBox {DIV} at (0,0) size 320x240
 layer at (8,265) size 320x25
   RenderFlexibleBox {DIV} at (0,215) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 216x15
-      RenderSlider {INPUT} at (45,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderButton {INPUT} at (297,4) size 16x16
-    RenderBlock {DIV} at (265,6) size 25x12
+layer at (14,269) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,270) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,272) size 217x11
+  RenderFlexibleBox {DIV} at (49,7) size 217x11
 layer at (57,272) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (228,272) size 45x11
-  RenderFlexibleBox {DIV} at (171,2) size 45x11 [color=#FFFFFF]
+layer at (229,272) size 45x11
+  RenderFlexibleBox {DIV} at (172,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:06"
-layer at (275,271) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,273) size 123x9
+  RenderFlexibleBox {DIV} at (47,1) size 123x9
+    RenderSlider {INPUT} at (0,0) size 123x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 123x9
+        RenderBlock {DIV} at (0,1) size 123x6
+layer at (104,274) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (274,267) size 22x22
+  RenderFlexibleBox {DIV} at (266,2) size 22x22
+layer at (277,270) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (305,270) size 16x16
+  RenderButton {BUTTON} at (297,5) size 16x16 [color=#FFFFFF]
 layer at (332,50) size 320x240
   RenderFlexibleBox {DIV} at (0,0) size 320x240
 layer at (332,265) size 320x25
   RenderFlexibleBox {DIV} at (0,215) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 216x15
-      RenderSlider {INPUT} at (45,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderButton {INPUT} at (297,4) size 16x16
-    RenderBlock {DIV} at (265,6) size 25x12
+layer at (338,269) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (364,270) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (381,272) size 217x11
+  RenderFlexibleBox {DIV} at (49,7) size 217x11
 layer at (381,272) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (552,272) size 45x11
-  RenderFlexibleBox {DIV} at (171,2) size 45x11 [color=#FFFFFF]
+layer at (553,272) size 45x11
+  RenderFlexibleBox {DIV} at (172,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:06"
-layer at (599,271) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (428,273) size 123x9
+  RenderFlexibleBox {DIV} at (47,1) size 123x9
+    RenderSlider {INPUT} at (0,0) size 123x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 123x9
+        RenderBlock {DIV} at (0,1) size 123x6
+layer at (428,274) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (598,267) size 22x22
+  RenderFlexibleBox {DIV} at (266,2) size 22x22
+layer at (601,270) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (629,270) size 16x16
+  RenderButton {BUTTON} at (297,5) size 16x16 [color=#FFFFFF]
index 39556a1..29ce91a 100644 (file)
Binary files a/LayoutTests/platform/mac/media/controls-without-preload-expected.png and b/LayoutTests/platform/mac/media/controls-without-preload-expected.png differ
index 6d8be5f..c8676cd 100644 (file)
@@ -14,24 +14,32 @@ layer at (8,42) size 320x240
   RenderFlexibleBox {DIV} at (0,0) size 320x240
 layer at (8,257) size 320x25
   RenderFlexibleBox {DIV} at (0,215) size 320x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderFlexibleBox {DIV} at (49,5) size 216x15
-      RenderSlider {INPUT} at (45,2) size 126x13
-        RenderFlexibleBox {DIV} at (0,0) size 126x13
-          RenderBlock {DIV} at (0,2) size 126x8
-            RenderBlock {DIV} at (0,0) size 10x8
-    RenderButton {INPUT} at (297,4) size 16x16
-    RenderBlock {DIV} at (265,6) size 25x12
+layer at (14,261) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,262) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,264) size 217x11
+  RenderFlexibleBox {DIV} at (49,7) size 217x11
 layer at (57,264) size 45x11
-  RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
+  RenderFlexibleBox {DIV} at (0,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
       RenderText {#text} at (0,0) size 26x11
         text run at (0,0) width 26: "00:00"
-layer at (228,264) size 45x11
-  RenderFlexibleBox {DIV} at (171,2) size 45x11 [color=#FFFFFF]
+layer at (229,264) size 45x11
+  RenderFlexibleBox {DIV} at (172,0) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (7,0) size 31x11
       RenderText {#text} at (0,0) size 31x11
         text run at (0,0) width 31: "-00:06"
-layer at (275,263) size 14x12
-  RenderButton zI: 1 {INPUT} at (2,0) size 14x12
+layer at (104,265) size 123x9
+  RenderFlexibleBox {DIV} at (47,1) size 123x9
+    RenderSlider {INPUT} at (0,0) size 123x9 [color=#909090] [bgcolor=#000000]
+      RenderFlexibleBox {DIV} at (0,0) size 123x9
+        RenderBlock {DIV} at (0,1) size 123x6
+layer at (104,266) size 6x6
+  RenderBlock {DIV} at (0,0) size 6x6 [bgcolor=#FFFFFF]
+layer at (274,259) size 22x22
+  RenderFlexibleBox {DIV} at (266,2) size 22x22
+layer at (277,262) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (305,262) size 16x16
+  RenderButton {BUTTON} at (297,5) size 16x16 [color=#FFFFFF]
index b848b10..777ebfd 100644 (file)
Binary files a/LayoutTests/platform/mac/media/media-controls-clone-expected.png and b/LayoutTests/platform/mac/media/media-controls-clone-expected.png differ
index e52c378..cb40a72 100644 (file)
@@ -15,27 +15,67 @@ layer at (8,8) size 300x150
   RenderFlexibleBox {DIV} at (0,0) size 300x150
 layer at (8,133) size 300x25
   RenderFlexibleBox {DIV} at (0,125) size 300x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (14,137) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,138) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,141) size 197x9
+  RenderFlexibleBox {DIV} at (49,8) size 197x9
+layer at (59,141) size 193x9
+  RenderFlexibleBox {DIV} at (2,0) size 193x9
+layer at (254,135) size 22x22
+  RenderFlexibleBox {DIV} at (246,2) size 22x22
+layer at (257,138) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (285,138) size 16x16
+  RenderButton {BUTTON} at (277,5) size 16x16 [color=#FFFFFF]
 layer at (308,133) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
 layer at (308,133) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (314,137) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (340,138) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (357,141) size 127x9
+  RenderFlexibleBox {DIV} at (49,8) size 127x9
+layer at (359,141) size 123x9
+  RenderFlexibleBox {DIV} at (2,0) size 123x9
+layer at (484,135) size 22x22
+  RenderFlexibleBox {DIV} at (176,2) size 22x22
+layer at (487,138) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
 layer at (8,162) size 300x150
   RenderFlexibleBox {DIV} at (0,0) size 300x150
 layer at (8,287) size 300x25
   RenderFlexibleBox {DIV} at (0,125) size 300x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (14,291) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (40,292) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (57,295) size 197x9
+  RenderFlexibleBox {DIV} at (49,8) size 197x9
+layer at (59,295) size 193x9
+  RenderFlexibleBox {DIV} at (2,0) size 193x9
+layer at (254,289) size 22x22
+  RenderFlexibleBox {DIV} at (246,2) size 22x22
+layer at (257,292) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
+layer at (285,292) size 16x16
+  RenderButton {BUTTON} at (277,5) size 16x16 [color=#FFFFFF]
 layer at (308,287) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
 layer at (308,287) size 200x25
   RenderFlexibleBox {DIV} at (0,0) size 200x25
-    RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (32,4) size 16x16
-    RenderBlock {DIV} at (49,12) size 0x0
+layer at (314,291) size 16x16
+  RenderButton {BUTTON} at (6,4) size 16x16 [color=#FFFFFF]
+layer at (340,292) size 16x16
+  RenderButton {BUTTON} at (32,5) size 16x16 [color=#FFFFFF]
+layer at (357,295) size 127x9
+  RenderFlexibleBox {DIV} at (49,8) size 127x9
+layer at (359,295) size 123x9
+  RenderFlexibleBox {DIV} at (2,0) size 123x9
+layer at (484,289) size 22x22
+  RenderFlexibleBox {DIV} at (176,2) size 22x22
+layer at (487,292) size 16x16
+  RenderButton {BUTTON} at (3,3) size 16x16 [color=#FFFFFF]
diff --git a/LayoutTests/platform/mac/webarchive/loading/video-in-webarchive-expected.txt b/LayoutTests/platform/mac/webarchive/loading/video-in-webarchive-expected.txt
new file mode 100644 (file)
index 0000000..118aade
--- /dev/null
@@ -0,0 +1,16 @@
+main frame - didStartProvisionalLoadForFrame
+main frame - didCommitLoadForFrame
+main frame - willPerformClientRedirectToURL: resources/video-in-webarchive.webarchive 
+main frame - didFinishDocumentLoadForFrame
+main frame - didFinishLoadForFrame
+main frame - didStartProvisionalLoadForFrame
+main frame - didCancelClientRedirectForFrame
+main frame - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame
+main frame - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didFailLoadWithError
+main frame "webkitfullscreenchange" - didFinishLoadForFrame
+frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame
+
index 695cbfc..cd6a490 100644 (file)
@@ -1,3 +1,14 @@
+2013-09-06  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2013-09-27  Andreas Kling  <akling@apple.com>
 
         Pass VM instead of ExecState to JSDateMath functions.
index 6546430..e91b1f6 100644 (file)
@@ -129,6 +129,7 @@ ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
 ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
 ENABLE_LINK_PREFETCH = ;
 ENABLE_MATHML = ENABLE_MATHML;
+ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
 ENABLE_MEDIA_SOURCE = ;
 ENABLE_MEDIA_STATISTICS = ;
 ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
@@ -187,4 +188,4 @@ ENABLE_XSLT = ENABLE_XSLT;
 
 ENABLE_FTL_JIT = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
index 348f99f..cf7d9bc 100644 (file)
@@ -1,3 +1,14 @@
+2013-09-06  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.
+
+        * wtf/FeatureDefines.h:
+
 2013-09-27  Gustavo Noronha Silva  <gns@gnome.org>
 
         [GCC] Fix build with gcc < 4.8.1, which does not have is_trivially_destructible
index cb915db..315388b 100644 (file)
 #define ENABLE_MEDIA_CAPTURE 0
 #endif
 
+#if !defined(ENABLE_MEDIA_CONTROLS_SCRIPT)
+#define ENABLE_MEDIA_CONTROLS_SCRIPT 0
+#endif
+
 #if !defined(ENABLE_MEDIA_SOURCE)
 #define ENABLE_MEDIA_SOURCE 0
 #endif
index 09a322d..f229f9b 100644 (file)
@@ -1,3 +1,178 @@
+2013-09-06  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Re-implement the existing MediaControls constellation of classes in JavaScript
+        and CSS. This will allow different ports to configure their controls without
+        dependencies on the layout requirements of any other port's controls.
+
+        Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT:
+        * Configurations/FeatureDefines.xcconfig:
+
+        Add new source files to the project:
+        * DerivedSources.cpp:
+        * DerivedSources.make:
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        Add a new class MediaControlsHost which the script controls can use to
+        communicate with the HTMLMediaElement without exposing private interfaces
+        to web facing scripts:
+        * Modules/mediacontrols/MediaControlsHost.cpp: Added.
+        (WebCore::MediaControlsHost::automaticKeyword): Static method.
+        (WebCore::MediaControlsHost::forcedOnlyKeyword): Ditto.
+        (WebCore::MediaControlsHost::alwaysOnKeyword): Ditto.
+        (WebCore::MediaControlsHost::create): Simple factory.
+        (WebCore::MediaControlsHost::MediaControlsHost): Simple constructor.
+        (WebCore::MediaControlsHost::~MediaControlsHost): Simple destructor.
+        (WebCore::MediaControlsHost::sortedTrackListForMenu): Pass through to CaptionUserPreferences.
+        (WebCore::MediaControlsHost::displayNameForTrack): Ditto.
+        (WebCore::MediaControlsHost::captionMenuOffItem): Pass through to TextTrack.
+        (WebCore::MediaControlsHost::captionMenuAutomaticItem): Ditto.
+        (WebCore::MediaControlsHost::captionDisplayMode): Pass through to CaptionUserPreferences.
+        (WebCore::MediaControlsHost::setSelectedTextTrack): Pass through to HTMLMediaElement.
+        (WebCore::MediaControlsHost::textTrackContainer): Lazily create a MediaControlTextTrackContainerElement.
+        (WebCore::MediaControlsHost::updateTextTrackContainer): Pass through to MediaControlTextTrackContainerElement.
+        * Modules/mediacontrols/MediaControlsHost.h: Added.
+        * Modules/mediacontrols/MediaControlsHost.idl: Added.
+        * Modules/mediacontrols/mediaControlsApple.css: Added.
+
+        Add convenience methods for adding a MediaControlsHost to a VM.
+        * bindings/js/ScriptObject.cpp:
+        (WebCore::ScriptGlobalObject::set):
+        * bindings/js/ScriptObject.h:
+
+        Add the new controller .js implementation:
+        * Modules/mediacontrols/mediaControlsApple.js: Added.
+        (createControls): Global method to create a new Controller object.
+        (Controller): Constructor. Create and configure the default set of controls.
+        (Controller.prototype.addListeners): Adds event listeners to the this.video object.
+        (Controller.prototype.removeListeners): Removes listeners from same.
+        (Controller.prototype.handleEvent): Makes Controller an EventHandler, making registration and
+                deregistration simpler.
+        (Controller.prototype.createBase): Creates the base controls object and the text track container.
+        (Controller.prototype.createControls): Creates the controls panel object and controller UI.
+        (Controller.prototype.setControlsType): Switches between Full Screen and Inline style of controller.
+        (Controller.prototype.disconnectControls): Disconnects all UI elements from the DOM.
+        (Controller.prototype.configureInlineControls): Configures existing controls for Inline mode.
+        (Controller.prototype.configureFullScreenControls): Ditto, for Full Screen Mode.
+
+        Add listeners for HTMLMediaElement events:
+        (Controller.prototype.onloadstart): Update the status display.
+        (Controller.prototype.onerror): Ditto.
+        (Controller.prototype.onabort): Ditto.
+        (Controller.prototype.onsuspend): Ditto.
+        (Controller.prototype.onprogress): Ditto.
+        (Controller.prototype.onstalled): Ditto.
+        (Controller.prototype.onwaiting): Ditto.
+        (Controller.prototype.onreadystatechange): Ditto.
+        (Controller.prototype.ontimeupdate): Update the timeline and time displays.
+        (Controller.prototype.ondurationchange): Ditto.
+        (Controller.prototype.onplaying): Update the play button.
+        (Controller.prototype.onplay): Ditto.
+        (Controller.prototype.onpause): Ditto.
+        (Controller.prototype.onratechange): Ditto.
+        (Controller.prototype.onvolumechange): Update the volume and mute UI.
+        (Controller.prototype.ontexttrackchange): Update the text track container and captions button.
+        (Controller.prototype.ontexttrackadd): Ditto.
+        (Controller.prototype.ontexttrackremove): Ditto.
+        (Controller.prototype.ontexttrackcuechange): Ditto.
+        (Controller.prototype.onfullscreenchange): Reconfigure the controls.
+
+        Add listeners for UI element events:
+        (Controller.prototype.onwrappermousemove): Show the controls and start the hide timer.
+        (Controller.prototype.onwrappermouseout): Hide the controls and stop the hide timer.
+        (Controller.prototype.onrewindbuttonclicked): Rewind.
+        (Controller.prototype.onplaybuttonclicked): Toggle pause.
+        (Controller.prototype.ontimelinechange): Update the currentTime.
+        (Controller.prototype.ontimelinedown):
+        (Controller.prototype.ontimelineup):
+        (Controller.prototype.ontimelinemouseover): Show the thumbnail view if available.
+        (Controller.prototype.ontimelinemouseout): Hide same.
+        (Controller.prototype.ontimelinemousemove): Move the thumbnail view.
+        (Controller.prototype.onmutebuttonclicked): Mute audio.
+        (Controller.prototype.onminbuttonclicked): Increase volume to max.
+        (Controller.prototype.onmaxbuttonclicked): Decrease volume to min.
+        (Controller.prototype.onvolumesliderchange): Update the current volume.
+        (Controller.prototype.oncaptionbuttonclicked): Show or hide the track menu.
+        (Controller.prototype.onfullscreenbuttonclicked): Enter or exit fullscreen.
+        (Controller.prototype.oncontrolschange): Show or hide the controls panel.
+        (Controller.prototype.onseekbackmousedown): Start seeking and enable the seek timer.
+        (Controller.prototype.onseekbackmouseup): Stop seeking and disable the seek timer.
+        (Controller.prototype.onseekforwardmousedown): Start seekind and enable the seek timer.
+        (Controller.prototype.onseekforwardmouseup): Stop seekind and disable the seek timer.
+
+        Add action methods (which are mostly self explanatory):
+        (Controller.prototype.updateDuration):
+        (Controller.prototype.updatePlaying):
+        (Controller.prototype.showControls): 
+        (Controller.prototype.hideControls):
+        (Controller.prototype.removeControls):
+        (Controller.prototype.addControls):
+        (Controller.prototype.updateTime):
+        (Controller.prototype.updateReadyState):
+        (Controller.prototype.setStatusHidden):        
+        (Controller.prototype.updateThumbnailTrack):
+        (Controller.prototype.updateCaptionButton):
+        (Controller.prototype.updateCaptionContainer):
+        (Controller.prototype.buildCaptionMenu):
+        (Controller.prototype.captionItemSelected):
+        (Controller.prototype.destroyCaptionMenu):
+        (Controller.prototype.updateVolume):
+
+        Add utility methods:
+        (Controller.prototype.isFullScreen):
+        (Controller.prototype.canPlay):
+        (Controller.prototype.nextRate):
+        (Controller.prototype.seekBackFaster):
+        (Controller.prototype.seekForwardFaster):
+        (Controller.prototype.formatTime):
+        (Controller.prototype.trackHasThumbnails):
+
+        Add the stylesheet for the javascript controls (which are mostly) copied from
+        the (deleted) mediaControlsQuickTime.css and fullscreenQuickTime.css files:
+        * Modules/mediacontrols/mediaControlsApple.css: Added.
+        * css/fullscreenQuickTime.css: Removed.
+        * css/mediaControlsQuickTime.css: Removed.
+
+        Inject new stylesheets into UA sheets:
+        * css/CSSDefaultStyleSheets.cpp:
+        (WebCore::CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement):
+
+        Use the new javascript controls rather than MediaControls:
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::childShouldCreateRenderer): Use the javascript controls if available.
+        (WebCore::HTMLMediaElement::updateTextTrackDisplay): Ditto.
+        (WebCore::HTMLMediaElement::mediaControls): Ditto.
+        (WebCore::HTMLMediaElement::hasMediaControls): Ditto.
+        (WebCore::HTMLMediaElement::createMediaControls): Ditto.
+        (WebCore::HTMLMediaElement::configureMediaControls): Ditto.
+        (WebCore::HTMLMediaElement::configureTextTrackDisplay): Ditto.
+        (WebCore::HTMLMediaElement::ensureIsolatedWorld): Create a new VM for the controls script.
+        (WebCore::HTMLMediaElement::ensureMediaControlsInjectedScript): Inject the media controls script into the VM.
+        (WebCore::HTMLMediaElement::didAddUserAgentShadowRoot): Inject the MediaControlsHost into the VM and call
+                the scripts global factory function.
+        * html/HTMLMediaElement.h:
+
+        Remove most of the drawing code from RenderThemeMac and RenderThemeWin and
+        add accessors for the new .js and .css file data:
+        * rendering/RenderTheme.h:
+        (WebCore::RenderTheme::mediaControlsStyleSheet): Empty virtual method.
+        (WebCore::RenderTheme::mediaControlsScript): Ditto.
+        * rendering/RenderThemeMac.h:
+        * rendering/RenderThemeMac.mm:
+        (WebCore::RenderThemeMac::mediaControlsStyleSheet): Add accessor for mediaControlsApple.css.
+        (WebCore::RenderThemeMac::mediaControlsScript): Add accessor for mediaControlsApple.js.
+        (WebCore::RenderThemeMac::adjustSliderThumbSize): Remove the call to adjustMediaSliderThumbSize.
+        * rendering/RenderThemeWin.cpp:
+        (WebCore::RenderThemeWin::mediaControlsStyleSheet):
+        (WebCore::RenderThemeWin::mediaControlsScript):
+        * rendering/RenderThemeWin.h:
+
 2013-09-27  Bem Jones-Bey  <bjonesbe@adobe.com>
 
         [css-shapes] Shapes are not resolved the same way in shape-inside and clip-path
index 6546430..e91b1f6 100644 (file)
@@ -129,6 +129,7 @@ ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
 ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
 ENABLE_LINK_PREFETCH = ;
 ENABLE_MATHML = ENABLE_MATHML;
+ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
 ENABLE_MEDIA_SOURCE = ;
 ENABLE_MEDIA_STATISTICS = ;
 ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
@@ -187,4 +188,4 @@ ENABLE_XSLT = ENABLE_XSLT;
 
 ENABLE_FTL_JIT = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
index 3ec9051..8804357 100644 (file)
 #include "JSKeyboardEvent.cpp"
 #include "JSLocation.cpp"
 #include "JSMediaController.cpp"
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+#include "JSMediaControlsHost.cpp"
+#endif
 #include "JSMediaError.cpp"
 #include "JSMediaList.cpp"
 #include "JSMediaQueryList.cpp"
index f4bf407..5336e90 100644 (file)
@@ -33,6 +33,7 @@ VPATH = \
     $(WebCore)/Modules/geolocation \
     $(WebCore)/Modules/indexeddb \
     $(WebCore)/Modules/indieui \
+    $(WebCore)/Modules/mediacontrols \
     $(WebCore)/Modules/mediasource \
     $(WebCore)/Modules/mediastream \
     $(WebCore)/Modules/notifications \
@@ -115,6 +116,7 @@ BINDING_IDLS = \
     $(WebCore)/Modules/indexeddb/IDBVersionChangeEvent.idl \
     $(WebCore)/Modules/indexeddb/WorkerGlobalScopeIndexedDatabase.idl \
     $(WebCore)/Modules/indieui/UIRequestEvent.idl \
+    $(WebCore)/Modules/mediacontrols/MediaControlsHost.idl \
        $(WebCore)/Modules/mediasource/MediaSource.idl \
        $(WebCore)/Modules/mediasource/SourceBuffer.idl \
        $(WebCore)/Modules/mediasource/SourceBufferList.idl \
@@ -700,6 +702,7 @@ all : \
     PlugInsResources.h \
     SVGElementFactory.cpp \
     SVGNames.cpp \
+    UserAgentScripts.h \
     UserAgentStyleSheets.h \
     WebKitFontFamilyNames.cpp \
     WebKitFontFamilyNames.h \
@@ -845,18 +848,35 @@ endif
 
 ifeq ($(findstring ENABLE_VIDEO,$(FEATURE_DEFINES)), ENABLE_VIDEO)
     USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/mediaControls.css
-    USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/mediaControlsQuickTime.css
 endif
 
 ifeq ($(findstring ENABLE_FULLSCREEN_API,$(FEATURE_DEFINES)), ENABLE_FULLSCREEN_API)
-    USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/fullscreen.css $(WebCore)/css/fullscreenQuickTime.css
+    USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/css/fullscreen.css
 endif
 
+# ifeq ($(findstring ENABLE_MEDIA_CONTROLS_SCRIPT,$(FEATURE_DEFINES)), ENABLE_MEDIA_CONTROLS_SCRIPT)
+       USER_AGENT_STYLE_SHEETS := $(USER_AGENT_STYLE_SHEETS) $(WebCore)/Modules/mediacontrols/mediaControlsApple.css
+# endif
+
 UserAgentStyleSheets.h : css/make-css-file-arrays.pl bindings/scripts/preprocessor.pm $(USER_AGENT_STYLE_SHEETS) $(PLATFORM_FEATURE_DEFINES)
        perl -I$(WebCore)/bindings/scripts $< --defines "$(FEATURE_DEFINES)" $@ UserAgentStyleSheetsData.cpp $(USER_AGENT_STYLE_SHEETS)
 
 # --------
 
+# user agent scripts
+
+USER_AGENT_SCRIPTS = 
+
+ifeq ($(findstring ENABLE_MEDIA_CONTROLS_SCRIPT,$(FEATURE_DEFINES)), ENABLE_MEDIA_CONTROLS_SCRIPT)
+       USER_AGENT_SCRIPTS := $(USER_AGENT_SCRIPTS) $(WebCore)/Modules/mediacontrols/mediaControlsApple.js
+endif
+
+
+UserAgentScripts.h : css/make-css-file-arrays.pl bindings/scripts/preprocessor.pm $(USER_AGENT_SCRIPTS) $(PLATFORM_FEATURE_DEFINES)
+       perl -I$(WebCore)/bindings/scripts $< --defines "$(FEATURE_DEFINES)" $@ UserAgentScriptsData.cpp $(USER_AGENT_SCRIPTS)
+
+# --------
+
 # plugIns resources
 
 PLUG_INS_RESOURCES = $(WebCore)/Resources/plugIns.js
diff --git a/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp b/Source/WebCore/Modules/mediacontrols/MediaControlsHost.cpp
new file mode 100644 (file)
index 0000000..ea29c51
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+
+#include "MediaControlsHost.h"
+
+#include "CaptionUserPreferences.h"
+#include "Element.h"
+#include "HTMLMediaElement.h"
+#include "MediaControlElements.h"
+#include "Page.h"
+#include "PageGroup.h"
+#include "TextTrack.h"
+#include "TextTrackList.h"
+
+namespace WebCore {
+
+const AtomicString& MediaControlsHost::automaticKeyword()
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, automatic, ("automatic", AtomicString::ConstructFromLiteral));
+    return automatic;
+}
+
+const AtomicString& MediaControlsHost::forcedOnlyKeyword()
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, forcedOn, ("forced-only", AtomicString::ConstructFromLiteral));
+    return forcedOn;
+}
+
+const AtomicString& MediaControlsHost::alwaysOnKeyword()
+{
+    DEFINE_STATIC_LOCAL(const AtomicString, alwaysOn, ("always-on", AtomicString::ConstructFromLiteral));
+    return alwaysOn;
+}
+
+PassRefPtr<MediaControlsHost> MediaControlsHost::create(HTMLMediaElement* mediaElement)
+{
+    return adoptRef(new MediaControlsHost(mediaElement));
+}
+
+MediaControlsHost::MediaControlsHost(HTMLMediaElement* mediaElement)
+    : m_mediaElement(mediaElement)
+{
+    ASSERT(mediaElement);
+}
+
+MediaControlsHost::~MediaControlsHost()
+{
+}
+
+Vector<RefPtr<TextTrack> > MediaControlsHost::sortedTrackListForMenu(TextTrackList* trackList)
+{
+    if (!trackList)
+        return Vector<RefPtr<TextTrack> >();
+
+    Page* page = m_mediaElement->document().page();
+    if (!page)
+        return Vector<RefPtr<TextTrack> >();
+
+    CaptionUserPreferences* captionPreferences = page->group().captionPreferences();
+    return captionPreferences->sortedTrackListForMenu(trackList);
+}
+
+String MediaControlsHost::displayNameForTrack(TextTrack* track)
+{
+    if (!track)
+        return emptyString();
+
+    Page* page = m_mediaElement->document().page();
+    if (!page)
+        return emptyString();
+
+    CaptionUserPreferences* captionPreferences = page->group().captionPreferences();
+    return captionPreferences->displayNameForTrack(track);
+}
+
+TextTrack* MediaControlsHost::captionMenuOffItem()
+{
+    return TextTrack::captionMenuOffItem();
+}
+
+TextTrack* MediaControlsHost::captionMenuAutomaticItem()
+{
+    return TextTrack::captionMenuAutomaticItem();
+}
+
+AtomicString MediaControlsHost::captionDisplayMode()
+{
+    Page* page = m_mediaElement->document().page();
+    if (!page)
+        return emptyAtom;
+
+    switch (page->group().captionPreferences()->captionDisplayMode()) {
+    case CaptionUserPreferences::Automatic:
+        return automaticKeyword();
+    case CaptionUserPreferences::ForcedOnly:
+        return forcedOnlyKeyword();
+    case CaptionUserPreferences::AlwaysOn:
+        return alwaysOnKeyword();
+    default:
+        ASSERT_NOT_REACHED();
+        return emptyAtom;
+    }
+}
+
+void MediaControlsHost::setSelectedTextTrack(TextTrack* track)
+{
+    m_mediaElement->setSelectedTextTrack(track);
+}
+
+Element* MediaControlsHost::textTrackContainer()
+{
+    if (!m_textTrackContainer) {
+        m_textTrackContainer = MediaControlTextTrackContainerElement::create(m_mediaElement->document());
+        m_textTrackContainer->setMediaController(m_mediaElement);
+    }
+    return m_textTrackContainer.get();
+}
+
+void MediaControlsHost::updateTextTrackContainer()
+{
+    if (m_textTrackContainer)
+        m_textTrackContainer->updateDisplay();
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h b/Source/WebCore/Modules/mediacontrols/MediaControlsHost.h
new file mode 100644 (file)
index 0000000..fca8bf6
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MediaControlsHost_h
+#define MediaControlsHost_h
+
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+
+#include "ScriptState.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class Element;
+class HTMLMediaElement;
+class MediaControlTextTrackContainerElement;
+class TextTrack;
+class TextTrackList;
+
+class MediaControlsHost : public RefCounted<MediaControlsHost> {
+public:
+    static PassRefPtr<MediaControlsHost> create(HTMLMediaElement*);
+    ~MediaControlsHost();
+
+    static const AtomicString& automaticKeyword();
+    static const AtomicString& forcedOnlyKeyword();
+    static const AtomicString& alwaysOnKeyword();
+
+    Vector<RefPtr<TextTrack> > sortedTrackListForMenu(TextTrackList*);
+    String displayNameForTrack(TextTrack*);
+    TextTrack* captionMenuOffItem();
+    TextTrack* captionMenuAutomaticItem();
+    AtomicString captionDisplayMode();
+    void setSelectedTextTrack(TextTrack*);
+    Element* textTrackContainer();
+    void updateTextTrackContainer();
+
+private:
+    MediaControlsHost(HTMLMediaElement*);
+
+    HTMLMediaElement* m_mediaElement;
+    RefPtr<MediaControlTextTrackContainerElement> m_textTrackContainer;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl b/Source/WebCore/Modules/mediacontrols/MediaControlsHost.idl
new file mode 100644 (file)
index 0000000..135a0d4
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+[
+    NoInterfaceObject,
+    Conditional=MEDIA_CONTROLS_SCRIPT,
+    ImplementationLacksVTable
+] interface MediaControlsHost {
+    TextTrack[] sortedTrackListForMenu(TextTrackList trackList);
+    DOMString displayNameForTrack(TextTrack track);
+    readonly attribute TextTrack captionMenuOffItem;
+    readonly attribute TextTrack captionMenuAutomaticItem;
+    readonly attribute DOMString captionDisplayMode;
+    void setSelectedTextTrack(TextTrack track);
+    readonly attribute HTMLElement textTrackContainer;
+    void updateTextTrackContainer();
+};
diff --git a/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css b/Source/WebCore/Modules/mediacontrols/mediaControlsApple.css
new file mode 100644 (file)
index 0000000..67efb75
--- /dev/null
@@ -0,0 +1,729 @@
+/*
+ * Copyright (C) 2013 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+audio {
+    width: 200px;
+    height: 25px;
+}
+
+body:-webkit-full-page-media {
+    background-color: rgb(38, 38, 38);
+}
+
+video:-webkit-full-page-media {
+    margin: auto;
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+
+video:-webkit-full-page-media::-webkit-media-controls-panel {
+    bottom: 0px;
+}
+
+::-webkit-media-controls {
+    width: inherit;
+    height: inherit;
+    position: relative;
+    display: -webkit-flex;
+    -webkit-align-items: stretch;
+    -webkit-justify-content: flex-end;
+    -webkit-flex-direction: column;
+}
+
+video::-webkit-media-text-track-container,
+audio::-webkit-media-text-track-container {
+    position: relative;
+    -webkit-flex: 1 1 auto;
+}
+
+video::-webkit-media-controls-panel,
+audio::-webkit-media-controls-panel {
+    box-sizing: border-box;
+    position: relative;
+    bottom: 0;
+    width: 100%;
+    padding-top: 1px;
+    height: 25px;
+    line-height: 25px;
+    -webkit-user-select: none;
+    background-color: transparent;
+    background-image: -webkit-linear-gradient(top,
+        rgba(0,  0,  0,  .92) 0,
+        rgba(0,  0,  0,  .92) 1px,
+        rgba(89, 89, 89, .92) 1px,
+        rgba(89, 89, 89, .92) 2px,
+        rgba(60, 60, 60, .92) 2px,
+        rgba(35, 35, 35, .92) 12px,
+        rgba(30, 30, 30, .92) 12px,
+        rgba(30, 30, 30, .92) 13px,
+        rgba(25, 25, 25, .92) 13px,
+        rgba(17, 17, 17, .92) 100%
+    );
+
+    display: -webkit-flex;
+    -webkit-flex-direction: row;
+    -webkit-align-items: center;
+    -webkit-user-select: none;
+
+    transition: opacity 0.25s linear;
+}
+
+video::-webkit-media-controls-panel {
+    cursor: none;
+    opacity: 0;
+}
+
+video::-webkit-media-controls-panel.show,
+video::-webkit-media-controls-panel.paused,
+video::-webkit-media-controls-panel:hover {
+    cursor: inherit;
+    opacity: 1;
+}
+
+video::-webkit-media-controls-panel button,
+audio::-webkit-media-controls-panel button {
+    -webkit-appearance: none;
+    display: block;
+    padding: 0;
+    border: 0;
+    height: 16px;
+    width: 16px;
+    background-color: transparent;
+    color: white;
+    background-origin: content-box;
+    background-repeat: no-repeat;
+    background-position: center;
+    -webkit-filter: drop-shadow(black 0 1px 1px);
+}
+
+video::-webkit-media-controls-panel button:active,
+audio::-webkit-media-controls-panel button:active {
+    -webkit-filter: drop-shadow(white 0 0 10px);
+}
+
+video::-webkit-media-controls-rewind-button,
+audio::-webkit-media-controls-rewind-button {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 17"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.44444" stop-color="rgb(216, 216, 216)"/><stop offset="0.44444" stop-color="rgb(208, 208, 208)"/><stop offset="0.55555" stop-color="rgb(208, 208, 208)"/><stop offset="0.55555" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="m 7.9131,2 0,-1.548 -2.586,2.155 0,-2.171 -2.582,2.208 2.582,2.175 0,-2.139 2.586,2.155 0,-1.276 c 3.138,0.129 5.491,2.681 5.543,5.838 l -1.031,0 0.016,0.215 1.015,0 c -0.06,3.19 -2.629,5.765 -5.819,5.833 l 0,-1.018 -0.214,0 0,1.021 c -3.21,-0.047 -5.801,-2.631 -5.862,-5.836 l 1.045,0 -0.016,-0.215 -1.045,0 c -0.052,-0.288 -0.318,-0.654 -0.766,-0.654 -0.538,0 -0.755,0.484 -0.755,0.75 0,4.146 3.331,7.506 7.476,7.506 4.146,0 7.506,-3.36 7.506,-7.506 0,-4.059 -3.066,-7.357 -7.093,-7.493" fill="url(#gradient)"/><path d="m 5.1729,11.0518 c -0.38,0 -0.668,-0.129 -0.945,-0.366 -0.083,-0.071 -0.186,-0.134 -0.338,-0.134 -0.277,0 -0.511,0.238 -0.511,0.521 0,0.154 0.083,0.301 0.179,0.383 0.394,0.346 0.911,0.563 1.601,0.563 1.077,0 1.739,-0.681 1.739,-1.608 l 0,-0.013 c 0,-0.911 -0.641,-1.265 -1.296,-1.376 l 0.945,-0.919 c 0.193,-0.19 0.317,-0.337 0.317,-0.604 0,-0.294 -0.228,-0.477 -0.538,-0.477 l -2.354,0 c -0.248,0 -0.455,0.21 -0.455,0.464 0,0.253 0.207,0.463 0.455,0.463 l 1.485,0 -0.939,0.961 c -0.166,0.169 -0.228,0.295 -0.228,0.444 0,0.25 0.207,0.463 0.455,0.463 l 0.166,0 c 0.594,0 0.945,0.222 0.945,0.624 l 0,0.012 c 0,0.367 -0.282,0.599 -0.683,0.599" fill="url(#gradient)"/><path d="m 10.354,9.5342 c 0,0.876 -0.379,1.525 -0.979,1.525 -0.599,0 -0.992,-0.655 -0.992,-1.539 l 0,-0.012 c 0,-0.884 0.388,-1.527 0.979,-1.527 0.592,0 0.992,0.663 0.992,1.539 l 0,0.014 z m -0.979,-2.512 c -1.197,0 -2.008,1.097 -2.008,2.498 l 0,0.014 c 0,1.401 0.792,2.484 1.995,2.484 1.205,0 2.01,-1.097 2.01,-2.498 l 0,-0.012 c 0,-1.402 -0.805,-2.486 -1.997,-2.486" fill="url(#gradient)"/></svg>');
+    width: 16px;
+    height: 18px;
+    margin-bottom: 1px;
+    margin-left: 6px;
+    margin-right: 4px;
+}
+
+video::-webkit-media-controls-play-button,
+audio::-webkit-media-controls-play-button {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 0,0 v 16 h 6 v -16 h -6 z" fill="url(#gradient)"/><path d="M 9,0 v 16 h 6 v -16 h -6 z" fill="url(#gradient)"/></svg>');
+    margin-left: 6px;
+    margin-right: 1px;
+}
+
+video::-webkit-media-controls-play-button.paused,
+audio::-webkit-media-controls-play-button.paused {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 0,0 15,7 0,15 z" fill="url(#gradient)"/></svg>');
+}
+
+video::-webkit-media-controls-panel .mute-box,
+audio::-webkit-media-controls-panel .mute-box {
+    width: 22px;
+    height: 22px;
+    margin-right: 2px;
+
+    position: relative;
+    display: -webkit-flex;
+    -webkit-flex-direction: column;
+    -webkit-justify-content: center;
+    -webkit-align-items: center;
+}
+
+video::-webkit-media-controls-mute-button,
+audio::-webkit-media-controls-mute-button,
+video::-webkit-media-controls-volume-max-button {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="m 0,9 0,-4 3,0 3,-3 0,10 -3,-3 -3,0 z" style="fill:url(#gradient) "/><path d="m 10.449,1.087 c 1.963,1.055 3.322,3.291 3.322,5.881 0,2.642 -1.402,4.913 -3.424,5.945" style="fill:none;stroke:url(#gradient);stroke-width:1.25;stroke-linecap:round;"/><path d="m 9.13,3.134 c 1.289,0.681 2.181,2.142 2.181,3.835 0,1.743001 -0.939,3.24 -2.285,3.897" style="fill:none;stroke:url(#gradient);stroke-width:1.25;stroke-linecap:round;"/><path d="M 7.794,5.175 C 8.403001,5.491 8.827001,6.167 8.827001,6.971 8.827001,7.818 8.356,8.537001 7.688,8.826" style="fill:none;stroke:url(#gradient);stroke-width:1.25;stroke-linecap:round;"/></svg>');
+    width: 14px;
+}
+
+video::-webkit-media-controls-panel .volume-box,
+audio::-webkit-media-controls-panel .volume-box {
+    position: absolute;
+    box-sizing: border-box;
+    height: 22px;
+    width: 114px;
+    bottom: 0;
+    left: 0;
+
+    -webkit-transform: rotate(-90deg);
+    -webkit-transform-origin: 11px 11px;
+
+    background-color: transparent;
+    background-image: -webkit-linear-gradient(
+        left,
+        rgba(17, 17, 17,  0.92),
+        rgba(42, 42, 42, 0.92)
+    );
+    border: 1px solid rgba(0, 0, 0, 0.95);
+    border-radius: 12px;
+
+    display: -webkit-flex;
+    -webkit-flex-direction: row;
+    -webkit-align-items: center;
+    -webkit-justify-content: flex-end;
+
+    opacity: 0;
+    display: none;
+}
+
+video::-webkit-media-controls-panel .mute-box:hover .volume-box,
+video::-webkit-media-controls-panel .volume-box:hover,
+video::-webkit-media-controls-panel .volume-box:active,
+audio::-webkit-media-controls-panel .mute-box:hover .volume-box,
+audio::-webkit-media-controls-panel .volume-box:hover,
+audio::-webkit-media-controls-panel .volume-box:active {
+    opacity: 1;
+    display: inherit;
+}
+
+audio::-webkit-media-controls-volume-slider,
+video::-webkit-media-controls-volume-slider {
+    -webkit-appearance: none;
+    box-sizing: border-box;
+    height: 10px;
+    width: 80px;
+    padding: 0;
+    margin-right: 6px;
+
+    border-radius: 5px;
+    background-color: transparent;
+    background-image: -webkit-linear-gradient(
+        top,
+        rgba(15, 15, 15, .85) 0,
+        rgba(23, 23, 23, .85) 50%,
+        rgba(15, 15, 15, .85) 100%
+    );
+    border: 1px solid rgba(0, 0, 0, 0.875);
+}
+
+video::-webkit-media-controls-volume-slider::-webkit-slider-thumb,
+audio::-webkit-media-controls-volume-slider::-webkit-slider-thumb {
+    -webkit-appearance: none;
+    width: 8px;
+    height: 8px;
+    border-radius: 4px;
+    background-color: transparent;
+
+    /* rotateZ() forces the layer into compositing mode.
+    Slider thumbs are small, so forcing a compositing layer is inexpensive,
+       and it keeps the slider from having to repaint while sliding. */
+    -webkit-transform: rotateZ(0);
+    background-image: -webkit-linear-gradient(
+        left,
+        rgba(99, 99, 99, 1),
+        rgba(144, 144, 144, 1)
+    );
+    box-shadow: inset -1px 0 0 rgba(255, 255, 255, .5), 0 1px rgba(255, 255, 255, .14);
+}
+video::-webkit-media-controls-volume-slider::-webkit-slider-thumb::-webkit-slider-thumb:active,
+video::-webkit-media-controls-volume-slider::-webkit-slider-thumb:active::-webkit-slider-thumb,
+audio::-webkit-media-controls-volume-slider::-webkit-slider-thumb::-webkit-slider-thumb:active,
+audio::-webkit-media-controls-volume-slider::-webkit-slider-thumb:active::-webkit-slider-thumb {
+    background-image: -webkit-linear-gradient(
+        right top,
+        rgba(160, 160, 160, 1),
+        rgba(221, 221, 221, 1)
+    );
+}
+
+video::-webkit-media-controls-mute-button.muted,
+audio::-webkit-media-controls-mute-button.muted,
+video::-webkit-media-controls-volume-min-button {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="m 0,9 0,-4 3,0 3,-3 0,10 -3,-3 -3,0 z" fill="url(#gradient)"/></svg>');
+}
+
+video::-webkit-media-controls-toggle-closed-captions-button,
+audio::-webkit-media-controls-toggle-closed-captions-button {
+    width: 16px;
+    height: 16px;
+    margin: 0 7px;
+
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 102 105"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.46875" stop-color="rgb(216, 216, 216)"/><stop offset="0.46875" stop-color="rgb(208, 208, 208)"/><stop offset="0.53125" stop-color="rgb(208, 208, 208)"/><stop offset="0.53125" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M98.766,43.224c0-23.163-21.775-41.94-48.637-41.94c-26.859,0-48.635,18.777-48.635,41.94c0,18.266,13.546,33.796,32.444,39.549c1.131,8.356,26.037,24.255,22.864,19.921c-4.462-6.096-5.159-13.183-5.07-17.566C77.85,84.397,98.766,65.923,98.766,43.224z" fill="url(#gradient)"/></svg>');
+}
+
+video::-webkit-media-controls-closed-captions-container,
+audio::-webkit-media-controls-closed-captions-container {
+    -webkit-appearance: media-closed-captions-container;
+    position: absolute;
+    display: block;
+    right: 38px;
+    bottom: 29px;
+    max-width: calc(100% - 48px); /* right + 10px */
+    max-height: calc(100% - 39px); /* bottom + 10px */
+    overflow-x: hidden;
+    overflow-y: scroll;
+    background-color: rgba(0, 0, 0, 0.85);
+    border: 3px solid rgba(128, 128, 128, 0.75);
+    border-radius: 10px;
+    cursor: default;
+    z-index: 2;
+    text-align: initial;
+}
+
+video::-webkit-media-controls-closed-captions-container .list,
+audio::-webkit-media-controls-closed-captions-container .list {
+    display: block;
+    font-family: "Helvetica Bold", Helvetica;
+    font-size: 10pt;
+    -webkit-user-select: none;
+}
+
+video::-webkit-media-controls-closed-captions-container h3,
+audio::-webkit-media-controls-closed-captions-container h3 {
+    margin: 0;
+    color: rgb(117, 117, 117);
+    text-shadow: 0 1px 0 black;
+    -webkit-margin-start: 23px;
+    padding-top: 4px;
+    font-weight: bold;
+    font-size: 10pt;
+}
+
+video::-webkit-media-controls-closed-captions-container ul,
+audio::-webkit-media-controls-closed-captions-container ul {
+    list-style-type: none;
+    margin: 0 0 4px 0;
+    padding: 0;
+    font-weight: bold;
+}
+
+video::-webkit-media-controls-closed-captions-container li,
+audio::-webkit-media-controls-closed-captions-container li {
+    position: relative;
+    color: white;
+    background-image: none;
+    text-shadow: 0 1px 0 black;
+    margin: 0;
+    padding-left: 37px;
+    padding-right: 35px;
+    padding-top: 0.15em;
+    padding-bottom: 0.2em;
+    box-sizing: border-box;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    border-top: 1px solid transparent;
+    border-bottom: 1px solid transparent;
+}
+
+video::-webkit-media-controls-closed-captions-container li:hover,
+audio::-webkit-media-controls-closed-captions-container li:hover {
+    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgb(79, 112, 246)), color-stop(1, rgb(26, 68, 243)));
+    border-top: 1px solid rgb(70, 103, 234);
+    border-bottom: 1px solid rgb(3, 54, 229);
+}
+
+video::-webkit-media-controls-closed-captions-container li.selected::before,
+audio::-webkit-media-controls-closed-captions-container li.selected::before {
+    display: block;
+    content: "";
+    position: absolute;
+    top: 0.25em;
+    width: 1.1em;
+    height: 1.1em;
+    -webkit-margin-start: -20px;
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="rgb(163, 163, 163)" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>');
+    background-repeat: no-repeat;
+}
+
+video::-webkit-media-controls-closed-captions-container li.selected:hover::before,
+audio::-webkit-media-controls-closed-captions-container li.selected:hover::before {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="white" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>');
+}
+
+video::-webkit-media-controls-fullscreen-button,
+audio::-webkit-media-controls-fullscreen-button {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15" transform="rotate(90,0,0)"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 14,1 m 0,6 -2,-2 -2,2 c 0,0 -1,1 -2,0 -1,-1 0,-2 0,-2 l 2,-2 -2,-2 6,0 z" style="fill:url(#gradient) "/><path d="M 1,14 m 0,-6 2,2 2,-2 c 0,0 1,-1 2,0 1,1 0,2 0,2 l -2,2 2,2 -6,0 z" style="fill:url(#gradient) "/></svg>');
+    margin: 0 7px;
+}
+video::-webkit-media-controls-fullscreen-button.exit,
+audio::-webkit-media-controls-fullscreen-button.exit {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15" transform="rotate(90,0,0)"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 7,8 m 0,6 -2,-2 -2,2 c 0,0 -1,1 -2,0 -1,-1 0,-2 0,-2 l 2,-2 -2,-2 6,0 z" style="fill:url(#gradient) "/><path d="M 8,7 m 0,-6 2,2 2,-2 c 0,0 1,-1 2,0 1,1 0,2 0,2 l -2,2 2,2 -6,0 z" style="fill:url(#gradient) "/></svg>');
+}
+video::-webkit-media-controls-status-display,
+audio::-webkit-media-controls-status-display {
+    cursor: default;
+    font: -webkit-small-control;
+    font-size: 9px;
+    overflow: hidden;
+    color: white;
+    text-shadow: black 0px 1px 1px;
+
+    letter-spacing: normal;
+    word-spacing: normal;
+    line-height: 25px;
+    text-transform: none;
+    text-indent: 0;
+    text-decoration: none;
+    text-align: center;
+
+    -webkit-box-flex: 1;
+}
+video::-webkit-media-controls-timeline,
+audio::-webkit-media-controls-timeline {
+    -webkit-appearance: none;
+    -webkit-flex: 1 1 0;
+    height: 9px;
+    margin: 0;
+
+    border-radius: 4.5px;
+    background-color: black;
+    background-image: -webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, rgba(7,  7,  7,  0.3)),
+        color-stop(1, rgba(37, 37, 37, 0.629))
+    );
+    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .68), 0 1px rgba(255, 255, 255, .08);
+}
+video::-webkit-media-controls-timeline::-webkit-slider-thumb,
+audio::-webkit-media-controls-timeline::-webkit-slider-thumb {
+    -webkit-appearance: none;
+    width:6px;
+    height: 6px;
+    background-color: white;
+
+    /* rotateZ() forces the layer into compositing mode.
+    Slider thumbs are small, so forcing a compositing layer is inexpensive,
+       and it keeps the slider from having to repaint while sliding. */
+    -webkit-transform: translateY(1px) rotateZ(-45deg);
+
+    background-image: -webkit-gradient(
+        linear,
+        left bottom,
+        right top,
+        color-stop(0, rgba(99,  99,  99,  1)),
+        color-stop(1, rgba(144, 144, 144, 1))
+    );
+}
+video::-webkit-media-controls-timeline::-webkit-slider-thumb:active,
+video::-webkit-media-controls-timeline:active::-webkit-slider-thumb,
+audio::-webkit-media-controls-timeline::-webkit-slider-thumb:active,
+audio::-webkit-media-controls-timeline:active::-webkit-slider-thumb,
+ {
+    background-image: -webkit-gradient(
+        linear,
+        left bottom,
+        right top,
+        color-stop(0, rgba(160, 160, 160, 1)),
+        color-stop(1, rgba(221, 221, 221, 1))
+    );
+}
+video::-webkit-media-controls-current-time-display,
+video::-webkit-media-controls-time-remaining-display,
+audio::-webkit-media-controls-current-time-display,
+audio::-webkit-media-controls-time-remaining-display {
+    -webkit-user-select: none;
+    -webkit-flex: 0 0 0;
+    display: -webkit-flex;
+    -webkit-justify-content: center;
+    -webkit-align-items: center;
+    cursor: default;
+    font: -webkit-small-control;
+    font-size: 9px;
+    overflow-y: hidden;
+    overflow-x: hidden;
+    width: 45px;
+    min-width: 45px;
+    color: white;
+    text-shadow: black 0px 1px 1px;
+    letter-spacing: normal;
+    word-spacing: normal;
+    line-height: normal;
+    text-transform: none;
+    text-indent: 0px;
+    text-decoration: none;
+}
+
+video::-webkit-media-controls-timeline-container,
+audio::-webkit-media-controls-timeline-container {
+    display: -webkit-flex;
+    -webkit-flex-direction: row;
+    -webkit-align-items: center;
+    -webkit-user-select: none;
+    -webkit-flex: 1 1 0;
+    position: relative;
+    padding: 0;
+}
+
+video::-webkit-media-controls-panel .thumbnail-track,
+audio::-webkit-media-controls-panel .thumbnail-track {
+    position: relative;
+    -webkit-flex: 1 1 0;
+    height: 9px;
+    margin: 0 2px;
+    display: -webkit-flex;
+    -webkit-align-items: stretch;
+    -webkit-flex-direction: column;
+}
+
+video::-webkit-media-controls-panel .thumbnail,
+audio::-webkit-media-controls-panel .thumbnail {
+    position: absolute;
+    opacity: 0;
+    transition: opacity 0.25s linear;
+    bottom: 15px;
+    width: 100px;
+    height: 58px;
+    margin-left: -50px;
+    border: 5px solid black;
+    box-shadow: 0 0 3px white;
+    border-radius: 3px;
+}
+
+video::-webkit-media-controls-panel .thumbnail-image,
+audio::-webkit-media-controls-panel .thumbnail-image {
+    width: 100%;
+    height: 100%;
+}
+
+video::-webkit-media-controls-panel .thumbnail.show,
+audio::-webkit-media-controls-panel .thumbnail.show {
+    opacity: 1;
+}
+
+video::-webkit-media-controls-panel .hidden,
+audio::-webkit-media-controls-panel .hidden {
+    display: none;
+}
+
+/* Full Screen */
+
+/* 
+    Page stylesheets are not allowed to override the style of media
+    controls while in full screen mode, so many if not all the rules
+    defined in this section will be marked as !important to enforce
+    this restriction 
+*/
+
+video:-webkit-full-screen::-webkit-media-controls-panel {
+    -webkit-align-items: flex-start !important;
+    -webkit-justify-content: flex-end !important;
+
+    width: 440px !important;
+    height: 60px !important;
+    margin: 0 auto 50px auto !important;
+    padding-top: 10px !important;
+
+    background: -webkit-linear-gradient(top,
+        rgba(45, 45, 45, .97) 0,
+        rgba(30, 30, 30, .97) 19px,
+        rgba(25, 25, 25, .97) 19px,
+        rgba(25, 25, 25, .97) 20px,
+        rgba(19, 19, 19, .97) 20px,
+        rgba(12, 12, 12, .97) 100%
+    ) !important;
+
+    box-shadow: 
+        inset 0 -1px 1px rgba(0, 0, 0, 0.5),
+        inset 0  1px 0 0px   rgba(255, 255, 255, 0.15),
+        inset 0 -1px 0 0px   rgba(202, 202, 202, 0.09),
+        0  0   0 1px rgba(0, 0, 0, 0.5);
+    border-radius: 8px !important;
+
+    transition: opacity 0.3s linear !important;
+}
+
+video:-webkit-animating-full-screen-transition::-webkit-media-controls-panel {
+    opacity: 0 ! important;
+    transition: opacity 0 ! important;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-panel .volume-box {
+    -webkit-transform: none;
+    opacity: 1;
+    left: 11px;
+    top: 13px;
+    width: 90px;
+    height: 14px;
+    display: -webkit-flex;
+    -webkit-flex-direction: row;
+    -webkit-align-items: center;
+    background-image: none;
+    border: none;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-volume-slider {
+    height: 6px;
+    border-radius: 3px;
+    background-image: -webkit-linear-gradient(top,
+        rgba(16, 16, 16, .300) 0,
+        rgba(9,  9,  9,  .629) 100%
+    );
+    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .68), 0 1px rgba(255, 255, 255, .08);
+}
+
+video:-webkit-full-screen::-webkit-media-controls-volume-slider::-webkit-slider-thumb {
+    width: 10px;
+    height: 10px;
+    border-radius: 5px;
+
+    /* rotateZ() forces the layer into compositing mode.
+    Slider thumbs are small, so forcing a compositing layer is inexpensive,
+       and it keeps the slider from having to repaint while sliding. */
+    -webkit-transform: rotateZ(270deg);
+}
+
+video:-webkit-full-screen::-webkit-media-controls-play-button {
+    position: absolute;
+    
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 22"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.478" stop-color="rgb(216, 216, 216)"/><stop offset="0.478" stop-color="rgb(208, 208, 208)"/><stop offset="0.522" stop-color="rgb(208, 208, 208)"/><stop offset="0.522" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 0,0 0,22 8,22 8,0 z" fill="url(#gradient)"/><path d="M 13,0 13,22 21,22 21,0 z" fill="url(#gradient)"/></svg>');
+
+    width: 22px;
+    height: 23px;
+    left: 209px;
+    top: 9px;
+    margin: 0;
+    padding: 0;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-play-button.paused {
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21 22"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.478" stop-color="rgb(216, 216, 216)"/><stop offset="0.478" stop-color="rgb(208, 208, 208)"/><stop offset="0.522" stop-color="rgb(208, 208, 208)"/><stop offset="0.522" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 0,0 21,11 0,22 z" fill="url(#gradient)"/></svg>');
+}
+
+video:-webkit-full-screen::-webkit-media-controls-rewind-button {
+    position: absolute;
+    left: 162px;
+    top: 13px;
+    width: 18px;
+    height: 18px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-seek-back-button {
+    position: absolute;
+
+
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 22,0 11,7 22,15 z" fill="url(#gradient)"/><path d="M 11,0 0,7 11,15 z" fill="url(#gradient)"/></svg>');
+
+    width: 23px;
+    height: 16px;
+    left: 156px;
+    top: 13px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-return-to-realtime-button {
+    position: absolute;
+    display: -webkit-flex;
+    width: 29px;
+    height: 16px;
+    left: 262px;
+    top: 13px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-seek-forward-button {
+    position: absolute;
+
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 15"><linearGradient id="gradient" x2="0" y2="100%" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(216, 216, 216)"/><stop offset="0.4375" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(208, 208, 208)"/><stop offset="0.5" stop-color="rgb(200, 200, 200)"/><stop offset="1" stop-color="rgb(208, 208, 208)"/></linearGradient><path d="M 0,0 11,7 0,15 z" fill="url(#gradient)"/><path d="M 11,0 22,7 11,15 z" fill="url(#gradient)"/></svg>');
+
+    width: 23px;
+    height: 16px;
+    left: 256px;
+    top: 13px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-timeline-container {
+    height: auto;
+    width: 420px;
+    position: absolute;
+    bottom: 9px;
+    left: 8px;
+    right: 8px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-status-display {
+    width: 420px;
+    position: absolute;
+    bottom: 9px;
+    left: 8px;
+    right: 8px;
+}
+
+video:-webkit-full-screen::-webkit-media-controls-closed-captions-container {
+    bottom: 114px;
+    right: calc(50% - 183px); /* 183px is 221px (half the media controller's width) minus 38px (the right position of the captions icon). */
+    max-width: calc(50% + 173px); /* right + 10px */
+    max-height: calc(100% - 124px); /* bottom + 10px */
+}
+
+video::-webkit-media-text-track-container {
+    position: relative;
+    width: 100%;
+    overflow: hidden;
+    padding-bottom: 5px;
+
+    text-align: center;
+    color: rgba(255, 255, 255, 1);
+
+    letter-spacing: normal;
+    word-spacing: normal;
+    text-transform: none;
+    text-indent: 0;
+    text-decoration: none;
+    pointer-events: none;
+    -webkit-user-select: none;
+    word-break: break-word;
+
+    -webkit-flex: 1 1;
+
+    -webkit-line-box-contain: block inline-box replaced;
+}
+
+video::cue {
+    background-color: rgba(0, 0, 0, 0.8);
+}
+
+video::-webkit-media-text-track-display {
+    position: absolute;
+    overflow: hidden;
+    white-space: pre-wrap;
+    -webkit-box-sizing: border-box;
+    font: 22px sans-serif;
+}
+
+video::cue(:future) {
+    color: gray;
+}
+
+video::-webkit-media-text-track-container b {
+    font-weight: bold;
+}
+
+video::-webkit-media-text-track-container u {
+    text-decoration: underline;
+}
+
+video::-webkit-media-text-track-container i {
+    font-style: italic;
+}
diff --git a/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js b/Source/WebCore/Modules/mediacontrols/mediaControlsApple.js
new file mode 100644 (file)
index 0000000..cc30400
--- /dev/null
@@ -0,0 +1,933 @@
+function createControls(root, video, host)
+{
+    return new Controller(root, video, host);
+};
+
+function Controller(root, video, host)
+{
+    this.video = video;
+    this.root = root;
+    this.host = host;
+    this.controls = {};
+    this.listeners = {};
+
+    this.addVideoListeners();
+    this.createBase();
+    this.createControls();
+    this.setControlsType(this.isFullScreen() ? Controller.FullScreenControls : Controller.InlineControls);
+
+    this.updateBase();
+    this.updateDuration();
+    this.updateTime();
+    this.updateReadyState();
+    this.updatePlaying();
+    this.updateThumbnail();
+    this.updateCaptionButton();
+    this.updateCaptionContainer();
+    this.updateVolume();
+};
+
+/* Enums */
+Controller.InlineControls = 0;
+Controller.FullScreenControls = 1;
+
+Controller.PlayAfterSeeking = 0;
+Controller.PauseAfterSeeking = 1;
+
+Controller.prototype = {
+
+    /* Constants */
+    HandledVideoEvents: {
+        loadstart: 'handleLoadStart',
+        error: 'handleError',
+        abort: 'handleAbort',
+        suspend: 'handleSuspend',
+        stalled: 'handleStalled',
+        waiting: 'handleWaiting',
+        emptied: 'handleReadyStateChange',
+        loadedmetadata: 'handleReadyStateChange',
+        loadeddata: 'handleReadyStateChange',
+        canplay: 'handleReadyStateChange',
+        canplaythrough: 'handleReadyStateChange',
+        timeupdate: 'handleTimeUpdate',
+        durationchange: 'handleDurationChange',
+        play: 'handlePlay',
+        pause: 'handlePause',
+        volumechange: 'handleVolumeChange',
+        webkitfullscreenchange: 'handleFullscreenChange',
+    },
+    HideContrtolsDelay: 4 * 1000,
+    RewindAmount: 30,
+    MaximumSeekRate: 8,
+    SeekDelay: 1500,
+    ClassNames: {
+        exit: 'exit',
+        hidden: 'hidden',
+        list: 'list',
+        muteBox: 'mute-box',
+        muted: 'muted',
+        paused: 'paused',
+        playing: 'playing',
+        selected: 'selected',
+        show: 'show',
+        thumbnail: 'thumbnail',
+        thumbnailImage: 'thumbnail-image',
+        thumbnailTrack: 'thumbnail-track',
+        volumeBox: 'volume-box',
+    },
+
+    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 (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);
+
+        /* controls attribute */
+        this.controlsObserver = new MutationObserver(this.handleControlsChange.bind(this));
+        this.controlsObserver.observe(this.video, { attributes: true, attributeFilter: ['controls'] });
+    },
+
+    removeVideoListeners: function()
+    {
+        for (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);
+
+        /* controls attribute */
+        this.controlsObserver.disconnect();
+        delete(this.controlsObserver);
+    },
+
+    handleEvent: function(event)
+    {
+        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);
+            } else {
+                if (!(this.listeners[event.type] instanceof Array))
+                    return;
+
+                this.listeners[event.type].forEach(function(entry) {
+                    if (entry.element === event.currentTarget && entry.handler instanceof Function)
+                        entry.handler.call(this, event);
+                }, this);
+            }
+        } catch(e) {
+            if (window.console)
+                console.error(e);
+        }
+    },
+
+    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);
+    },
+
+    shouldHaveControls: function()
+    {
+        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()
+    {
+        var panel = this.controls.panel = document.createElement('div');
+        panel.setAttribute('pseudo', '-webkit-media-controls-panel');
+        this.listenFor(panel, 'mousedown', this.handlePanelMouseDown);
+        this.listenFor(panel, 'transitionend', this.handlePanelTransitionEnd);
+        this.listenFor(panel, 'click', this.handlePanelClick);
+        this.listenFor(panel, 'dblclick', this.handlePanelClick);
+
+        var rewindButton = this.controls.rewindButton = document.createElement('button');
+        rewindButton.setAttribute('pseudo', '-webkit-media-controls-rewind-button');
+        this.listenFor(rewindButton, 'click', this.handleRewindButtonClicked);
+
+        var seekBackButton = this.controls.seekBackButton = document.createElement('button');
+        seekBackButton.setAttribute('pseudo', '-webkit-media-controls-seek-back-button');
+        this.listenFor(seekBackButton, 'mousedown', this.handleSeekBackMouseDown);
+        this.listenFor(seekBackButton, 'mouseup', this.handleSeekBackMouseUp);
+
+        var seekForwardButton = this.controls.seekForwardButton = document.createElement('button');
+        seekForwardButton.setAttribute('pseudo', '-webkit-media-controls-seek-forward-button');
+        this.listenFor(seekForwardButton, 'mousedown', this.handleSeekForwardMouseDown);
+        this.listenFor(seekForwardButton, 'mouseup', this.handleSeekForwardMouseUp);
+
+        var playButton = this.controls.playButton = document.createElement('button');
+        playButton.setAttribute('pseudo', '-webkit-media-controls-play-button');
+        this.listenFor(playButton, 'click', this.handlePlayButtonClicked);
+
+        var statusDisplay = this.controls.statusDisplay = document.createElement('div');
+        statusDisplay.setAttribute('pseudo', '-webkit-media-controls-status-display');
+        statusDisplay.classList.add(this.ClassNames.hidden);
+
+        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');
+
+        var timeline = this.controls.timeline = document.createElement('input');
+        timeline.setAttribute('pseudo', '-webkit-media-controls-timeline');
+        timeline.type = 'range';
+        this.listenFor(timeline, 'change', this.handleTimelineChange);
+        this.listenFor(timeline, 'mouseover', this.handleTimelineMouseOver);
+        this.listenFor(timeline, 'mouseout', this.handleTimelineMouseOut);
+        this.listenFor(timeline, 'mousemove', this.handleTimelineMouseMove);
+        timeline.step = .01;
+
+        var thumbnailTrack = this.controls.thumbnailTrack = document.createElement('div');
+        thumbnailTrack.classList.add(this.ClassNames.thumbnailTrack);
+
+        var thumbnail = this.controls.thumbnail = document.createElement('div');
+        thumbnail.classList.add(this.ClassNames.thumbnail);
+
+        var thumbnailImage = this.controls.thumbnailImage = document.createElement('img');
+        thumbnailImage.classList.add(this.ClassNames.thumbnailImage);
+
+        var remainingTime = this.controls.remainingTime = document.createElement('div');
+        remainingTime.setAttribute('pseudo', '-webkit-media-controls-time-remaining-display');
+
+        var muteBox = this.controls.muteBox = document.createElement('div');
+        muteBox.classList.add(this.ClassNames.muteBox);
+
+        var muteButton = this.controls.muteButton = document.createElement('button');
+        muteButton.setAttribute('pseudo', '-webkit-media-controls-mute-button');
+        this.listenFor(muteButton, 'click', this.handleMuteButtonClicked);
+
+        var minButton = this.controls.minButton = document.createElement('button');
+        minButton.setAttribute('pseudo', '-webkit-media-controls-volume-min-button');
+        this.listenFor(minButton, 'click', this.handleMinButtonClicked);
+
+        var maxButton = this.controls.maxButton = document.createElement('button');
+        maxButton.setAttribute('pseudo', '-webkit-media-controls-volume-max-button');
+        this.listenFor(maxButton, 'click', this.handleMaxButtonClicked);
+
+        var volumeBox = this.controls.volumeBox = document.createElement('div');
+        volumeBox.classList.add(this.ClassNames.volumeBox);
+
+        var volume = this.controls.volume = document.createElement('input');
+        volume.setAttribute('pseudo', '-webkit-media-controls-volume-slider');
+        volume.type = 'range';
+        volume.min = 0;
+        volume.max = 1;
+        volume.step = .01;
+        this.listenFor(volume, 'change', this.handleVolumeSliderChange);
+
+        var captionButton = this.controls.captionButton = document.createElement('button');
+        captionButton.setAttribute('pseudo', '-webkit-media-controls-toggle-closed-captions-button');
+        this.listenFor(captionButton, 'click', this.handleCaptionButtonClicked);
+
+        var fullscreenButton = this.controls.fullscreenButton = document.createElement('button');
+        fullscreenButton.setAttribute('pseudo', '-webkit-media-controls-fullscreen-button');
+        this.listenFor(fullscreenButton, 'click', this.handleFullscreenButtonClicked);
+    },
+
+    setControlsType: function(type)
+    {
+        if (type === this.controlsType)
+            return;
+
+        this.disconnectControls();
+
+        if (type === Controller.InlineControls)
+            this.configureInlineControls();
+        else
+            this.configureFullScreenControls();
+
+        if (this.shouldHaveControls())
+            this.addControls();
+    },
+
+    disconnectControls: function(event)
+    {
+        for (item in this.controls) {
+            var control = this.controls[item];
+            if (control && control.parentNode)
+                control.parentNode.removeChild(control);
+       }
+    },
+
+    configureInlineControls: function()
+    {
+        this.controls.panel.appendChild(this.controls.rewindButton);
+        this.controls.panel.appendChild(this.controls.playButton);
+        this.controls.panel.appendChild(this.controls.statusDisplay);
+        this.controls.panel.appendChild(this.controls.timelineBox);
+        this.controls.timelineBox.appendChild(this.controls.currentTime);
+        this.controls.timelineBox.appendChild(this.controls.thumbnailTrack);
+        this.controls.thumbnailTrack.appendChild(this.controls.timeline);
+        this.controls.thumbnailTrack.appendChild(this.controls.thumbnail);
+        this.controls.thumbnail.appendChild(this.controls.thumbnailImage);
+        this.controls.timelineBox.appendChild(this.controls.remainingTime);
+        this.controls.panel.appendChild(this.controls.muteBox);
+        this.controls.muteBox.appendChild(this.controls.volumeBox);
+        this.controls.volumeBox.appendChild(this.controls.volume);
+        this.controls.muteBox.appendChild(this.controls.muteButton);
+        this.controls.panel.appendChild(this.controls.captionButton);
+        if (!this.isAudio())
+            this.controls.panel.appendChild(this.controls.fullscreenButton);
+
+        this.controls.panel.style.removeProperty('left');
+        this.controls.panel.style.removeProperty('top');
+        this.controls.panel.style.removeProperty('bottom');
+    },
+
+    configureFullScreenControls: function()
+    {
+        this.controls.panel.appendChild(this.controls.volumeBox);
+        this.controls.volumeBox.appendChild(this.controls.minButton);
+        this.controls.volumeBox.appendChild(this.controls.volume);
+        this.controls.volumeBox.appendChild(this.controls.maxButton);
+        this.controls.panel.appendChild(this.controls.seekBackButton);
+        this.controls.panel.appendChild(this.controls.playButton);
+        this.controls.panel.appendChild(this.controls.seekForwardButton);
+        this.controls.panel.appendChild(this.controls.captionButton);
+        if (!this.isAudio())
+            this.controls.panel.appendChild(this.controls.fullscreenButton);
+        this.controls.panel.appendChild(this.controls.timelineBox);
+        this.controls.timelineBox.appendChild(this.controls.currentTime);
+        this.controls.timelineBox.appendChild(this.controls.thumbnailTrack);
+        this.controls.thumbnailTrack.appendChild(this.controls.timeline);
+        this.controls.thumbnailTrack.appendChild(this.controls.thumbnail);
+        this.controls.thumbnail.appendChild(this.controls.thumbnailImage);
+        this.controls.timelineBox.appendChild(this.controls.remainingTime);
+    },
+
+    handleLoadStart: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Loading';
+    },
+
+    handleError: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Error';
+    },
+
+    handleAbort: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Aborted';
+    },
+
+    handleSuspend: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Suspended';
+    },
+
+    handleStalled: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Stalled';
+    },
+
+    handleWaiting: function(event)
+    {
+        // FIXME: Needs localization <http://webkit.org/b/120956>
+        this.controls.statusDisplay.innerText = 'Waiting';
+    },
+
+    handleReadyStateChange: function(event)
+    {
+        this.updateReadyState();
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
+    },
+
+    handleTimeUpdate: function(event)
+    {
+        this.updateTime();
+    },
+
+    handleDurationChange: function(event)
+    {
+        this.updateDuration();
+        this.updateTime();
+    },
+
+    handlePlay: function(event)
+    {
+        this.updatePlaying();
+    },
+
+    handlePause: function(event)
+    {
+        this.updatePlaying();
+    },
+
+    handleVolumeChange: function(event)
+    {
+        this.updateVolume();
+    },
+
+    handleTextTrackChange: function(event)
+    {
+        this.updateCaptionContainer();
+    },
+
+    handleTextTrackAdd: function(event)
+    {
+        var track = event.track;
+        this.listenFor(track, 'cuechange', this.handleTextTrackCueChange);
+
+        if (this.trackHasThumbnails(track) && track.mode === 'disabled')
+            track.mode = 'hidden';
+
+        this.updateThumbnail();
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
+    },
+
+    handleTextTrackRemove: function(event)
+    {
+        var track = event.track;
+        this.stopListeningFor(track, 'cuechange', this.handleTextTrackCueChange);
+        this.updateThumbnail();
+        this.updateCaptionButton();
+        this.updateCaptionContainer();
+    },
+
+    handleTextTrackCueChange: function(event)
+    {
+        this.updateCaptionContainer();
+    },
+
+    isFullScreen: function()
+    {
+        return document.webkitCurrentFullScreenElement === this.video;
+    },
+
+    handleFullscreenChange: function(event)
+    {
+        this.updateBase();
+
+        if (this.isFullScreen()) {
+            this.controls.fullscreenButton.classList.add(this.ClassNames.exit);
+            this.setControlsType(Controller.FullScreenControls);
+        } else {
+            this.controls.fullscreenButton.classList.remove(this.ClassNames.exit);
+            this.setControlsType(Controller.InlineControls);
+        }
+    },
+
+    handleWrapperMouseMove: function(event)
+    {
+        this.showControls();
+        if (this.hideTimer)
+            clearTimeout(this.hideTimer);
+        this.hideTimer = setTimeout(this.hideControls.bind(this), this.HideContrtolsDelay);
+
+        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()
+    },
+
+    handleWrapperMouseOut: function(event)
+    {
+        this.controls.panel.classList.remove(this.ClassNames.show);
+        if (this.hideTimer)
+            clearTimeout(this.hideTimer);
+    },
+
+    handleWrapperMouseUp: function(event)
+    {
+        this.isDragging = false;
+        this.stopListeningFor(this.base, 'mouseup', 'handleWrapperMouseUp', true);
+    },
+
+    handlePanelMouseDown: function(event)
+    {
+        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
+        );
+    },
+
+    handlePanelTransitionEnd: function(event)
+    {
+        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);
+    },
+
+    handlePanelClick: function(event)
+    {
+        // Prevent clicks in the panel from playing or pausing the video in a MediaDocument.
+        event.preventDefault();
+    },
+
+    handleRewindButtonClicked: function(event)
+    {
+        var newTime = Math.max(
+                               this.video.startTime,
+                               this.video.currentTime - this.RewindAmount,
+                               this.video.seekable.start(0));
+        this.video.currentTime = newTime;
+    },
+
+    canPlay: function()
+    {
+        return this.video.paused || this.video.ended || this.video.readyState < HTMLMediaElement.HAVE_METADATA;
+    },
+
+    handlePlayButtonClicked: function(event)
+    {
+        if (this.canPlay())
+            this.video.play();
+        else
+            this.video.pause();
+    },
+
+    handleTimelineChange: function(event)
+    {
+        this.video.currentTime = this.controls.timeline.value;
+    },
+
+    handleTimelineDown: function(event)
+    {
+        this.controls.thumbnail.classList.add(this.ClassNames.show);
+    },
+
+    handleTimelineUp: function(event)
+    {
+        this.controls.thumbnail.classList.remove(this.ClassNames.show);
+    },
+
+    handleTimelineMouseOver: function(event)
+    {
+        this.controls.thumbnail.classList.add(this.ClassNames.show);
+    },
+
+    handleTimelineMouseOut: function(event)
+    {
+        this.controls.thumbnail.classList.remove(this.ClassNames.show);
+    },
+
+    handleTimelineMouseMove: function(event)
+    {
+        if (this.controls.thumbnail.classList.contains(this.ClassNames.hidden))
+            return;
+
+        this.controls.thumbnail.classList.add(this.ClassNames.show);
+        var localPoint = webkitConvertPointFromPageToNode(this.controls.timeline, new WebKitPoint(event.clientX, event.clientY));
+        var percent = (localPoint.x - this.controls.timeline.offsetLeft) / this.controls.timeline.offsetWidth;
+        percent = Math.max(Math.min(1, percent), 0);
+        this.controls.thumbnail.style.left = percent * 100 + '%';
+
+        var thumbnailTime = this.video.startTime + percent * this.video.duration;
+        for (var i = 0; i < this.video.textTracks.length; ++i) {
+            var track = this.video.textTracks[i];
+            if (!this.trackHasThumbnails(track))
+                continue;
+
+            if (!track.cues)
+                continue;
+
+            for (var j = 0; j < track.cues.length; ++j) {
+                var cue = track.cues[j];
+                if (thumbnailTime >= cue.startTime && thumbnailTime < cue.endTime) {
+                    this.controls.thumbnailImage.src = cue.text;
+                    return;
+                }
+            }
+        }
+    },
+
+    handleMuteButtonClicked: function(event)
+    {
+        this.video.muted = !this.video.muted;
+    },
+
+    handleMinButtonClicked: function(event)
+    {
+        if (this.video.muted)
+            this.video.muted = false;
+        this.video.volume = 0;
+    },
+
+    handleMaxButtonClicked: function(event)
+    {
+        if (this.video.muted)
+            this.video.muted = false;
+        this.video.volume = 1;
+    },
+
+    handleVolumeSliderChange: function(event)
+    {
+        if (this.video.muted)
+            this.video.muted = false;
+        this.video.volume = this.controls.volume.value;
+    },
+
+    handleCaptionButtonClicked: function(event)
+    {
+        if (this.captionMenu)
+            this.destroyCaptionMenu();
+        else
+            this.buildCaptionMenu();
+    },
+
+    handleFullscreenButtonClicked: function(event)
+    {
+        if (this.isFullScreen())
+            document.webkitExitFullscreen();
+        else
+            this.video.webkitRequestFullscreen();
+    },
+
+    handleControlsChange: function()
+    {
+        try {
+            this.updateBase();
+
+            if (this.shouldHaveControls())
+                this.addControls();
+            else
+                this.removeControls();
+        } catch(e) {
+            if (window.console)
+                console.error(e);
+        }
+    },
+
+    nextRate: function()
+    {
+        return Math.min(this.MaximumSeekRate, Math.abs(this.video.playbackRate * 2));
+    },
+
+    handleSeekBackMouseDown: function(event)
+    {
+        this.actionAfterSeeking = (this.canPlay() ? Controller.PauseAfterSeeking : Controller.PlayAfterSeeking);
+        this.video.play();
+        this.video.playbackRate = this.nextRate() * -1;
+        this.seekInterval = setInterval(this.seekBackFaster.bind(this), this.SeekDelay);
+    },
+
+    seekBackFaster: function()
+    {
+        this.video.playbackRate = this.nextRate() * -1;
+    },
+
+    handleSeekBackMouseUp: function(event)
+    {
+        this.video.playbackRate = this.video.defaultPlaybackRate;
+        if (this.actionAfterSeeking === Controller.PauseAfterSeeking)
+            this.video.pause();
+        else if (this.actionAfterSeeking === Controller.PlayAfterSeeking)
+            this.video.play();
+        if (this.seekInterval)
+            clearInterval(this.seekInterval);
+    },
+
+    handleSeekForwardMouseDown: function(event)
+    {
+        this.actionAfterSeeking = (this.canPlay() ? Controller.PauseAfterSeeking : Controller.PlayAfterSeeking);
+        this.video.play();
+        this.video.playbackRate = this.nextRate();
+        this.seekInterval = setInterval(this.seekForwardFaster.bind(this), this.SeekDelay);
+    },
+
+    seekForwardFaster: function()
+    {
+        this.video.playbackRate = this.nextRate();
+    },
+
+    handleSeekForwardMouseUp: function(event)
+    {
+        this.video.playbackRate = this.video.defaultPlaybackRate;
+        if (this.actionAfterSeeking === Controller.PauseAfterSeeking)
+            this.video.pause();
+        else if (this.actionAfterSeeking === Controller.PlayAfterSeeking)
+            this.video.play();
+        if (this.seekInterval)
+            clearInterval(this.seekInterval);
+    },
+
+    updateDuration: function()
+    {
+        this.controls.timeline.min = this.video.startTime;
+        this.controls.timeline.max = this.video.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).toFixed(0);
+        return (time < 0 ? '-' : '' ) + String('00' + intMinutes).slice(-2) + ":" + String('00' + intSeconds).slice(-2)
+    },
+
+    updatePlaying: function()
+    {
+        if (this.canPlay()) {
+            this.controls.panel.classList.add(this.ClassNames.paused);
+            this.controls.playButton.classList.add(this.ClassNames.paused);
+        } else {
+            this.controls.panel.classList.remove(this.ClassNames.paused);
+            this.controls.playButton.classList.remove(this.ClassNames.paused);
+
+            this.controls.panel.classList.remove(this.ClassNames.show);
+            if (this.hideTimer)
+                clearTimeout(this.hideTimer);
+            this.hideTimer = setTimeout(this.hideControls.bind(this), this.HideContrtolsDelay);
+        }
+    },
+
+    showControls: function()
+    {
+        this.controls.panel.classList.add(this.ClassNames.show);
+        this.controls.panel.classList.remove(this.ClassNames.hidden);
+    },
+
+    hideControls: function()
+    {
+        this.controls.panel.classList.remove(this.ClassNames.show);
+    },
+
+    removeControls: function()
+    {
+        if (this.controls.panel.parentNode)
+            this.controls.panel.parentNode.removeChild(this.controls.panel);
+        this.destroyCaptionMenu();
+    },
+
+    addControls: function()
+    {
+        this.base.appendChild(this.controls.panel);
+    },
+
+    updateTime: function()
+    {
+        var currentTime = this.video.currentTime;
+        var timeRemaining = (currentTime - this.video.startTime) - this.video.duration;
+        this.controls.currentTime.innerText = this.formatTime(currentTime);
+        this.controls.timeline.value = this.video.currentTime;
+        this.controls.remainingTime.innerText = this.formatTime(timeRemaining);
+    },
+
+    updateReadyState: function()
+    {
+        this.setStatusHidden(this.video.readyState > HTMLMediaElement.HAVE_NOTHING);
+    },
+
+    setStatusHidden: function(hidden)
+    {
+        if (hidden) {
+            this.controls.statusDisplay.classList.add(this.ClassNames.hidden);
+            this.controls.currentTime.classList.remove(this.ClassNames.hidden);
+            this.controls.timeline.classList.remove(this.ClassNames.hidden);
+            this.controls.remainingTime.classList.remove(this.ClassNames.hidden);
+        } else {
+            this.controls.statusDisplay.classList.remove(this.ClassNames.hidden);
+            this.controls.currentTime.classList.add(this.ClassNames.hidden);
+            this.controls.timeline.classList.add(this.ClassNames.hidden);
+            this.controls.remainingTime.classList.add(this.ClassNames.hidden);
+        }
+    },
+
+    trackHasThumbnails: function(track)
+    {
+        return track.kind === 'thumbnails' || (track.kind === 'metadata' && track.label === 'thumbnails');
+    },
+
+    updateThumbnail: function()
+    {
+        for (var i = 0; i < this.video.textTracks.length; ++i) {
+            var track = this.video.textTracks[i];
+            if (this.trackHasThumbnails(track)) {
+                this.controls.thumbnail.classList.remove(this.ClassNames.hidden);
+                return;
+            }
+        }
+
+        this.controls.thumbnail.classList.add(this.ClassNames.hidden);
+    },
+
+    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;
+
+        if (this.video.webkitHasClosedCaptions)
+            this.host.textTrackContainer.classList.remove(this.ClassNames.hidden);
+        else
+            this.host.textTrackContainer.classList.add(this.ClassNames.hidden);
+
+        this.updateBase();
+        this.host.updateTextTrackContainer();
+    },
+
+    buildCaptionMenu: function()
+    {
+        var tracks = this.host.sortedTrackListForMenu(this.video.textTracks);
+        if (!tracks || !tracks.length)
+            return;
+
+        this.captionMenu = document.createElement('div');
+        this.captionMenu.setAttribute('pseudo', '-webkit-media-controls-closed-captions-container');
+        this.base.appendChild(this.captionMenu);
+        this.captionMenuItems = [];
+
+        var offItem = this.host.captionMenuOffItem;
+        var automaticItem = this.host.captionMenuAutomaticItem;
+        var displayMode = this.host.captionDisplayMode;
+
+        var list = document.createElement('div');
+        this.captionMenu.appendChild(list);
+        list.classList.add(this.ClassNames.list);
+
+        var heading = document.createElement('h3');
+        list.appendChild(heading);
+        heading.innerText = 'Subtitles';
+
+        var ul = document.createElement('ul');
+        list.appendChild(ul);
+
+        for (var i = 0; i < tracks.length; ++i) {
+            var menuItem = document.createElement('li');
+            this.captionMenuItems.push(menuItem);
+            this.listenFor(menuItem, 'click', this.captionItemSelected);
+            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);
+                continue;
+            }
+
+            if (displayMode != 'automatic' && track.mode === 'showing') {
+                var trackMenuItemSelected = true;
+                menuItem.classList.add(this.ClassNames.selected);
+            }
+        }
+
+        if (offMenu && displayMode === 'forced-only' && !trackMenuItemSelected)
+            offMenu.classList.add(this.ClassNames.selected);
+    },
+
+    captionItemSelected: function(event)
+    {
+        this.host.setSelectedTextTrack(event.target.track);
+        this.destroyCaptionMenu();
+    },
+
+    destroyCaptionMenu: function()
+    {
+        if (!this.captionMenu)
+            return;
+
+        this.captionMenuItems.forEach(function(item){
+            this.stopListeningFor(item, 'click', this.captionItemSelected);
+        }, this);
+
+        if (this.captionMenu.parentNode)
+            this.captionMenu.parentNode.removeChild(this.captionMenu);
+        delete this.captionMenu;
+        delete this.captionMenuItems;
+    },
+
+    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;
+        }
+    },
+
+    isAudio: function()
+    {
+        return this.video instanceof HTMLAudioElement;
+    },
+
+};
index 5895285..0b0b3f0 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaControlsHost.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaError.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClCompile Include="..\Modules\quota\StorageErrorCallback.cpp" />
     <ClCompile Include="..\Modules\quota\StorageInfo.cpp" />
     <ClCompile Include="..\Modules\quota\StorageQuota.cpp" />
+    <ClInclude Include="..\Modules\mediacontrols\MediaControlsHost.cpp" />
     <ClCompile Include="..\Modules\mediasource\MediaSource.cpp" />
     <ClCompile Include="..\Modules\mediasource\MediaSourceRegistry.cpp" />
     <ClCompile Include="..\Modules\mediasource\SourceBuffer.cpp" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSJavaScriptCallFrame.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSKeyboardEvent.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSLocation.h" />
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaControlsHost.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaError.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaList.h" />
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaQueryList.h" />
     <ClInclude Include="..\Modules\quota\StorageQuota.h" />
     <ClInclude Include="..\Modules\quota\StorageQuotaCallback.h" />
     <ClInclude Include="..\Modules\quota\StorageUsageCallback.h" />
+    <ClInclude Include="..\Modules\mediacontrols\MediaControlsHost.h" />
     <ClInclude Include="..\Modules\mediasource\MediaSource.h" />
     <ClInclude Include="..\Modules\mediasource\MediaSourceRegistry.h" />
     <ClInclude Include="..\Modules\mediasource\SourceBuffer.h" />
     <None Include="..\css\CSSPropertyNames.in" />
     <None Include="..\css\CSSValueKeywords.in" />
     <None Include="..\css\fullscreen.css" />
-    <None Include="..\css\fullscreenQuickTime.css" />
     <None Include="..\css\html.css" />
     <None Include="..\css\mathml.css" />
     <None Include="..\css\mediaControls.css" />
-    <None Include="..\css\mediaControlsQuickTime.css" />
     <None Include="..\css\plugIns.css" />
     <None Include="..\css\quirks.css" />
     <None Include="..\css\svg.css" />
index 248d1a4..6245bd5 100644 (file)
@@ -25,6 +25,9 @@
     <Filter Include="Modules\quota">
       <UniqueIdentifier>{47f62e6e-87ae-4091-993d-d1d78f2c8ba9}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Modules\mediacontrols">
+      <UniqueIdentifier>{63ec45f2-29a3-4f42-90af-dd4fedaca99b}</UniqueIdentifier>
+    </Filter>
     <Filter Include="Modules\mediasource">
       <UniqueIdentifier>{614031cc-d79e-45b1-939e-dabeefe1fc9d}</UniqueIdentifier>
     </Filter>
     <ClCompile Include="..\Modules\quota\StorageInfo.cpp">
       <Filter>Modules\quota</Filter>
     </ClCompile>
+    <ClCompile Include="..\Modules\mediacontrols\MediaControlsHost.cpp">
+      <Filter>Modules\mediacontrols</Filter>
+    </CLCompile>
     <ClCompile Include="..\Modules\mediasource\MediaSource.cpp">
       <Filter>Modules\mediasource</Filter>
     </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSLocation.cpp">
       <Filter>DerivedSources</Filter>
     </ClCompile>
-    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaError.cpp">
+    <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaControlsHost.cpp">
+      <Filter>DerivedSources</Filter>
+    </ClCompile>
+     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaError.cpp">
       <Filter>DerivedSources</Filter>
     </ClCompile>
     <ClCompile Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaList.cpp">
     <ClInclude Include="..\Modules\quota\StorageUsageCallback.h">
       <Filter>Modules\quota</Filter>
     </ClInclude>
+    <ClInclude Include="..\Modules\mediacontrols\MediaControlsHost.h">
+      <Filter>Modules\mediacontrols</Filter>
+    </CLCompile>
     <ClInclude Include="..\Modules\mediasource\MediaSource.h">
       <Filter>Modules\mediasource</Filter>
     </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSLocation.h">
       <Filter>DerivedSources</Filter>
     </ClInclude>
+    <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaControlsHost.h">
+      <Filter>DerivedSources</Filter>
+    </ClInclude>
     <ClInclude Include="$(ConfigurationBuildDir)\obj$(PlatformArchitecture)\$(ProjectName)\DerivedSources\JSMediaError.h">
       <Filter>DerivedSources</Filter>
     </ClInclude>
index 9503665..dacd79a 100644 (file)
                CDA98E0D1603FE4A00FEA3B1 /* MediaKeys.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98DCA1601508A00FEA3B1 /* MediaKeys.cpp */; };
                CDA98E0E1603FE5800FEA3B1 /* MediaKeySession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDA98DC716014F2C00FEA3B1 /* MediaKeySession.cpp */; };
                CDAA8D0A14D71B2E0061EA60 /* PlatformClockCM.mm in Sources */ = {isa = PBXBuildFile; fileRef = CDAA8D0814D385600061EA60 /* PlatformClockCM.mm */; };
+               CDAB6D2817C7DE6C00C60B34 /* MediaControlsHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDAB6D2617C7DE6C00C60B34 /* MediaControlsHost.cpp */; };
+               CDAB6D2917C7DE6C00C60B34 /* MediaControlsHost.h in Headers */ = {isa = PBXBuildFile; fileRef = CDAB6D2717C7DE6C00C60B34 /* MediaControlsHost.h */; };
+               CDAB6D2D17C814EE00C60B34 /* JSMediaControlsHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDAB6D2B17C814EE00C60B34 /* JSMediaControlsHost.cpp */; };
+               CDAB6D2E17C814EE00C60B34 /* JSMediaControlsHost.h in Headers */ = {isa = PBXBuildFile; fileRef = CDAB6D2C17C814EE00C60B34 /* JSMediaControlsHost.h */; };
+               CDAB6D3117C9259500C60B34 /* UserAgentScripts.h in Headers */ = {isa = PBXBuildFile; fileRef = CDAB6D2F17C9259500C60B34 /* UserAgentScripts.h */; };
+               CDAB6D3217C9259500C60B34 /* UserAgentScriptsData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDAB6D3017C9259500C60B34 /* UserAgentScriptsData.cpp */; };
                CDAE8C091746B95700532D78 /* AudioSessionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDAE8C071746B95700532D78 /* AudioSessionManager.cpp */; };
                CDB859F7160D48A400E5B07F /* MediaKeyEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB859F4160D489900E5B07F /* MediaKeyEvent.cpp */; };
                CDB859FA160D494900E5B07F /* JSMediaKeyEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDB859F8160D493E00E5B07F /* JSMediaKeyEvent.cpp */; };
                CDA98E0C1603CF3C00FEA3B1 /* CDMPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDMPrivate.h; path = Modules/encryptedmedia/CDMPrivate.h; sourceTree = "<group>"; };
                CDAA8D0714D385600061EA60 /* PlatformClockCM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformClockCM.h; sourceTree = "<group>"; };
                CDAA8D0814D385600061EA60 /* PlatformClockCM.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PlatformClockCM.mm; sourceTree = "<group>"; };
+               CDAB6D2517C7DE5700C60B34 /* MediaControlsHost.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = MediaControlsHost.idl; sourceTree = "<group>"; };
+               CDAB6D2617C7DE6C00C60B34 /* MediaControlsHost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControlsHost.cpp; sourceTree = "<group>"; };
+               CDAB6D2717C7DE6C00C60B34 /* MediaControlsHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControlsHost.h; sourceTree = "<group>"; };
+               CDAB6D2B17C814EE00C60B34 /* JSMediaControlsHost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaControlsHost.cpp; sourceTree = "<group>"; };
+               CDAB6D2C17C814EE00C60B34 /* JSMediaControlsHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaControlsHost.h; sourceTree = "<group>"; };
+               CDAB6D2F17C9259500C60B34 /* UserAgentScripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserAgentScripts.h; sourceTree = "<group>"; };
+               CDAB6D3017C9259500C60B34 /* UserAgentScriptsData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserAgentScriptsData.cpp; sourceTree = "<group>"; };
                CDAE8C071746B95700532D78 /* AudioSessionManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSessionManager.cpp; sourceTree = "<group>"; };
                CDAE8C081746B95700532D78 /* AudioSessionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSessionManager.h; sourceTree = "<group>"; };
                CDB859F2160D489900E5B07F /* MediaKeyError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaKeyError.h; sourceTree = "<group>"; };
                CDB859F6160D489900E5B07F /* MediaKeyEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaKeyEvent.idl; sourceTree = "<group>"; };
                CDB859F8160D493E00E5B07F /* JSMediaKeyEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaKeyEvent.cpp; sourceTree = "<group>"; };
                CDB859F9160D493E00E5B07F /* JSMediaKeyEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSMediaKeyEvent.h; sourceTree = "<group>"; };
-               CDBD93BA1333BD4B002570E3 /* fullscreenQuickTime.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = fullscreenQuickTime.css; sourceTree = "<group>"; };
+               CDC1DD4117CC2C48008CB55D /* mediaControlsApple.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = mediaControlsApple.css; sourceTree = "<group>"; };
                CDC26B3C160A62B00026757B /* MockCDM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MockCDM.cpp; sourceTree = "<group>"; };
                CDC26B3D160A62B00026757B /* MockCDM.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockCDM.h; sourceTree = "<group>"; };
                CDC69DD41632026C007C38DF /* WebCoreFullScreenWarningView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreFullScreenWarningView.h; sourceTree = "<group>"; };
                CDC69DD916371FD3007C38DF /* WebCoreFullScreenPlaceholderView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCoreFullScreenPlaceholderView.mm; sourceTree = "<group>"; };
                CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = "<group>"; };
                CDD1E525167BA56400CE820B /* TextTrackRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentation.h; sourceTree = "<group>"; };
+               CDE6560E17CA6E7600526BA7 /* mediaControlsApple.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = mediaControlsApple.js; sourceTree = "<group>"; };
                CDEA762C14608224008B31F1 /* Clock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Clock.h; sourceTree = "<group>"; };
                CDEA762E146084DE008B31F1 /* PlatformClockCA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformClockCA.cpp; sourceTree = "<group>"; };
                CDEA762F146084EE008B31F1 /* PlatformClockCA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformClockCA.h; sourceTree = "<group>"; };
                                AA93C850175D5B2000FD3CE3 /* IndieUI */,
                                1C5FAECA0DCFD8C900D58F78 /* Inspector */,
                                CD61FE7B1794CA02004101EB /* MediaSource */,
+                               CDAB6D2A17C7E97D00C60B34 /* MediaControls */,
                                07CFD99317D01405001C4FFC /* MediaStream */,
                                33503C9C10179A9A003B47E1 /* Notifications */,
                                1AC226020DB69EA70089B669 /* Offline */,
                656580EC09D12B20000E61D7 /* Derived Sources */ = {
                        isa = PBXGroup;
                        children = (
+                               CDAB6D2F17C9259500C60B34 /* UserAgentScripts.h */,
+                               CDAB6D3017C9259500C60B34 /* UserAgentScriptsData.cpp */,
                                656581AC09D14EE6000E61D7 /* CharsetData.cpp */,
                                E406F3FB1198307D009D59D6 /* ColorData.cpp */,
                                6565814409D13043000E61D7 /* CSSGrammar.cpp */,
                                971145FF14EF007900674FD9 /* geolocation */,
                                9712A55315004E3C0048AF10 /* indexeddb */,
                                AA7EA0A917557B1C00DF4643 /* indieui */,
+                               CD9A37F517C7D93600C5FA7A /* mediacontrols */,
                                B1A942DD15B5CE2200D525D1 /* mediasource */,
                                07221B4617CEC32700848E51 /* mediastream */,
                                333F703D0FB49C16008E12A6 /* notifications */,
                        name = MediaSource;
                        sourceTree = "<group>";
                };
+               CD9A37F517C7D93600C5FA7A /* mediacontrols */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CDC1DD4117CC2C48008CB55D /* mediaControlsApple.css */,
+                               CDE6560E17CA6E7600526BA7 /* mediaControlsApple.js */,
+                               CDAB6D2517C7DE5700C60B34 /* MediaControlsHost.idl */,
+                               CDAB6D2617C7DE6C00C60B34 /* MediaControlsHost.cpp */,
+                               CDAB6D2717C7DE6C00C60B34 /* MediaControlsHost.h */,
+                       );
+                       name = mediacontrols;
+                       path = Modules/mediacontrols;
+                       sourceTree = "<group>";
+               };
                CDA98DBD16014E0800FEA3B1 /* encryptedmedia */ = {
                        isa = PBXGroup;
                        children = (
                        name = EncryptedMedia;
                        sourceTree = "<group>";
                };
+               CDAB6D2A17C7E97D00C60B34 /* MediaControls */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CDAB6D2B17C814EE00C60B34 /* JSMediaControlsHost.cpp */,
+                               CDAB6D2C17C814EE00C60B34 /* JSMediaControlsHost.h */,
+                       );
+                       name = MediaControls;
+                       sourceTree = "<group>";
+               };
                DF9AFD6F13FC31B00015FEB7 /* objc */ = {
                        isa = PBXGroup;
                        children = (
                                A80E6CC70A1989CA007FB8C5 /* FontValue.cpp */,
                                A80E6CC30A1989CA007FB8C5 /* FontValue.h */,
                                CD4E0AFA11F7BC27009D3811 /* fullscreen.css */,
-                               CDBD93BA1333BD4B002570E3 /* fullscreenQuickTime.css */,
                                93CA4C9909DF93FA00DF8677 /* html.css */,
                                4A9CC81E16BF9BB400EC645A /* InspectorCSSOMWrappers.cpp */,
                                4A9CC81F16BF9BB400EC645A /* InspectorCSSOMWrappers.h */,
                                2ECF7AE210162B5800427DE7 /* ErrorEvent.h in Headers */,
                                85031B420A44EFC700F992E0 /* Event.h in Headers */,
                                4138D3351244054800323D33 /* EventContext.h in Headers */,
+                               CDAB6D2917C7DE6C00C60B34 /* MediaControlsHost.h in Headers */,
                                418A06D0133C04D500CD379C /* EventDispatcher.h in Headers */,
                                4AF1AD3F13FD23A400AA9590 /* EventDispatchMediator.h in Headers */,
                                BC60D90C0D2A17CE00B9918F /* EventException.h in Headers */,
                                84730D791248F0B300D3A9C9 /* FEConvolveMatrix.h in Headers */,
                                50D403C814768C9400D30BB5 /* FECustomFilter.h in Headers */,
                                84730D7B1248F0B300D3A9C9 /* FEDiffuseLighting.h in Headers */,
+                               CDAB6D3117C9259500C60B34 /* UserAgentScripts.h in Headers */,
                                84730D7D1248F0B300D3A9C9 /* FEDisplacementMap.h in Headers */,
                                4358E8811360A31700E4748C /* FEDropShadow.h in Headers */,
                                84730D7F1248F0B300D3A9C9 /* FEFlood.h in Headers */,
                                0F580B0D0F12A2690051D689 /* GraphicsLayer.h in Headers */,
                                499B3ED7128CD31400E726C2 /* GraphicsLayerCA.h in Headers */,
                                0F580B0E0F12A2690051D689 /* GraphicsLayerClient.h in Headers */,
+                               CDAB6D2E17C814EE00C60B34 /* JSMediaControlsHost.h in Headers */,
                                1AC69593161A1E53003732CB /* GraphicsLayerFactory.h in Headers */,
                                0FA24D7A162DF91900A3F4C0 /* GraphicsLayerUpdater.h in Headers */,
                                B2A015AB0AF6CD53006BCE0E /* GraphicsTypes.h in Headers */,
                                1A8F6BBE0DB55CDC001DB794 /* ApplicationCacheGroup.cpp in Sources */,
                                24F54EAC101FE914000AE741 /* ApplicationCacheHost.cpp in Sources */,
                                1A8F6BC00DB55CDC001DB794 /* ApplicationCacheResource.cpp in Sources */,
+                               CDAB6D2817C7DE6C00C60B34 /* MediaControlsHost.cpp in Sources */,
                                1A2AAC580DC2A3B100A20D9A /* ApplicationCacheStorage.cpp in Sources */,
                                9B417065125662B3006B28FC /* ApplyBlockElementCommand.cpp in Sources */,
                                93309DD8099E64920056E581 /* ApplyStyleCommand.cpp in Sources */,
                                8931DE5B14C44C44000DC9D2 /* JSBlobCustom.cpp in Sources */,
                                1449E287107D4DB400B5793F /* JSCallbackData.cpp in Sources */,
                                65DF323909D1DE65000BE325 /* JSCanvasGradient.cpp in Sources */,
+                               CDAB6D3217C9259500C60B34 /* UserAgentScriptsData.cpp in Sources */,
                                65DF323B09D1DE65000BE325 /* JSCanvasPattern.cpp in Sources */,
                                49EED1421051969400099FAB /* JSCanvasRenderingContext.cpp in Sources */,
                                49EED1441051969400099FAB /* JSCanvasRenderingContext2D.cpp in Sources */,
                                00B9318713BA8DB30035A948 /* XMLDocumentParser.cpp in Sources */,
                                00B9318913BA8DBC0035A948 /* XMLDocumentParserLibxml2.cpp in Sources */,
                                00B9318B13BA8DC90035A948 /* XMLDocumentParserScope.cpp in Sources */,
+                               CDAB6D2D17C814EE00C60B34 /* JSMediaControlsHost.cpp in Sources */,
                                59C28045138DC2410079B7E2 /* XMLErrors.cpp in Sources */,
                                BC772C460C4EB2C60083285F /* XMLHttpRequest.cpp in Sources */,
                                978D07CE145A10370096908D /* XMLHttpRequestException.cpp in Sources */,
index 3136c81..ad93279 100644 (file)
 #include "JSInspectorFrontendHost.h"
 #endif
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+#include "JSMediaControlsHost.h"
+#endif
+
 using namespace JSC;
 
 namespace WebCore {
@@ -90,6 +94,16 @@ bool ScriptGlobalObject::set(JSC::ExecState* scriptState, const char* name, Inje
 }
 #endif // ENABLE(INSPECTOR)
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+bool ScriptGlobalObject::set(JSC::ExecState* scriptState, const char* name, MediaControlsHost* value)
+{
+    JSLockHolder lock(scriptState);
+    JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
+    globalObject->putDirect(scriptState->vm(), Identifier(scriptState, name), toJS(scriptState, globalObject, value));
+    return handleException(scriptState);
+}
+#endif
+
 bool ScriptGlobalObject::get(JSC::ExecState* scriptState, const char* name, ScriptObject& value)
 {
     JSLockHolder lock(scriptState);
index e9825e9..6b32a0c 100644 (file)
@@ -40,6 +40,7 @@
 namespace WebCore {
     class InjectedScriptHost;
     class InspectorFrontendHost;
+    class MediaControlsHost;
 
     class ScriptObject : public ScriptValue {
     public:
@@ -60,6 +61,10 @@ namespace WebCore {
         static bool set(JSC::ExecState*, const char* name, InspectorFrontendHost*);
         static bool set(JSC::ExecState*, const char* name, InjectedScriptHost*);
 #endif
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+        static bool set(JSC::ExecState*, const char* name, MediaControlsHost*);
+#endif
+
         static bool get(JSC::ExecState*, const char* name, ScriptObject&);
         static bool remove(JSC::ExecState*, const char* name);
     private:
index 01055ff..b8fab2f 100644 (file)
@@ -185,7 +185,9 @@ void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element,
 
 #if ENABLE(VIDEO)
     if (!mediaControlsStyleSheet && (element->hasTagName(videoTag) || isHTMLAudioElement(element))) {
-        String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document().page())->extraMediaControlsStyleSheet();
+        String mediaRules = RenderTheme::themeForPage(element->document().page())->mediaControlsStyleSheet();
+        if (mediaRules.isEmpty())
+            mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::themeForPage(element->document().page())->extraMediaControlsStyleSheet();
         mediaControlsStyleSheet = parseUASheet(mediaRules);
         defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval());
         defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval());
diff --git a/Source/WebCore/css/fullscreenQuickTime.css b/Source/WebCore/css/fullscreenQuickTime.css
deleted file mode 100644 (file)
index 5457463..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-/* alternate media controls - Extend fullscreen.css */
-
-video:-webkit-full-screen::-webkit-media-controls-panel {
-    -webkit-align-items: flex-start !important;
-    -webkit-justify-content: flex-end !important;
-    -webkit-appearance: none !important;
-
-    padding: 12px 0 0 10px !important;
-    width: 430px !important;
-    height: 48px !important;
-    margin: 0 auto 50px auto !important;
-    
-    background-image: -webkit-gradient(
-        linear,
-        left top,
-        left bottom,
-        color-stop(0, rgba(30, 30, 30, .97)),
-        color-stop(0.333, rgba(45, 45, 45, .97)),
-        color-stop(0.35,  rgba(25, 25, 25, .97)),
-        color-stop(0.366, rgba(25, 25, 25, .97)),
-        color-stop(0.366, rgba(12, 12, 12, .97)),
-        color-stop(1, rgba(19, 19, 19, .97))
-    ) !important;
-
-    -webkit-box-shadow: 
-        inset 0 -1px 1px rgba(0, 0, 0, 0.5),
-        inset 0  1px 0 0px   rgba(255, 255, 255, 0.15),
-        inset 0 -1px 0 0px   rgba(202, 202, 202, 0.09),
-        0  0   0 1px rgba(0, 0, 0, 0.5);
-    border-radius: 8px !important;
-
-    -webkit-transition: opacity 0.3s linear !important;
-}
-
-video:-webkit-animating-full-screen-transition::-webkit-media-controls-panel {
-    opacity: 0 ! important;
-    -webkit-transition: opacity 0 ! important;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-mute-button {
-    display: none;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-volume-slider-container {
-    display: none;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-volume-slider {
-    display: none;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-volume-slider-mute-button {
-    display: none;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-fullscreen-volume-min-button {
-    -webkit-appearance: media-mute-button;
-    display: block;
-    position: absolute;
-    left: 11px;
-    top: 15px;
-    width: 17px;
-    height: 14px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-fullscreen-volume-slider {
-    -webkit-appearance: media-fullscreen-volume-slider;
-    display: block;
-    position: absolute;
-    left: 28px;
-    top: 14px;
-    height: 11px;
-    width: 50px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-fullscreen-volume-max-button {
-    -webkit-appearance: media-mute-button;
-    display: block;
-    position: absolute;
-    left: 84px;
-    top: 15px;
-    width: 17px;
-    height: 14px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-play-button {
-    position: absolute;
-    width: 22px;
-    height: 23px;
-    left: 209px;
-    top: 9px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-rewind-button {
-    position: absolute;
-    left: 162px;
-    top: 13px;
-    width: 18px;
-    height: 18px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-seek-back-button {
-    position: absolute;
-    display: -webkit-flex;
-    width: 23px;
-    height: 16px;
-    left: 162px;
-    top: 13px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-return-to-realtime-button {
-    position: absolute;
-    display: -webkit-flex;
-    width: 29px;
-    height: 16px;
-    left: 262px;
-    top: 13px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-seek-forward-button {
-    position: absolute;
-    display: -webkit-flex;
-    width: 23px;
-    height: 16px;
-    left: 262px;
-    top: 13px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-timeline-container {
-    height: auto;
-    width: 420px;
-    position: absolute;
-    bottom: 9px;
-    left: 8px;
-    right: 8px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-status-display {
-    width: 420px;
-    position: absolute;
-    bottom: 9px;
-    left: 8px;
-    right: 8px;
-}
-
-video:-webkit-full-screen::-webkit-media-controls-closed-captions-container {
-    bottom: 114px;
-    right: -webkit-calc(50% - 183px); /* 183px is 221px (half the media controller's width) minus 38px (the right position of the captions icon). */
-    max-width: -webkit-calc(50% + 173px); /* right + 10px */
-    max-height: -webkit-calc(100% - 124px); /* bottom + 10px */
-}
diff --git a/Source/WebCore/css/mediaControlsQuickTime.css b/Source/WebCore/css/mediaControlsQuickTime.css
deleted file mode 100644 (file)
index 804f922..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2009, 2010, 2011 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-/* alternate media controls - Extend mediaControls.css */
-
-audio {
-    width: 200px;
-    height: 25px;
-}
-
-audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
-    /* In mediaControls.css */
-    -webkit-appearance: media-controls-background;
-    overflow: visible;
-    height: 25px;
-    -webkit-flex-shrink: 0;
-}
-
-video:-webkit-full-page-media::-webkit-media-controls-panel {
-    bottom: 0px;
-}
-
-audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button {
-    -webkit-order: 2; /* Before the fullscreen button */
-
-    width: 14px;
-    height: 12px;
-    margin-left: 2px;
-    margin-right: 9px;
-    border: none !important;
-
-    position: relative;
-    z-index: 1;
-}
-
-audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
-    width: 16px;
-    height: 16px;
-    margin-left: 6px;
-    margin-right: 1px;
-    border: none !important;
-}
-
-audio::-webkit-media-controls-timeline-container, video::-webkit-media-controls-timeline-container {
-    -webkit-appearance: none;
-    -webkit-flex-direction: row;
-    -webkit-align-items: center;
-    -webkit-justify-content: flex-start;
-    -webkit-flex: 1 1;
-    text-align: right;
-    height: auto;
-}
-
-audio::-webkit-media-controls-current-time-display, video::-webkit-media-controls-current-time-display {
-    -webkit-user-select: none;
-    display: -webkit-flex;
-    -webkit-flex: 0 0;
-    -webkit-justify-content: center;
-    -webkit-align-items: center;
-    cursor: default;
-    font: -webkit-small-control;
-    font-size: 9px;
-    overflow: hidden;
-    width: 45px;
-    min-width: 45px;
-    color: white;
-    text-shadow: black 0px 1px 1px;
-
-    letter-spacing: normal;
-    word-spacing: normal;
-    line-height: normal;
-    text-transform: none;
-    text-indent: 0;
-    text-decoration: none;
-}
-
-audio::-webkit-media-controls-time-remaining-display, video::-webkit-media-controls-time-remaining-display {
-    -webkit-user-select: none;
-    display: -webkit-flex;
-    -webkit-flex: 0 0;
-    -webkit-justify-content: center;
-    -webkit-align-items: center;
-    cursor: default;
-    font: -webkit-small-control;
-    font-size: 9px;
-    overflow: hidden;
-    width: 45px;
-    min-width: 45px;
-    color: white;
-    text-shadow: black 0px 1px 1px;
-
-    letter-spacing: normal;
-    word-spacing: normal;
-    line-height: normal;
-    text-transform: none;
-    text-indent: 0;
-    text-decoration: none;
-}
-
-audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
-    display: -webkit-flex;
-    -webkit-flex: 1 1;
-    height: 13px;
-    padding: 0px;
-    margin: 0px;
-    margin-top: 2px;
-}
-
-audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button {
-    display: none;
-    width: 0px;
-    border: none !important;
-}
-
-audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button {
-    display: none;
-    width: 0px;
-    border: none !important;
-}
-
-audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button {
-    width: 16px;
-    height: 16px;
-    margin-left: 7px;
-    margin-right: 7px;
-    -webkit-order: 4; /* At the very end */
-    border: none !important;
-}
-
-audio::-webkit-media-controls-rewind-button, video::-webkit-media-controls-rewind-button {
-    display: -webkit-flex;
-    -webkit-appearance: media-rewind-button;
-    width: 18px;
-    height: 18px;
-    margin-bottom: 1px;
-    margin-left: 6px;
-    margin-right: 2px;
-    border: none !important;
-}
-
-audio::-webkit-media-controls-return-to-realtime-button, video::-webkit-media-controls-return-to-realtime-button {
-    display: none;
-    -webkit-appearance: media-return-to-realtime-button;
-    width: 16px;
-    height: 11px;
-    margin-left: 6px;
-    margin-right: 2px;
-    border: none !important;
-}
-
-audio::-webkit-media-controls-status-display, video::-webkit-media-controls-status-display {
-    -webkit-user-select: none;
-    cursor: default;
-    display: -webkit-flex;
-    -webkit-flex: 1 1;
-    font: -webkit-small-control;
-    color: white;
-    font-size: 10px;
-    line-height: 13px;
-    overflow: hidden;
-    text-shadow: black 0px 1px 1px;
-    margin-left: 10px;
-    margin-right: 10px;
-
-    letter-spacing: normal;
-    word-spacing: normal;
-    line-height: normal;
-    text-transform: none;
-    text-indent: 0;
-    text-decoration: none;
-}
-
-audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container {
-    -webkit-appearance: media-volume-slider-container;
-    position: absolute;
-
-    bottom: 0px;
-    z-index: 2;
-
-    width: 22px;
-    height: 114px;
-}
-
-audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider {
-    -webkit-appearance: media-volume-slider;
-    display: inline;
-    position: absolute;
-
-    top: 7px;
-    left: 6px;
-
-    width: 10px;
-    height: 80px;
-}
-
-audio::-webkit-media-controls-volume-slider-mute-button, video::-webkit-media-controls-volume-slider-mute-button {
-    -webkit-appearance: media-volume-slider-mute-button;
-    display: inline;
-
-    position: absolute;
-
-    bottom: 7px;
-    left: 0px;
-
-    width: 14px;
-    height: 12px;
-
-    margin-left: 2px;
-    margin-right: 9px;
-
-    border: none !important;
-}
-
-video::-webkit-media-controls-toggle-closed-captions-button {
-    -webkit-appearance: media-toggle-closed-captions-button;
-    display: -webkit-flex;
-    width: 16px;
-    height: 16px;
-    margin-left: 7px;
-    margin-right: 7px;
-    -webkit-order: 3; /* between mute and fullscreen */
-    border: none !important;
-    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 102 105"><path fill="rgb(224,224,224)" d="M98.766,43.224c0-23.163-21.775-41.94-48.637-41.94c-26.859,0-48.635,18.777-48.635,41.94c0,18.266,13.546,33.796,32.444,39.549c1.131,8.356,26.037,24.255,22.864,19.921c-4.462-6.096-5.159-13.183-5.07-17.566C77.85,84.397,98.766,65.923,98.766,43.224z"/></svg>');
-    background-repeat: no-repeat;
-    background-size: 16px 16px;
-}
-
-video::-webkit-media-controls-closed-captions-container {
-    -webkit-appearance: media-closed-captions-container;
-    position: absolute;
-    display: block;
-    right: 38px;
-    bottom: 29px;
-    max-width: -webkit-calc(100% - 48px); /* right + 10px */
-    max-height: -webkit-calc(100% - 39px); /* bottom + 10px */
-    overflow-x: hidden;
-    overflow-y: scroll;
-    background-color: rgba(0, 0, 0, 0.85);
-    border: 3px solid rgba(128, 128, 128, 0.75);
-    border-radius: 10px;
-    cursor: default;
-    z-index: 2;
-    text-align: initial;
-}
-
-video::-webkit-media-controls-closed-captions-track-list {
-    display: block;
-    font-family: "Helvetica Bold", Helvetica;
-    font-size: 10pt;
-    -webkit-user-select: none;
-}
-
-video::-webkit-media-controls-closed-captions-track-list h3 {
-    margin: 0;
-    color: #757575;
-    text-shadow: 0 1px 0 black;
-    -webkit-margin-start: 23px;
-    padding-top: 4px;
-    font-weight: bold;
-    font-size: 10pt;
-}
-
-video::-webkit-media-controls-closed-captions-track-list ul {
-    list-style-type: none;
-    margin: 0 0 4px 0;
-    padding: 0;
-    font-weight: bold;
-}
-
-video::-webkit-media-controls-closed-captions-track-list li {
-    position: relative;
-    color: white;
-    background-image: none;
-    text-shadow: 0 1px 0 black;
-    margin: 0;
-    padding-left: 37px;
-    padding-right: 35px;
-    padding-top: 0.15em;
-    padding-bottom: 0.2em;
-    box-sizing: border-box;
-    overflow: hidden;
-    white-space: nowrap;
-    text-overflow: ellipsis;
-    border-top: 1px solid rgba(0, 0, 0, 0);
-    border-bottom: 1px solid rgba(0, 0, 0, 0);
-}
-
-video::-webkit-media-controls-closed-captions-track-list li:hover {
-    background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #4f70f6), color-stop(1, #1a44f3));
-    border-top: 1px solid #4667ea;
-    border-bottom: 1px solid #0336e5;
-}
-
-video::-webkit-media-controls-closed-captions-track-list li.selected::before {
-    display: block;
-    content: "";
-    position: absolute;
-    top: 0.25em;
-    width: 1.1em;
-    height: 1.1em;
-    -webkit-margin-start: -20px;
-    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="#a3a3a3" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>');
-    background-repeat: no-repeat;
-}
-
-video::-webkit-media-controls-closed-captions-track-list li.selected:hover::before {
-    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"><polygon fill="white" points="252.301,4.477 126.667,194.104 43.358,108.3 6.868,161.408 132.515,290.814 297.732,49.926"/></svg>');
-}
index b59a29e..bb3969a 100644 (file)
@@ -45,7 +45,6 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "ExceptionCodePlaceholder.h"
-#include "Frame.h"
 #include "FrameLoader.h"
 #include "FrameLoaderClient.h"
 #include "FrameView.h"
 #include "HTMLNames.h"
 #include "HTMLSourceElement.h"
 #include "HTMLVideoElement.h"
+#include "JSHTMLMediaElement.h"
 #include "Language.h"
 #include "Logging.h"
+#include "MainFrame.h"
 #include "MediaController.h"
 #include "MediaControls.h"
 #include "MediaDocument.h"
 #include "Page.h"
 #include "PageActivityAssertionToken.h"
 #include "PageGroup.h"
+#include "RenderTheme.h"
 #include "RenderVideo.h"
 #include "RenderView.h"
 #include "ScriptController.h"
+#include "ScriptSourceCode.h"
 #include "SecurityPolicy.h"
 #include "Settings.h"
 #include "ShadowRoot.h"
 #include "AudioSessionManager.h"
 #endif
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+#include "JSMediaControlsHost.h"
+#include "MediaControlsHost.h"
+#include "ScriptObject.h"
+#include "UserAgentScripts.h"
+#endif
+
 using namespace std;
 
 namespace WebCore {
@@ -573,6 +583,9 @@ RenderElement* HTMLMediaElement::createRenderer(RenderArena& arena, RenderStyle&
 
 bool HTMLMediaElement::childShouldCreateRenderer(const Node* child) const
 {
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return hasShadowRootParent(child) && HTMLElement::childShouldCreateRenderer(child);
+#else
     if (!hasMediaControls())
         return false;
     // <media> doesn't allow its content, including shadow subtree, to
@@ -582,6 +595,7 @@ bool HTMLMediaElement::childShouldCreateRenderer(const Node* child) const
     return mediaControls()->treeScope() == child->treeScope()
         && hasShadowRootParent(child)
         && HTMLElement::childShouldCreateRenderer(child);
+#endif
 }
 
 Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint)
@@ -4505,6 +4519,10 @@ bool HTMLMediaElement::closedCaptionsVisible() const
 #if ENABLE(VIDEO_TRACK)
 void HTMLMediaElement::updateTextTrackDisplay()
 {
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    ensureUserAgentShadowRoot();
+    return;
+#endif
     if (!hasMediaControls() && !createMediaControls())
         return;
     
@@ -4634,11 +4652,19 @@ void HTMLMediaElement::privateBrowsingStateDidChange()
 
 MediaControls* HTMLMediaElement::mediaControls() const
 {
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return 0;
+#else
     return toMediaControls(userAgentShadowRoot()->firstChild());
+#endif
 }
 
 bool HTMLMediaElement::hasMediaControls() const
 {
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return false;
+#else
+
     if (ShadowRoot* userAgent = userAgentShadowRoot()) {
         Node* node = userAgent->firstChild();
         ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isMediaControls());
@@ -4646,10 +4672,15 @@ bool HTMLMediaElement::hasMediaControls() const
     }
 
     return false;
+#endif
 }
 
 bool HTMLMediaElement::createMediaControls()
 {
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    ensureUserAgentShadowRoot();
+    return false;
+#else
     if (hasMediaControls())
         return true;
 
@@ -4668,11 +4699,18 @@ bool HTMLMediaElement::createMediaControls()
         mediaControls->hide();
 
     return true;
+#endif
 }
 
 void HTMLMediaElement::configureMediaControls()
 {
-#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    if (!controls() || !inDocument())
+        return;
+
+    ensureUserAgentShadowRoot();
+    return;
+#elif !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
     if (!controls() || !inDocument()) {
         if (hasMediaControls())
             mediaControls()->hide();
@@ -4683,7 +4721,7 @@ void HTMLMediaElement::configureMediaControls()
         return;
 
     mediaControls()->show();
-#else
+#else 
     if (m_player)
         m_player->setControls(controls());
 
@@ -4718,6 +4756,14 @@ void HTMLMediaElement::configureTextTrackDisplay(TextTrackVisibilityCheckType ch
     m_haveVisibleTextTrack = haveVisibleTextTrack;
     m_closedCaptionsVisible = m_haveVisibleTextTrack;
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    if (!m_haveVisibleTextTrack)
+        return;
+
+    ensureUserAgentShadowRoot();
+    return;
+#endif
+
     if (!m_haveVisibleTextTrack && !hasMediaControls())
         return;
     if (!hasMediaControls() && !createMediaControls())
@@ -5120,5 +5166,85 @@ void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
     m_restrictions = NoRestrictions;
 }
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+DOMWrapperWorld* HTMLMediaElement::ensureIsolatedWorld()
+{
+    if (!m_isolatedWorld)
+        m_isolatedWorld = DOMWrapperWorld::create(JSDOMWindow::commonVM());
+    return m_isolatedWorld.get();
 }
+
+bool HTMLMediaElement::ensureMediaControlsInjectedScript()
+{
+    Page* page = document().page();
+    if (!page)
+        return false;
+
+    String mediaControlsScript = RenderTheme::themeForPage(page)->mediaControlsScript();
+    if (!mediaControlsScript.length())
+        return false;
+
+    DOMWrapperWorld* world = ensureIsolatedWorld();
+    ScriptController& scriptController = page->mainFrame().script();
+    JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
+    JSC::ExecState* exec = globalObject->globalExec();
+
+    JSC::JSValue overlayValue = globalObject->get(exec, JSC::Identifier(exec, "createControls"));
+    if (overlayValue.isFunction())
+        return true;
+
+    scriptController.evaluateInWorld(ScriptSourceCode(mediaControlsScript), world);
+    if (exec->hadException()) {
+        exec->clearException();
+        return false;
+    }
+
+    return true;
+}
+
+void HTMLMediaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
+{
+    Page* page = document().page();
+    if (!page)
+        return;
+
+    DOMWrapperWorld* world = ensureIsolatedWorld();
+    if (!world)
+        return;
+
+    if (!ensureMediaControlsInjectedScript())
+        return;
+
+    ScriptController& scriptController = page->mainFrame().script();
+    JSDOMGlobalObject* globalObject = JSC::jsCast<JSDOMGlobalObject*>(scriptController.globalObject(world));
+    JSC::ExecState* exec = globalObject->globalExec();
+    JSC::JSLockHolder lock(exec);
+
+    // It is expected the JS file provides a createControls(shadowRoot, video, mediaControlsHost) function.
+    JSC::JSValue overlayValue = globalObject->get(exec, JSC::Identifier(exec, "createControls"));
+    if (overlayValue.isUndefinedOrNull())
+        return;
+
+    if (!m_mediaControlsHost)
+        m_mediaControlsHost = MediaControlsHost::create(this);
+
+    JSC::MarkedArgumentBuffer argList;
+    argList.append(toJS(exec, globalObject, root));
+    argList.append(toJS(exec, globalObject, this));
+    argList.append(toJS(exec, globalObject, m_mediaControlsHost.get()));
+
+    JSC::JSObject* overlay = overlayValue.toObject(exec);
+    JSC::CallData callData;
+    JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData);
+    if (callType == JSC::CallTypeNone)
+        return;
+
+    JSC::call(exec, overlay, callType, callData, globalObject, argList);
+    if (exec->hadException())
+        exec->clearException();
+}
+#endif
+
+}
+
 #endif
index cf6e896..90b1bff 100644 (file)
@@ -48,6 +48,8 @@
 #include "VideoTrack.h"
 #endif
 
+
+
 namespace WebCore {
 
 #if USE(AUDIO_SESSION)
@@ -63,6 +65,7 @@ class HTMLTrackElement;
 class KURL;
 class MediaController;
 class MediaControls;
+class MediaControlsHost;
 class MediaError;
 class PageActivityAssertionToken;
 class TimeRanges;
@@ -622,6 +625,12 @@ private:
     bool shouldDisableSleep() const;
 #endif
 
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    virtual void didAddUserAgentShadowRoot(ShadowRoot*) OVERRIDE;
+    DOMWrapperWorld* ensureIsolatedWorld();
+    bool ensureMediaControlsInjectedScript();
+#endif
+
     Timer<HTMLMediaElement> m_loadTimer;
     Timer<HTMLMediaElement> m_progressEventTimer;
     Timer<HTMLMediaElement> m_playbackProgressTimer;
@@ -774,6 +783,11 @@ private:
 
     OwnPtr<PageActivityAssertionToken> m_activityToken;
     size_t m_reportedExtraMemoryCost;
+
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    RefPtr<MediaControlsHost> m_mediaControlsHost;
+    RefPtr<DOMWrapperWorld> m_isolatedWorld;
+#endif
 };
 
 #if ENABLE(VIDEO_TRACK)
index e590f32..4286cce 100644 (file)
@@ -67,6 +67,8 @@ bool RenderTextTrackCue::initializeLayoutParameters(InlineFlowBox*& firstLineBox
 
     RenderBlock* parentBlock = containingBlock();
     firstLineBox = toRenderInline(firstChild())->firstLineBox();
+    if (!firstLineBox)
+        firstLineBox = this->firstLineBox();
 
     // 1. Horizontal: Let step be the height of the first line box in boxes.
     //    Vertical: Let step be the width of the first line box in boxes.
index 19e2b2f..b3d2fbc 100644 (file)
@@ -91,7 +91,9 @@ public:
     virtual String extraQuirksStyleSheet() { return String(); }
     virtual String extraPlugInsStyleSheet() { return String(); }
 #if ENABLE(VIDEO)
+    virtual String mediaControlsStyleSheet() { return String(); }
     virtual String extraMediaControlsStyleSheet() { return String(); }
+    virtual String mediaControlsScript() { return String() ; }
 #endif
 #if ENABLE(FULLSCREEN_API)
     virtual String extraFullScreenStyleSheet() { return String(); }
index 306eb84..69a660f 100644 (file)
@@ -107,33 +107,9 @@ protected:
     virtual ~RenderThemeMac();
 
 #if ENABLE(VIDEO)
-    virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaRewindButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaTimeRemaining(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaFullScreenVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-    virtual bool paintMediaFullScreenVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
     // Media controls
-    virtual String extraMediaControlsStyleSheet();
-#if ENABLE(FULLSCREEN_API)
-    virtual String extraFullScreenStyleSheet();
-#endif
-
-    virtual bool usesMediaControlStatusDisplay() { return true; }
-    virtual void adjustMediaSliderThumbSize(RenderStyle*) const;
-    virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const OVERRIDE;
+    virtual String mediaControlsStyleSheet() OVERRIDE;
+    virtual String mediaControlsScript() OVERRIDE;
 #endif
     virtual bool supportsSelectionForegroundColors() const { return false; }
 
index 9df980f..3341c7e 100644 (file)
@@ -56,6 +56,7 @@
 #import "StyleResolver.h"
 #import "ThemeMac.h"
 #import "TimeRanges.h"
+#import "UserAgentScripts.h"
 #import "UserAgentStyleSheets.h"
 #import "WebCoreNSCellExtras.h"
 #import "WebCoreSystemInterface.h"
@@ -183,296 +184,22 @@ NSView* RenderThemeMac::documentViewFor(RenderObject* o) const
 }
 
 #if ENABLE(VIDEO)
-
-void RenderThemeMac::adjustMediaSliderThumbSize(RenderStyle* style) const
-{
-    int wkPart;
-    switch (style->appearance()) {
-    case MediaSliderThumbPart:
-        wkPart = MediaSliderThumb;
-        break;
-    case MediaVolumeSliderThumbPart:
-        wkPart = MediaVolumeSliderThumb;
-        break;
-    case MediaFullScreenVolumeSliderThumbPart:
-        wkPart = MediaFullScreenVolumeSliderThumb;
-        break;
-    default:
-        return;
-    }
-
-    CGSize size;
-    wkMeasureMediaUIPart(wkPart, NULL, &size);
-    int width = size.width;
-    int height = size.height;
-
-    float zoomLevel = style->effectiveZoom();
-    style->setWidth(Length(static_cast<int>(width * zoomLevel), Fixed));
-    style->setHeight(Length(static_cast<int>(height * zoomLevel), Fixed));
-}
-
-enum WKMediaControllerThemeState {
-    MediaUIPartDisabledFlag = 1 << 0,
-    MediaUIPartPressedFlag = 1 << 1,
-    MediaUIPartDrawEndCapsFlag = 1 << 3,
-};
-
-static unsigned getMediaUIPartStateFlags(Node* node)
-{
-    unsigned flags = 0;
-
-    if (isDisabledFormControl(node))
-        flags |= MediaUIPartDisabledFlag;
-    else if (node->isElementNode() && toElement(node)->active())
-        flags |= MediaUIPartPressedFlag;
-    return flags;
-}
-
-// Utility to scale when the UI part are not scaled by wkDrawMediaUIPart
-static FloatRect getUnzoomedRectAndAdjustCurrentContext(RenderObject* o, const PaintInfo& paintInfo, const IntRect &originalRect)
-{
-    float zoomLevel = o->style()->effectiveZoom();
-    FloatRect unzoomedRect(originalRect);
-    if (zoomLevel != 1.0f) {
-        unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
-        unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
-        paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
-        paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
-        paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
-    }
-    return unzoomedRect;
-}
-
-bool RenderThemeMac::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
+String RenderThemeMac::mediaControlsStyleSheet()
 {
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    if (node->isMediaControlElement()) {
-        LocalCurrentGraphicsContext localContext(paintInfo.context);
-        wkDrawMediaUIPart(mediaControlElementType(node), localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    }
-    return false;
-}
-
-bool RenderThemeMac::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    Node* mediaNode = node ? node->shadowHost() : 0;
-    if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !isHTMLAudioElement(mediaNode)))
-        return false;
-
-    if (node->isMediaControlElement()) {
-        LocalCurrentGraphicsContext localContext(paintInfo.context);
-        wkDrawMediaUIPart(mediaControlElementType(node), localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    }
-    return false;
-}
-
-bool RenderThemeMac::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    Node* mediaNode = node ? node->shadowHost() : 0;
-    if (!mediaNode || (!mediaNode->hasTagName(videoTag) && !isHTMLAudioElement(mediaNode)))
-        return false;
-
-    if (node->isMediaControlElement()) {
-        LocalCurrentGraphicsContext localContext(paintInfo.context);
-        wkDrawMediaUIPart(mediaControlElementType(node), localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    }
-    return false;
-}
-
-bool RenderThemeMac::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaSeekBackButton, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaSeekForwardButton, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    Element* mediaNode = node ? node->shadowHost() : 0;
-    if (!mediaNode || !mediaNode->isMediaElement())
-        return false;
-
-    HTMLMediaElement* mediaElement = toHTMLMediaElement(mediaNode);
-    if (!mediaElement)
-        return false;
-
-    RefPtr<TimeRanges> timeRanges = mediaElement->buffered();
-    float timeLoaded = timeRanges->length() ? timeRanges->end(0, IGNORE_EXCEPTION) : 0;
-    float currentTime = mediaElement->currentTime();
-    float duration = mediaElement->duration();
-    if (std::isnan(duration))
-        duration = 0;
-
-    ContextContainer cgContextContainer(paintInfo.context);
-    CGContextRef context = cgContextContainer.context();
-    GraphicsContextStateSaver stateSaver(*paintInfo.context);
-    FloatRect unzoomedRect = getUnzoomedRectAndAdjustCurrentContext(o, paintInfo, r);
-    wkDrawMediaSliderTrack(context, unzoomedRect,
-        timeLoaded, currentTime, duration, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaSliderThumb, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaRewindButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaRewindButton, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaReturnToRealtimeButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaReturnToRealtimeButton, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaControlsBackground(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaTimelineContainer, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaCurrentTime(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    ContextContainer cgContextContainer(paintInfo.context);
-    GraphicsContextStateSaver stateSaver(*paintInfo.context);
-    FloatRect unzoomedRect = getUnzoomedRectAndAdjustCurrentContext(o, paintInfo, r);
-    wkDrawMediaUIPart(MediaCurrentTimeDisplay, cgContextContainer.context(), unzoomedRect, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaTimeRemaining(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    ContextContainer cgContextContainer(paintInfo.context);
-    GraphicsContextStateSaver stateSaver(*paintInfo.context);
-    FloatRect unzoomedRect = getUnzoomedRectAndAdjustCurrentContext(o, paintInfo, r);
-    wkDrawMediaUIPart(MediaTimeRemainingDisplay, cgContextContainer.context(), unzoomedRect, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaVolumeSliderContainer(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaVolumeSliderContainer, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaVolumeSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaVolumeSlider, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaVolumeSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaVolumeSliderThumb, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaFullScreenVolumeSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaFullScreenVolumeSlider, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-bool RenderThemeMac::paintMediaFullScreenVolumeSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    Node* node = o->node();
-    if (!node)
-        return false;
-
-    LocalCurrentGraphicsContext localContext(paintInfo.context);
-    wkDrawMediaUIPart(MediaFullScreenVolumeSliderThumb, localContext.cgContext(), r, getMediaUIPartStateFlags(node));
-    return false;
-}
-
-String RenderThemeMac::extraMediaControlsStyleSheet()
-{
-    return String(mediaControlsQuickTimeUserAgentStyleSheet, sizeof(mediaControlsQuickTimeUserAgentStyleSheet));
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return String(mediaControlsAppleUserAgentStyleSheet, sizeof(mediaControlsAppleUserAgentStyleSheet));
+#else
+    return emptyString();
+#endif
 }
 
-#if ENABLE(FULLSCREEN_API)
-String RenderThemeMac::extraFullScreenStyleSheet()
+String RenderThemeMac::mediaControlsScript()
 {
-    return String(fullscreenQuickTimeUserAgentStyleSheet, sizeof(fullscreenQuickTimeUserAgentStyleSheet));
-}
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return String(mediaControlsAppleJavaScript, sizeof(mediaControlsAppleJavaScript));
+#else
+    return emptyString();
 #endif
-
-IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
-{
-    return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
 }
 
 #endif // ENABLE(VIDEO)
@@ -2131,10 +1858,6 @@ void RenderThemeMac::adjustSliderThumbSize(RenderStyle* style, Element*) const
         style->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
         style->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
     }
-
-#if ENABLE(VIDEO)
-    adjustMediaSliderThumbSize(style);
-#endif
 }
 
 bool RenderThemeMac::shouldShowPlaceholderWhenFocused() const
index 35f2642..90f44f9 100644 (file)
@@ -1075,89 +1075,23 @@ Color RenderThemeWin::systemColor(CSSValueID cssValueId) const
 }
 
 #if ENABLE(VIDEO)
-
-String RenderThemeWin::extraMediaControlsStyleSheet()
-{
-    return String(mediaControlsQuickTimeUserAgentStyleSheet, sizeof(mediaControlsQuickTimeUserAgentStyleSheet));
-}
-
-#if ENABLE(FULLSCREEN_API)
-String RenderThemeWin::extraFullScreenStyleSheet()
+String RenderThemeWin::mediaControlsStyleSheet()
 {
-    return String(fullscreenQuickTimeUserAgentStyleSheet, sizeof(fullscreenQuickTimeUserAgentStyleSheet));
-}
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return String(mediaControlsAppleUserAgentStyleSheet, sizeof(mediaControlsAppleUserAgentStyleSheet));
+#else
+    return emptyString();
 #endif
-
-bool RenderThemeWin::supportsClosedCaptioning() const
-{
-    return true;
-}
-
-bool RenderThemeWin::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaEnterFullscreenButton, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaRewindButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaRewindButton, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaSeekBackButton, o, paintInfo, r);
 }
 
-bool RenderThemeWin::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
+String RenderThemeWin::mediaControlsScript()
 {
-    return RenderMediaControls::paintMediaControlsPart(MediaSeekForwardButton, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaSlider, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaControlsBackground(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaTimelineContainer, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaVolumeSliderContainer(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaVolumeSliderContainer, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaVolumeSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaVolumeSlider, o, paintInfo, r);
-}
-
-bool RenderThemeWin::paintMediaVolumeSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    return RenderMediaControls::paintMediaControlsPart(MediaVolumeSliderThumb, o, paintInfo, r);
-}
-
-IntPoint RenderThemeWin::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
-{
-    return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButtonBox, size);
+#if ENABLE(MEDIA_CONTROLS_SCRIPT)
+    return String(mediaControlsAppleJavaScript, sizeof(mediaControlsAppleJavaScript));
+#else
+    return emptyString();
+#endif
 }
-
 #endif
 
 #if ENABLE(METER_ELEMENT)
index 96bb63b..d032843 100644 (file)
@@ -123,24 +123,8 @@ public:
     virtual bool supportsFocusRing(const RenderStyle*) const;
 
 #if ENABLE(VIDEO)
-    virtual String extraMediaControlsStyleSheet();
-#if ENABLE(FULLSCREEN_API)
-    virtual String extraFullScreenStyleSheet();
-#endif
-    virtual bool supportsClosedCaptioning() const;
-    virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaRewindButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
-    virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const OVERRIDE;
+    virtual String mediaControlsStyleSheet() OVERRIDE;
+    virtual String mediaControlsScript() OVERRIDE;
 #endif
 
 #if ENABLE(METER_ELEMENT)
index b11017a..7dfafe9 100644 (file)
@@ -1,3 +1,14 @@
+2013-09-06  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2013-09-27  Darin Adler  <darin@apple.com>
 
         Add empty MainFrame class
index 6546430..e91b1f6 100644 (file)
@@ -129,6 +129,7 @@ ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
 ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
 ENABLE_LINK_PREFETCH = ;
 ENABLE_MATHML = ENABLE_MATHML;
+ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
 ENABLE_MEDIA_SOURCE = ;
 ENABLE_MEDIA_STATISTICS = ;
 ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
@@ -187,4 +188,4 @@ ENABLE_XSLT = ENABLE_XSLT;
 
 ENABLE_FTL_JIT = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
index 3008880..324a16c 100644 (file)
@@ -1,3 +1,14 @@
+2013-09-06  Jer Noble  <jer.noble@apple.com>
+
+        [Mac] Implement the media controls in JavaScript.
+        https://bugs.webkit.org/show_bug.cgi?id=120895
+
+        Reviewed by Dean Jackson.
+
+        Define and turn on ENABLE_MEDIA_CONTROLS_SCRIPT.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2013-09-27  Darin Adler  <darin@apple.com>
 
         Add empty MainFrame class
index 6546430..e91b1f6 100644 (file)
@@ -129,6 +129,7 @@ ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
 ENABLE_LEGACY_WEB_AUDIO = ENABLE_LEGACY_WEB_AUDIO;
 ENABLE_LINK_PREFETCH = ;
 ENABLE_MATHML = ENABLE_MATHML;
+ENABLE_MEDIA_CONTROLS_SCRIPT = ENABLE_MEDIA_CONTROLS_SCRIPT;
 ENABLE_MEDIA_SOURCE = ;
 ENABLE_MEDIA_STATISTICS = ;
 ENABLE_METER_ELEMENT = ENABLE_METER_ELEMENT;
@@ -187,4 +188,4 @@ ENABLE_XSLT = ENABLE_XSLT;
 
 ENABLE_FTL_JIT = ;
 
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));
+FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_BLOB) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_TRANSFORMS_ANIMATIONS_UNPREFIXED) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_CONDITIONAL_RULES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PLUGIN_PROXY_FOR_VIDEO) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SUBPIXEL_LAYOUT) $(ENABLE_SVG) $(ENABLE_SVG_FONTS) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_THREADED_HTML_PARSER) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(FEATURE_DEFINES_$(PLATFORM_NAME));