2009-08-25 Eric Carlson <eric.carlson@apple.com>
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Aug 2009 23:07:19 +0000 (23:07 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Aug 2009 23:07:19 +0000 (23:07 +0000)
        Reviewed by Oliver Hunt.

        <video> and <audio> controller should be accessible (edit)
        https://bugs.webkit.org/show_bug.cgi?id=28081

        Test: accessibility/media-element.html

        * GNUmakefile.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
            Add AccessibilityMediaControls.cpp/.h

        * accessibility/AXObjectCache.cpp:
        * accessibility/AXObjectCache.h:
        (WebCore::AXObjectCache::getOrCreate):
            Create AccessibilityMediaControl. Update Copyright

        * accessibility/AccessibilityMediaControls.cpp:
        * accessibility/AccessibilityMediaControls.h:
            Added.

        * accessibility/AccessibilityObject.cpp:
        * accessibility/AccessibilityObject.h:
            Add isMediaTimeline. Update Copyright.

        * accessibility/AccessibilitySlider.h:
            Make constructor protected instead of private so AccessibilityMediaTimeline can
            call it.

        * accessibility/mac/AccessibilityObjectWrapper.mm:
        (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
            Add NSAccessibilityValueDescriptionAttribute to range attributes.
        (-[AccessibilityObjectWrapper subrole]):
            Return NSAccessibilityTimelineSubrole for AccessibilityMediaTimeline.

        * dom/Node.h:
            add isMediaControlElement.

        * page/mac/WebCoreViewFactory.h:
        * platform/LocalizedStrings.h:
        * platform/mac/LocalizedStringsMac.mm:
        (WebCore::localizedMediaControlElementString):
        (WebCore::localizedMediaControlElementHelpText):
        (WebCore::localizedMediaTimeDescription):
            New, return localized media controller strings.

        * platform/gtk/LocalizedStringsGtk.cpp:
        (WebCore::mediaElementLoadingStateText):
        (WebCore::mediaElementLiveBroadcastStateText):
            Move inside of "#if ENABLE(VIDEO)"
        (WebCore::localizedMediaControlElementString):
        (WebCore::localizedMediaControlElementHelpText):
        (WebCore::localizedMediaTimeDescription):

        * rendering/MediaControlElements.cpp:
        (WebCore::MediaControlElement::MediaControlElement):
            Initialize m_displayType.
        (WebCore::MediaControlElement::MediaControlElement):
        (WebCore::MediaControlStatusDisplayElement::MediaControlStatusDisplayElement):
            Fix style.
        (WebCore::MediaControlInputElement::MediaControlInputElement):
            Set m_displayType based on pseudo style ID.
        (WebCore::MediaControlInputElement::MediaControlInputElement):
            rename local "o" to "object".
        (WebCore::MediaControlMuteButtonElement::MediaControlMuteButtonElement):
        (WebCore::MediaControlPlayButtonElement::MediaControlPlayButtonElement):
        (WebCore::MediaControlSeekButtonElement::MediaControlSeekButtonElement):
        (WebCore::MediaControlRewindButtonElement::MediaControlRewindButtonElement):
        (WebCore::MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement):
        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
        (WebCore::MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement):
        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
            Update for MediaControlInputElement constructor change.
        (WebCore::MediaControlTimeDisplayElement::formatTime):
            New, moved here from RenderMedia so AccessibilityMediaTimeDisplay can use it.
        (WebCore::MediaControlTimeDisplayElement::setCurrentValue):
            New, set text to current time.
        * rendering/MediaControlElements.h:

        * rendering/RenderMedia.cpp:
        (WebCore::RenderMedia::updateControls):
            Create controls in tab order.
        (WebCore::RenderMedia::formatTime):
            Moved to MediaControlTimeDisplayElement::formatTime.
        (WebCore::RenderMedia::updateTimeDisplay):
            Call MediaControlTimeDisplayElement::setCurrentValue.
        * rendering/RenderMedia.h:

2009-08-25  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Oliver Hunt.

        <video> and <audio> controller should be accessible
        https://bugs.webkit.org/show_bug.cgi?id=28081

        Add localized strings for media controller accessiblility.

        * English.lproj/Localizable.strings:

2009-08-25  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Oliver Hunt.

        <video> and <audio> controller should be accessible
        https://bugs.webkit.org/show_bug.cgi?id=28081

        * WebCoreSupport/WebViewFactory.mm:
        (-[WebViewFactory localizedMediaControlElementString:]):
        (-[WebViewFactory localizedMediaControlElementHelpText:]):
        (-[WebViewFactory localizedMediaTimeDescription:]):
            New.

2009-08-25  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Oliver Hunt.

        <video> and <audio> controller should be accessible
        https://bugs.webkit.org/show_bug.cgi?id=28081

        * WebCoreLocalizedStrings.cpp:
        (WebCore::localizedMediaControlElementString):
        (WebCore::localizedMediaControlElementHelpText):
        (WebCore::localizedMediaTimeDescription):
            New.

2009-08-25  Eric Carlson  <eric.carlson@apple.com>

        Reviewed by Oliver Hunt.

        <video> and <audio> controller should be accessible
        https://bugs.webkit.org/show_bug.cgi?id=28081

        * accessibility/media-element.html: Added.
        * platform/mac/accessibility/media-element-expected.txt: Added.
        * media/video-controls-visible-audio-only.html:
        * platform/mac-leopard/accessibility/media-element-expected.txt: Added.
        * platform/mac-leopard/media/controls-drag-timebar-expected.txt: Added.
        * platform/mac-leopard/media/controls-strict-expected.txt: Added.
        * platform/mac-leopard/media/video-controls-rendering-expected.txt: Added.
        * platform/mac-leopard/media/video-display-toggle-expected.txt: Added.
        * platform/win/media/controls-strict-expected.txt: Added.
        * platform/win/media/video-controls-rendering-expected.txt: Added.
        * platform/win/media/video-display-toggle-expected.txt: Added.
            Added.

        * platform/mac-leopard/media/audio-controls-rendering-expected.txt:
        * platform/mac-leopard/media/controls-after-reload-expected.txt:
        * platform/mac-leopard/media/controls-styling-expected.txt:
        * platform/mac-leopard/media/video-zoom-controls-expected.txt:
        * platform/mac/media/audio-controls-rendering-expected.txt:
        * platform/mac/media/controls-after-reload-expected.txt:
        * platform/mac/media/controls-styling-expected.txt:
        * platform/mac/media/video-zoom-controls-expected.txt:
        * platform/win/media/audio-controls-rendering-expected.txt:
        * platform/win/media/controls-after-reload-expected.txt:
        * platform/win/media/controls-drag-timebar-expected.txt:
        * platform/win/media/controls-styling-expected.txt:
            Update for controller element tab order change.

        * platform/gtk/Skipped:
        * platform/win/Skipped:
            Skip new test.

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

56 files changed:
LayoutTests/ChangeLog
LayoutTests/accessibility/media-element.html [new file with mode: 0644]
LayoutTests/media/video-controls-visible-audio-only.html
LayoutTests/platform/gtk/Skipped
LayoutTests/platform/mac-leopard/accessibility/media-element-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-leopard/media/audio-controls-rendering-expected.txt
LayoutTests/platform/mac-leopard/media/controls-after-reload-expected.txt
LayoutTests/platform/mac-leopard/media/controls-drag-timebar-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-leopard/media/controls-strict-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-leopard/media/controls-styling-expected.txt
LayoutTests/platform/mac-leopard/media/video-controls-rendering-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-leopard/media/video-display-toggle-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac-leopard/media/video-zoom-controls-expected.txt
LayoutTests/platform/mac/accessibility/media-element-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/media/audio-controls-rendering-expected.txt
LayoutTests/platform/mac/media/controls-after-reload-expected.txt
LayoutTests/platform/mac/media/controls-styling-expected.txt
LayoutTests/platform/mac/media/video-zoom-controls-expected.txt
LayoutTests/platform/win/Skipped
LayoutTests/platform/win/media/audio-controls-rendering-expected.txt
LayoutTests/platform/win/media/controls-after-reload-expected.txt
LayoutTests/platform/win/media/controls-drag-timebar-expected.txt
LayoutTests/platform/win/media/controls-strict-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/media/controls-styling-expected.txt
LayoutTests/platform/win/media/video-controls-rendering-expected.txt [new file with mode: 0644]
LayoutTests/platform/win/media/video-display-toggle-expected.txt [new file with mode: 0644]
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/accessibility/AXObjectCache.cpp
WebCore/accessibility/AXObjectCache.h
WebCore/accessibility/AccessibilityMediaControls.cpp [new file with mode: 0644]
WebCore/accessibility/AccessibilityMediaControls.h [new file with mode: 0644]
WebCore/accessibility/AccessibilityObject.cpp
WebCore/accessibility/AccessibilityObject.h
WebCore/accessibility/AccessibilitySlider.h
WebCore/accessibility/mac/AccessibilityObjectWrapper.mm
WebCore/dom/Node.h
WebCore/page/mac/WebCoreViewFactory.h
WebCore/platform/LocalizedStrings.h
WebCore/platform/gtk/LocalizedStringsGtk.cpp
WebCore/platform/mac/LocalizedStringsMac.mm
WebCore/rendering/MediaControlElements.cpp
WebCore/rendering/MediaControlElements.h
WebCore/rendering/RenderMedia.cpp
WebCore/rendering/RenderMedia.h
WebKit/ChangeLog
WebKit/English.lproj/Localizable.strings
WebKit/mac/ChangeLog
WebKit/mac/WebCoreSupport/WebViewFactory.mm
WebKit/win/ChangeLog
WebKit/win/WebCoreLocalizedStrings.cpp

index 36e300a..a330f51 100644 (file)
@@ -1,3 +1,41 @@
+2009-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <video> and <audio> controller should be accessible
+        https://bugs.webkit.org/show_bug.cgi?id=28081
+
+        * accessibility/media-element.html: Added.
+        * platform/mac/accessibility/media-element-expected.txt: Added.
+        * media/video-controls-visible-audio-only.html:
+        * platform/mac-leopard/accessibility/media-element-expected.txt: Added.
+        * platform/mac-leopard/media/controls-drag-timebar-expected.txt: Added.
+        * platform/mac-leopard/media/controls-strict-expected.txt: Added.
+        * platform/mac-leopard/media/video-controls-rendering-expected.txt: Added.
+        * platform/mac-leopard/media/video-display-toggle-expected.txt: Added.
+        * platform/win/media/controls-strict-expected.txt: Added.
+        * platform/win/media/video-controls-rendering-expected.txt: Added.
+        * platform/win/media/video-display-toggle-expected.txt: Added.
+            Added.
+
+        * platform/mac-leopard/media/audio-controls-rendering-expected.txt:
+        * platform/mac-leopard/media/controls-after-reload-expected.txt:
+        * platform/mac-leopard/media/controls-styling-expected.txt:
+        * platform/mac-leopard/media/video-zoom-controls-expected.txt:
+        * platform/mac/media/audio-controls-rendering-expected.txt:
+        * platform/mac/media/controls-after-reload-expected.txt:
+        * platform/mac/media/controls-styling-expected.txt:
+        * platform/mac/media/video-zoom-controls-expected.txt:
+        * platform/win/media/audio-controls-rendering-expected.txt:
+        * platform/win/media/controls-after-reload-expected.txt:
+        * platform/win/media/controls-drag-timebar-expected.txt:
+        * platform/win/media/controls-styling-expected.txt:
+            Update for controller element tab order change.
+
+        * platform/gtk/Skipped:
+        * platform/win/Skipped:
+            Skip new test.
+
 2009-08-25  Mads Ager  <ager@chromium.org>
 
         Reviewed by Adam Barth.
diff --git a/LayoutTests/accessibility/media-element.html b/LayoutTests/accessibility/media-element.html
new file mode 100644 (file)
index 0000000..f7e140f
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+    <head>
+        <link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
+        <script src="../fast/js/resources/js-test-pre.js"></script>
+        <script>
+            var vidAXObject;
+            var indentLevel = 0;
+
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+                layoutTestController.waitUntilDone();
+            }
+
+            function indent(count)
+            {
+                var spaces = "                                                      ";
+                return spaces.substr(0, count);
+            }
+
+            function dumpObject(axObject)
+            {
+                debug(indent(indentLevel) + "description: " + axObject.description); 
+                debug(indent(indentLevel) + "role: " + axObject.role); 
+                debug("<br>");
+            }
+
+            function dumpChildren(axObject)
+            {
+                var count = axObject.childrenCount
+                if (!count)
+                    return;
+
+                indentLevel += 4;
+                for (var ndx = 0; ndx < count; ndx++) {
+                    var childAXObject = axObject.childAtIndex(ndx);
+                    dumpObject(childAXObject);
+                    if (childAXObject.childrenCount) {
+                        // don't bother dumping static text children
+                        if ( childAXObject.role != "AXRole: AXStaticText")
+                           dumpChildren(childAXObject);
+                    }
+                }
+                indentLevel -= 4;
+            }
+
+            function dumpVideoAX()
+            {
+                debug("<br>+++++++++++++++++++++++++++++++++++<br>");
+                debug("State at '" + event.type + "' event:<br>");
+
+                if (!window.accessibilityController)
+                    return;
+
+                var body = document.getElementsByTagName("body")[0];
+                body.focus();
+
+                var vidAXObject = accessibilityController.focusedElement.childAtIndex(0);
+                
+                dumpChildren(vidAXObject);
+
+                if (window.layoutTestController && event.type == 'load')
+                    layoutTestController.notifyDone();     
+            }
+        </script>
+    </head>
+
+<body>
+
+    <video id=vid src="../media/content/test.mp4" controls onload="dumpVideoAX()">
+    </video>
+
+    <div>Dump &lt;video&gt; element controller accessibility object tree at 'loadstart' and 'load' events.</div>
+    
+    <div id=console></div>
+
+</body>
+</html>
+
index 055c334..73a4f8c 100644 (file)
@@ -33,7 +33,7 @@
                     return;
 
                 // start playback
-                eventSender.mouseMoveTo(left + 16 + 8, bottom - 8);
+                eventSender.mouseMoveTo(left + 8, bottom - 8);
                 eventSender.mouseDown();
                 eventSender.mouseUp();
                 testcondition("!video.paused");
index c4d1a16..1a18da0 100644 (file)
@@ -76,6 +76,7 @@ accessibility/img-aria-button-alt-tag.html
 accessibility/input-image-alt.html
 accessibility/input-slider.html
 accessibility/language-attribute.html
+accessibility/media-element.html
 accessibility/onclick-handlers.html
 accessibility/placeholder.html
 accessibility/radio-button-title-label.html
diff --git a/LayoutTests/platform/mac-leopard/accessibility/media-element-expected.txt b/LayoutTests/platform/mac-leopard/accessibility/media-element-expected.txt
new file mode 100644 (file)
index 0000000..c54bede
--- /dev/null
@@ -0,0 +1,35 @@
+Dump <video> element controller accessibility object tree at 'loadstart' and 'load' events.
+
++++++++++++++++++++++++++++++++++++
+
+State at 'load' event:
+
+    description: AXDescription: video element controller
+    role: AXRole: AXToolbar
+
+
+        description: AXDescription: play
+        role: AXRole: AXButton
+
+
+        description: AXDescription: 
+        role: AXRole: AXSlider
+
+
+            description: AXDescription: 
+            role: AXRole: AXValueIndicator
+
+
+        description: AXDescription: fast reverse
+        role: AXRole: AXButton
+
+
+        description: AXDescription: fast forward
+        role: AXRole: AXButton
+
+
+        description: AXDescription: mute
+        role: AXRole: AXButton
+
+
+
index 295d4aa..77de6be 100644 (file)
@@ -19,10 +19,10 @@ layer at (8,42) size 200x16
 layer at (8,42) size 200x16
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 200x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 136x16
+    RenderFlexibleBox {DIV} at (16,0) size 136x16
       RenderSlider {INPUT} at (0,0) size 136x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (152,0) size 16x16
     RenderButton {INPUT} at (168,0) size 16x16
     RenderButton {INPUT} at (184,0) size 16x16
 layer at (8,76) size 320x16
@@ -30,10 +30,10 @@ layer at (8,76) size 320x16
 layer at (8,76) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
 layer at (8,110) size 320x100
@@ -43,9 +43,9 @@ layer at (8,110) size 320x100
 layer at (8,194) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,84) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
index 9a8560d..923fac3 100644 (file)
@@ -17,9 +17,9 @@ layer at (8,42) size 320x240
 layer at (8,266) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
diff --git a/LayoutTests/platform/mac-leopard/media/controls-drag-timebar-expected.txt b/LayoutTests/platform/mac-leopard/media/controls-drag-timebar-expected.txt
new file mode 100644 (file)
index 0000000..3231085
--- /dev/null
@@ -0,0 +1,13 @@
+Test that drag the timebar thumb causes seeks.
+
+RUN(video.autoplay = true)
+RUN(video.src = 'content/test.mp4')
+EVENT(playing)
+EVENT(seeked)
+Time: 2.1
+EVENT(seeked)
+Time: 2.6
+EVENT(seeked)
+Time: 3.1
+END OF TEST
+
diff --git a/LayoutTests/platform/mac-leopard/media/controls-strict-expected.txt b/LayoutTests/platform/mac-leopard/media/controls-strict-expected.txt
new file mode 100644 (file)
index 0000000..5296d55
--- /dev/null
@@ -0,0 +1,25 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x302
+  RenderBlock {HTML} at (0,0) size 800x302
+    RenderBody {BODY} at (8,16) size 784x278
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 226x18
+          text run at (0,0) width 226: "Drawing the controls in strict mode."
+      RenderBlock (anonymous) at (0,34) size 784x244
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+layer at (8,50) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,50) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,274) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
index a22c31e..fd24373 100644 (file)
@@ -21,10 +21,10 @@ layer at (18,42) size 320x240
 layer at (18,266) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
 layer at (8,282) size 320x240
@@ -32,9 +32,9 @@ layer at (8,282) size 320x240
 layer at (8,506) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
diff --git a/LayoutTests/platform/mac-leopard/media/video-controls-rendering-expected.txt b/LayoutTests/platform/mac-leopard/media/video-controls-rendering-expected.txt
new file mode 100644 (file)
index 0000000..fff11e1
--- /dev/null
@@ -0,0 +1,52 @@
+layer at (0,0) size 785x762
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x600
+  RenderBlock {HTML} at (0,0) size 785x600
+    RenderBody {BODY} at (8,8) size 769x584
+      RenderBlock {P} at (0,0) size 769x18
+        RenderText {#text} at (0,0) size 153x18
+          text run at (0,0) width 153: "Test controls placement."
+      RenderBlock {DIV} at (0,34) size 769x240
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,274) size 769x240
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,514) size 769x0
+layer at (8,42) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,282) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,42) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,266) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
+layer at (8,282) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,506) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
+layer at (8,522) size 320x240
+  RenderVideo {VIDEO} at (8,522) size 320x240
+layer at (8,522) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,746) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
diff --git a/LayoutTests/platform/mac-leopard/media/video-display-toggle-expected.txt b/LayoutTests/platform/mac-leopard/media/video-display-toggle-expected.txt
new file mode 100644 (file)
index 0000000..a9baa00
--- /dev/null
@@ -0,0 +1,24 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (0,0) size 493x18
+        text run at (0,0) width 493: "This tests that toggling the display property won't make the controls disappear."
+      RenderBR {BR} at (493,14) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,26) size 320x240
+  RenderVideo {VIDEO} at (0,18) size 320x240
+layer at (8,26) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,250) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
index 62fa55b..93618ac 100644 (file)
@@ -13,10 +13,10 @@ layer at (57,85) size 240x180
 layer at (57,241) size 240x24
   RenderFlexibleBox (positioned) {DIV} at (0,156) size 240x24
     RenderButton {INPUT} at (0,0) size 24x24
-    RenderButton {INPUT} at (24,0) size 24x24
-    RenderFlexibleBox {DIV} at (48,0) size 144x24
+    RenderFlexibleBox {DIV} at (24,0) size 144x24
       RenderSlider {INPUT} at (0,0) size 144x24
         RenderBlock {DIV} at (3,1) size 19x21
+    RenderButton {INPUT} at (168,0) size 24x24
     RenderButton {INPUT} at (192,0) size 24x24
     RenderButton {INPUT} at (216,0) size 24x24
 layer at (57,310) size 240x180
@@ -26,9 +26,9 @@ layer at (57,310) size 240x180
 layer at (57,466) size 240x24
   RenderFlexibleBox (positioned) {DIV} at (0,156) size 240x24
     RenderButton {INPUT} at (0,0) size 24x24
-    RenderButton {INPUT} at (24,0) size 24x24
-    RenderFlexibleBox {DIV} at (48,0) size 144x24
+    RenderFlexibleBox {DIV} at (24,0) size 144x24
       RenderSlider {INPUT} at (0,0) size 144x24
         RenderBlock {DIV} at (3,1) size 19x21
+    RenderButton {INPUT} at (168,0) size 24x24
     RenderButton {INPUT} at (192,0) size 24x24
     RenderButton {INPUT} at (216,0) size 24x24
diff --git a/LayoutTests/platform/mac/accessibility/media-element-expected.txt b/LayoutTests/platform/mac/accessibility/media-element-expected.txt
new file mode 100644 (file)
index 0000000..7eacfba
--- /dev/null
@@ -0,0 +1,39 @@
+Dump <video> element controller accessibility object tree at 'loadstart' and 'load' events.
+
++++++++++++++++++++++++++++++++++++
+
+State at 'load' event:
+
+    description: AXDescription: video element controller
+    role: AXRole: AXToolbar
+
+
+        description: AXDescription: back 30 seconds
+        role: AXRole: AXButton
+
+
+        description: AXDescription: play
+        role: AXRole: AXButton
+
+
+        description: AXDescription: elapsed time
+        role: AXRole: AXStaticText
+
+
+        description: AXDescription: 
+        role: AXRole: AXSlider
+
+
+            description: AXDescription: 
+            role: AXRole: AXValueIndicator
+
+
+        description: AXDescription: remaining time
+        role: AXRole: AXStaticText
+
+
+        description: AXDescription: mute
+        role: AXRole: AXButton
+
+
+
index 8dbae43..9ff6c9a 100644 (file)
@@ -19,21 +19,21 @@ layer at (8,42) size 200x25
 layer at (8,42) size 200x25
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 200x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (177,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,1) size 126x22
       RenderSlider {INPUT} at (0,5) size 126x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (177,5) size 15x14
 layer at (8,85) size 320x25
   RenderBlock (relative positioned) {DIV} at (0,0) size 320x25
 layer at (8,85) size 320x25
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 320x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (297,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,5) size 246x15
       RenderSlider {INPUT} at (45,2) size 156x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (297,5) size 15x14
 layer at (57,92) size 45x11
   RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
@@ -51,11 +51,11 @@ layer at (8,128) size 320x100
 layer at (8,203) size 320x25
   RenderFlexibleBox (positioned) {DIV} at (0,75) size 320x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (297,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,5) size 246x15
       RenderSlider {INPUT} at (45,2) size 156x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (297,5) size 15x14
 layer at (57,210) size 45x11
   RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
index 41f9643..0b414ad 100644 (file)
@@ -17,11 +17,11 @@ layer at (8,42) size 320x240
 layer at (8,257) size 320x25
   RenderFlexibleBox (positioned) {DIV} at (0,215) size 320x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (297,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,5) size 246x15
       RenderSlider {INPUT} at (45,2) size 156x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (297,5) size 15x14
 layer at (57,264) size 45x11
   RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
index 0bd9cf8..06bd231 100644 (file)
@@ -21,11 +21,11 @@ layer at (18,42) size 320x240
 layer at (18,257) size 320x25
   RenderFlexibleBox (positioned) {DIV} at (0,215) size 320x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (297,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,5) size 246x15
       RenderSlider {INPUT} at (45,2) size 156x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (297,5) size 15x14
 layer at (67,264) size 45x11
   RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
@@ -41,11 +41,11 @@ layer at (8,282) size 320x240
 layer at (8,497) size 320x25
   RenderFlexibleBox (positioned) {DIV} at (0,215) size 320x25
     RenderButton {INPUT} at (6,3) size 18x18
-    RenderButton {INPUT} at (297,5) size 15x14
     RenderButton {INPUT} at (32,4) size 16x16
     RenderFlexibleBox {DIV} at (49,5) size 246x15
       RenderSlider {INPUT} at (45,2) size 156x13
         RenderBlock {DIV} at (0,1) size 12x10
+    RenderButton {INPUT} at (297,5) size 15x14
 layer at (57,504) size 45x11
   RenderFlexibleBox {DIV} at (0,2) size 45x11 [color=#FFFFFF]
     RenderBlock (anonymous) at (9,0) size 26x11
index f43dcac..1a98a6d 100644 (file)
@@ -13,11 +13,11 @@ layer at (57,85) size 240x180
 layer at (57,228) size 240x37
   RenderFlexibleBox (positioned) {DIV} at (0,143) size 240x37
     RenderButton {INPUT} at (9,4) size 27x27
-    RenderButton {INPUT} at (206,8) size 22x21
     RenderButton {INPUT} at (48,6) size 24x24
     RenderFlexibleBox {DIV} at (73,1) size 130x34
       RenderSlider {INPUT} at (0,9) size 130x19
         RenderBlock {DIV} at (0,2) size 18x15
+    RenderButton {INPUT} at (206,8) size 22x21
 layer at (57,310) size 240x180
   RenderVideo {VIDEO} at (45,298) size 240x180
 layer at (57,310) size 240x180
@@ -25,8 +25,8 @@ layer at (57,310) size 240x180
 layer at (57,453) size 240x37
   RenderFlexibleBox (positioned) {DIV} at (0,143) size 240x37
     RenderButton {INPUT} at (9,4) size 27x27
-    RenderButton {INPUT} at (206,8) size 22x21
     RenderButton {INPUT} at (48,6) size 24x24
     RenderFlexibleBox {DIV} at (73,1) size 130x34
       RenderSlider {INPUT} at (0,9) size 130x19
         RenderBlock {DIV} at (0,2) size 18x15
+    RenderButton {INPUT} at (206,8) size 22x21
index ee6e196..bf78e73 100644 (file)
@@ -373,6 +373,7 @@ accessibility/internal-link-anchors2.html
 accessibility/language-attribute.html
 accessibility/legend.html
 accessibility/lists.html
+accessibility/media-element.html
 accessibility/nochildren-elements.html
 accessibility/non-data-table-cell-title-ui-element.html
 accessibility/non-native-image-crash.html
index 295d4aa..08bb18c 100644 (file)
@@ -3,49 +3,49 @@ layer at (0,0) size 800x600
 layer at (0,0) size 800x600
   RenderBlock {HTML} at (0,0) size 800x600
     RenderBody {BODY} at (8,8) size 784x584
-      RenderBlock {P} at (0,0) size 784x18
-        RenderText {#text} at (0,0) size 153x18
+      RenderBlock {P} at (0,0) size 784x21
+        RenderText {#text} at (0,0) size 153x20
           text run at (0,0) width 153: "Test controls placement."
-      RenderBlock (anonymous) at (0,34) size 784x86
+      RenderBlock (anonymous) at (0,37) size 784x95
         RenderMedia {AUDIO} at (0,0) size 200x16 [bgcolor=#0000FF]
         RenderBR {BR} at (200,16) size 0x0
-        RenderBR {BR} at (0,16) size 0x18
-        RenderMedia {AUDIO} at (0,34) size 320x16 [bgcolor=#0000FF]
-        RenderBR {BR} at (320,50) size 0x0
-        RenderBR {BR} at (0,50) size 0x18
-        RenderBR {BR} at (0,68) size 0x18
-layer at (8,42) size 200x16
+        RenderBR {BR} at (0,16) size 0x20
+        RenderMedia {AUDIO} at (0,37) size 320x16 [bgcolor=#0000FF]
+        RenderBR {BR} at (320,53) size 0x0
+        RenderBR {BR} at (0,53) size 0x20
+        RenderBR {BR} at (0,74) size 0x20
+layer at (8,45) size 200x16
   RenderBlock (relative positioned) {DIV} at (0,0) size 200x16
-layer at (8,42) size 200x16
+layer at (8,45) size 200x16
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 200x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 136x16
+    RenderFlexibleBox {DIV} at (16,0) size 136x16
       RenderSlider {INPUT} at (0,0) size 136x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (152,0) size 16x16
     RenderButton {INPUT} at (168,0) size 16x16
     RenderButton {INPUT} at (184,0) size 16x16
-layer at (8,76) size 320x16
+layer at (8,82) size 320x16
   RenderBlock (relative positioned) {DIV} at (0,0) size 320x16
-layer at (8,76) size 320x16
+layer at (8,82) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,0) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
-layer at (8,110) size 320x100
-  RenderMedia {AUDIO} at (8,110) size 320x100 [bgcolor=#0000FF]
-layer at (8,110) size 320x100
+layer at (8,119) size 320x100
+  RenderMedia {AUDIO} at (8,119) size 320x100 [bgcolor=#0000FF]
+layer at (8,119) size 320x100
   RenderBlock (relative positioned) {DIV} at (0,0) size 320x100
-layer at (8,194) size 320x16
+layer at (8,203) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,84) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
index 9a8560d..923fac3 100644 (file)
@@ -17,9 +17,9 @@ layer at (8,42) size 320x240
 layer at (8,266) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
index 08ea19a..3231085 100644 (file)
@@ -4,10 +4,10 @@ RUN(video.autoplay = true)
 RUN(video.src = 'content/test.mp4')
 EVENT(playing)
 EVENT(seeked)
-Time: 1.7
+Time: 2.1
 EVENT(seeked)
-Time: 2.2
+Time: 2.6
 EVENT(seeked)
-Time: 2.7
+Time: 3.1
 END OF TEST
 
diff --git a/LayoutTests/platform/win/media/controls-strict-expected.txt b/LayoutTests/platform/win/media/controls-strict-expected.txt
new file mode 100644 (file)
index 0000000..5296d55
--- /dev/null
@@ -0,0 +1,25 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x302
+  RenderBlock {HTML} at (0,0) size 800x302
+    RenderBody {BODY} at (8,16) size 784x278
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 226x18
+          text run at (0,0) width 226: "Drawing the controls in strict mode."
+      RenderBlock (anonymous) at (0,34) size 784x244
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+layer at (8,50) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,50) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,274) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
index a22c31e..fd24373 100644 (file)
@@ -21,10 +21,10 @@ layer at (18,42) size 320x240
 layer at (18,266) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
 layer at (8,282) size 320x240
@@ -32,9 +32,9 @@ layer at (8,282) size 320x240
 layer at (8,506) size 320x16
   RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
     RenderButton {INPUT} at (0,0) size 16x16
-    RenderButton {INPUT} at (16,0) size 16x16
-    RenderFlexibleBox {DIV} at (32,0) size 256x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
       RenderSlider {INPUT} at (0,0) size 256x16
         RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
     RenderButton {INPUT} at (288,0) size 16x16
     RenderButton {INPUT} at (304,0) size 16x16
diff --git a/LayoutTests/platform/win/media/video-controls-rendering-expected.txt b/LayoutTests/platform/win/media/video-controls-rendering-expected.txt
new file mode 100644 (file)
index 0000000..fff11e1
--- /dev/null
@@ -0,0 +1,52 @@
+layer at (0,0) size 785x762
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x600
+  RenderBlock {HTML} at (0,0) size 785x600
+    RenderBody {BODY} at (8,8) size 769x584
+      RenderBlock {P} at (0,0) size 769x18
+        RenderText {#text} at (0,0) size 153x18
+          text run at (0,0) width 153: "Test controls placement."
+      RenderBlock {DIV} at (0,34) size 769x240
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,274) size 769x240
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {DIV} at (0,514) size 769x0
+layer at (8,42) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,282) size 320x240
+  RenderVideo {VIDEO} at (0,0) size 320x240
+layer at (8,42) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,266) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
+layer at (8,282) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,506) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
+layer at (8,522) size 320x240
+  RenderVideo {VIDEO} at (8,522) size 320x240
+layer at (8,522) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,746) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
diff --git a/LayoutTests/platform/win/media/video-display-toggle-expected.txt b/LayoutTests/platform/win/media/video-display-toggle-expected.txt
new file mode 100644 (file)
index 0000000..a9baa00
--- /dev/null
@@ -0,0 +1,24 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (0,0) size 493x18
+        text run at (0,0) width 493: "This tests that toggling the display property won't make the controls disappear."
+      RenderBR {BR} at (493,14) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,26) size 320x240
+  RenderVideo {VIDEO} at (0,18) size 320x240
+layer at (8,26) size 320x240
+  RenderBlock (relative positioned) {DIV} at (0,0) size 320x240
+layer at (8,250) size 320x16
+  RenderFlexibleBox (positioned) {DIV} at (0,224) size 320x16
+    RenderButton {INPUT} at (0,0) size 16x16
+    RenderFlexibleBox {DIV} at (16,0) size 256x16
+      RenderSlider {INPUT} at (0,0) size 256x16
+        RenderBlock {DIV} at (2,1) size 13x14
+    RenderButton {INPUT} at (272,0) size 16x16
+    RenderButton {INPUT} at (288,0) size 16x16
+    RenderButton {INPUT} at (304,0) size 16x16
index ae6f9c8..3420ce5 100644 (file)
@@ -1,3 +1,98 @@
+2009-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <video> and <audio> controller should be accessible (edit)
+        https://bugs.webkit.org/show_bug.cgi?id=28081
+
+        Test: accessibility/media-element.html
+
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * WebCoreSources.bkl:
+            Add AccessibilityMediaControls.cpp/.h
+
+        * accessibility/AXObjectCache.cpp:
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::getOrCreate):
+            Create AccessibilityMediaControl. Update Copyright
+
+        * accessibility/AccessibilityMediaControls.cpp:
+        * accessibility/AccessibilityMediaControls.h:
+            Added.
+
+        * accessibility/AccessibilityObject.cpp:
+        * accessibility/AccessibilityObject.h:
+            Add isMediaTimeline. Update Copyright.
+
+        * accessibility/AccessibilitySlider.h:
+            Make constructor protected instead of private so AccessibilityMediaTimeline can
+            call it.
+
+        * accessibility/mac/AccessibilityObjectWrapper.mm:
+        (-[AccessibilityObjectWrapper accessibilityAttributeNames]):
+            Add NSAccessibilityValueDescriptionAttribute to range attributes. 
+        (-[AccessibilityObjectWrapper subrole]):
+            Return NSAccessibilityTimelineSubrole for AccessibilityMediaTimeline.
+
+        * dom/Node.h:
+            add isMediaControlElement.
+
+        * page/mac/WebCoreViewFactory.h:
+        * platform/LocalizedStrings.h:
+        * platform/mac/LocalizedStringsMac.mm:
+        (WebCore::localizedMediaControlElementString): 
+        (WebCore::localizedMediaControlElementHelpText):
+        (WebCore::localizedMediaTimeDescription): 
+            New, return localized media controller strings.
+
+        * platform/gtk/LocalizedStringsGtk.cpp:
+        (WebCore::mediaElementLoadingStateText):
+        (WebCore::mediaElementLiveBroadcastStateText):
+            Move inside of "#if ENABLE(VIDEO)"
+        (WebCore::localizedMediaControlElementString):
+        (WebCore::localizedMediaControlElementHelpText):
+        (WebCore::localizedMediaTimeDescription):
+
+        * rendering/MediaControlElements.cpp:
+        (WebCore::MediaControlElement::MediaControlElement):
+            Initialize m_displayType.
+        (WebCore::MediaControlElement::MediaControlElement):
+        (WebCore::MediaControlStatusDisplayElement::MediaControlStatusDisplayElement):
+            Fix style.
+        (WebCore::MediaControlInputElement::MediaControlInputElement):
+            Set m_displayType based on pseudo style ID.
+        (WebCore::MediaControlInputElement::MediaControlInputElement):
+            rename local "o" to "object".
+        (WebCore::MediaControlMuteButtonElement::MediaControlMuteButtonElement):
+        (WebCore::MediaControlPlayButtonElement::MediaControlPlayButtonElement):
+        (WebCore::MediaControlSeekButtonElement::MediaControlSeekButtonElement):
+        (WebCore::MediaControlRewindButtonElement::MediaControlRewindButtonElement):
+        (WebCore::MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement):
+        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
+        (WebCore::MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement):
+        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
+        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
+        (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
+            Update for MediaControlInputElement constructor change.
+        (WebCore::MediaControlTimeDisplayElement::formatTime):
+            New, moved here from RenderMedia so AccessibilityMediaTimeDisplay can use it.
+        (WebCore::MediaControlTimeDisplayElement::setCurrentValue):
+            New, set text to current time.
+        * rendering/MediaControlElements.h:
+
+        * rendering/RenderMedia.cpp:
+        (WebCore::RenderMedia::updateControls):
+            Create controls in tab order.
+        (WebCore::RenderMedia::formatTime):
+            Moved to MediaControlTimeDisplayElement::formatTime.
+        (WebCore::RenderMedia::updateTimeDisplay):
+            Call MediaControlTimeDisplayElement::setCurrentValue.
+        * rendering/RenderMedia.h:
+
 2009-08-25  Jian Li  <jianli@chromium.org>
 
         Reviewed by David Levin.
index a590bf7..7edcc83 100644 (file)
@@ -287,6 +287,8 @@ webcore_sources += \
        WebCore/accessibility/AccessibilityListBox.h \
        WebCore/accessibility/AccessibilityListBoxOption.cpp \
        WebCore/accessibility/AccessibilityListBoxOption.h \
+       WebCore/accessibility/AccessibilityMediaControls.cpp \
+       WebCore/accessibility/AccessibilityMediaControls.h \
        WebCore/accessibility/AccessibilityObject.cpp \
        WebCore/accessibility/AccessibilityObject.h \
        WebCore/accessibility/AccessibilityRenderObject.cpp \
index e617d8f..4b8e39f 100644 (file)
             'accessibility/AccessibilityListBox.h',
             'accessibility/AccessibilityListBoxOption.cpp',
             'accessibility/AccessibilityListBoxOption.h',
+            'accessibility/AccessibilityMediaControls.cpp',
+            'accessibility/AccessibilityMediaControls.h',
             'accessibility/AccessibilityObject.cpp',
             'accessibility/AccessibilityObject.h',
             'accessibility/AccessibilityRenderObject.cpp',
index 76940fd..bad353e 100644 (file)
@@ -627,6 +627,7 @@ IDL_BINDINGS += \
 
 SOURCES += \
     accessibility/AccessibilityImageMapLink.cpp \
+    accessibility/AccessibilityMediaControls.cpp \    
     accessibility/AccessibilityObject.cpp \    
     accessibility/AccessibilityList.cpp \    
     accessibility/AccessibilityListBox.cpp \    
@@ -1323,6 +1324,7 @@ HEADERS += \
     accessibility/AccessibilityListBox.h \
     accessibility/AccessibilityListBoxOption.h \
     accessibility/AccessibilityList.h \
+    accessibility/AccessibilityMediaControls.h \
     accessibility/AccessibilityObject.h \
     accessibility/AccessibilityRenderObject.h \
     accessibility/AccessibilitySlider.h \
index 260855b..4333eb3 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\accessibility\AccessibilityMediaControls.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\accessibility\AccessibilityMediaControls.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\accessibility\AccessibilityObject.cpp"\r
                                >\r
                        </File>\r
index fa25dc2..7e80610 100644 (file)
@@ -40,6 +40,8 @@
                0709FC4C1025DED80059CDBA /* AccessibilitySlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0709FC4B1025DED80059CDBA /* AccessibilitySlider.cpp */; };
                0709FC4E1025DEE30059CDBA /* AccessibilitySlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 0709FC4D1025DEE30059CDBA /* AccessibilitySlider.h */; };
                0735EE6A0F40C5E4004A2604 /* MediaPlayerProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               07B0113D1032241900FBDC33 /* AccessibilityMediaControls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07B0113C1032241900FBDC33 /* AccessibilityMediaControls.cpp */; };
+               07B0113F1032242200FBDC33 /* AccessibilityMediaControls.h in Headers */ = {isa = PBXBuildFile; fileRef = 07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */; };
                080081960ED3B2DD00C53BC0 /* WMLAnchorElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 080081940ED3B2DD00C53BC0 /* WMLAnchorElement.cpp */; };
                080081970ED3B2DD00C53BC0 /* WMLAnchorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 080081950ED3B2DD00C53BC0 /* WMLAnchorElement.h */; };
                0804BF6E0EE09C3B0006C000 /* WMLDoElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0804BF6C0EE09C3B0006C000 /* WMLDoElement.cpp */; };
                0735EE690F40C5E4004A2604 /* MediaPlayerProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerProxy.h; sourceTree = "<group>"; };
                079F5E4B0F3BEBEA005E0782 /* MediaPlayerPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlayerPrivate.h; sourceTree = "<group>"; };
                07AFE5900F1446BD00841617 /* mediaControlsQT.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mediaControlsQT.css; sourceTree = "<group>"; };
+               07B0113C1032241900FBDC33 /* AccessibilityMediaControls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityMediaControls.cpp; sourceTree = "<group>"; };
+               07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccessibilityMediaControls.h; sourceTree = "<group>"; };
                080081940ED3B2DD00C53BC0 /* WMLAnchorElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLAnchorElement.cpp; sourceTree = "<group>"; };
                080081950ED3B2DD00C53BC0 /* WMLAnchorElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLAnchorElement.h; sourceTree = "<group>"; };
                0804BF6C0EE09C3B0006C000 /* WMLDoElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLDoElement.cpp; sourceTree = "<group>"; };
                                29A812250FBB9C1D00510293 /* AccessibilityListBox.h */,
                                29A8121F0FBB9C1D00510293 /* AccessibilityListBoxOption.cpp */,
                                29A812240FBB9C1D00510293 /* AccessibilityListBoxOption.h */,
+                               07B0113C1032241900FBDC33 /* AccessibilityMediaControls.cpp */,
+                               07B0113E1032242200FBDC33 /* AccessibilityMediaControls.h */,
                                29A8121E0FBB9C1D00510293 /* AccessibilityObject.cpp */,
                                29A812180FBB9C1D00510293 /* AccessibilityObject.h */,
                                29A812080FBB9C1D00510293 /* AccessibilityRenderObject.cpp */,
                                29A8122C0FBB9C1D00510293 /* AccessibilityList.h in Headers */,
                                29A812430FBB9C1D00510293 /* AccessibilityListBox.h in Headers */,
                                29A812420FBB9C1D00510293 /* AccessibilityListBoxOption.h in Headers */,
+                               07B0113F1032242200FBDC33 /* AccessibilityMediaControls.h in Headers */,
                                29A812360FBB9C1D00510293 /* AccessibilityObject.h in Headers */,
                                29A812490FBB9CA900510293 /* AccessibilityObjectWrapper.h in Headers */,
                                29A812390FBB9C1D00510293 /* AccessibilityRenderObject.h in Headers */,
                                29A8122F0FBB9C1D00510293 /* AccessibilityList.cpp in Sources */,
                                29A8123E0FBB9C1D00510293 /* AccessibilityListBox.cpp in Sources */,
                                29A8123D0FBB9C1D00510293 /* AccessibilityListBoxOption.cpp in Sources */,
+                               07B0113D1032241900FBDC33 /* AccessibilityMediaControls.cpp in Sources */,
                                29A8123C0FBB9C1D00510293 /* AccessibilityObject.cpp in Sources */,
                                29A812480FBB9CA900510293 /* AccessibilityObjectMac.mm in Sources */,
                                29A8124A0FBB9CA900510293 /* AccessibilityObjectWrapper.mm in Sources */,
index 99cee3e..7deb364 100644 (file)
@@ -37,6 +37,7 @@ This file contains the list of files needed to build WebCore.
         accessibility/AccessibilityARIAGridCell.cpp
         accessibility/AccessibilityARIAGridRow.cpp
         accessibility/AccessibilityImageMapLink.cpp
+        accessibility/AccessibilityMediaControls.cpp
         accessibility/AccessibilityObject.cpp
         accessibility/AccessibilityList.cpp
         accessibility/AccessibilityListBox.cpp
index 0cac8be..cb34015 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
 #include "AccessibilityListBox.h"
 #include "AccessibilityListBoxOption.h"
 #include "AccessibilityImageMapLink.h"
+#include "AccessibilityMediaControls.h"
 #include "AccessibilityRenderObject.h"
 #include "AccessibilitySlider.h"
 #include "AccessibilityTable.h"
@@ -46,6 +47,9 @@
 #include "FocusController.h"
 #include "Frame.h"
 #include "HTMLNames.h"
+#if ENABLE(VIDEO)
+#include "MediaControlElements.h"
+#endif
 #include "InputElement.h"
 #include "Page.h"
 #include "RenderObject.h"
@@ -157,6 +161,12 @@ AccessibilityObject* AXObjectCache::getOrCreate(RenderObject* renderer)
         else if (renderer->isTableCell())
             newObj = AccessibilityTableCell::create(renderer);
 
+#if ENABLE(VIDEO)
+        // media controls
+        else if (renderer->node() && renderer->node()->isMediaControlElement())
+            newObj = AccessibilityMediaControl::create(renderer);
+#endif
+
         // input type=range
         else if (renderer->isSlider())
             newObj = AccessibilitySlider::create(renderer);
index 96ded44..d57d9a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
diff --git a/WebCore/accessibility/AccessibilityMediaControls.cpp b/WebCore/accessibility/AccessibilityMediaControls.cpp
new file mode 100644 (file)
index 0000000..a807ab9
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2009 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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(VIDEO)
+
+#include "AccessibilityMediaControls.h"
+
+#include "AXObjectCache.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "MediaControlElements.h"
+#include "RenderObject.h"
+#include "RenderSlider.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+
+AccessibilityMediaControl::AccessibilityMediaControl(RenderObject* renderer)
+    : AccessibilityRenderObject(renderer)
+{
+}
+
+PassRefPtr<AccessibilityObject> AccessibilityMediaControl::create(RenderObject* renderer)
+{
+    ASSERT(renderer->node() && renderer->node()->isMediaControlElement());
+
+    Node* node = renderer->node();
+    MediaControlElementType controlType;
+
+    if (node->hasTagName(inputTag))
+        controlType = static_cast<MediaControlInputElement*>(node)->displayType();
+    else
+        controlType = static_cast<MediaControlElement*>(node)->displayType();
+
+    PassRefPtr<AccessibilityObject> obj;
+    switch (controlType) {
+    case MediaSlider:
+        obj = AccessibilityMediaTimeline::create(renderer);
+        break;
+
+    case MediaCurrentTimeDisplay:
+    case MediaTimeRemainingDisplay:
+        obj = AccessibilityMediaTimeDisplay::create(renderer);
+        break;
+
+    case MediaControlsPanel:
+        obj = AccessibilityMediaControlsContainer::create(renderer);
+        break;
+
+    default:
+        obj = adoptRef(new AccessibilityMediaControl(renderer));
+        break;
+    }
+
+    return obj;
+}
+
+MediaControlElementType AccessibilityMediaControl::controlType() const
+{
+    if (!renderer() || !renderer()->node())
+        return MediaTimelineContainer;  // Timeline container is not accessible.
+
+    Node* node = renderer()->node();
+
+    if (node->hasTagName(inputTag))
+        return static_cast<MediaControlInputElement*>(node)->displayType();
+
+    return static_cast<MediaControlElement*>(node)->displayType();
+}
+
+String AccessibilityMediaControl::controlTypeName() const
+{
+    DEFINE_STATIC_LOCAL(const String, mediaMuteButtonName, ("MuteButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaPlayButtonName, ("PlayButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaSeekBackButtonName, ("SeekBackButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaSeekForwardButtonName, ("SeekForwardButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaRewindButtonName, ("RewindButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaReturnToRealtimeButtonName, ("ReturnToRealtimeButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaUnMuteButtonName, ("UnMuteButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaPauseButtonName, ("PauseButton"));
+    DEFINE_STATIC_LOCAL(const String, mediaStatusDisplayName, ("StatusDisplay"));
+    DEFINE_STATIC_LOCAL(const String, mediaCurrentTimeDisplay, ("CurrentTimeDisplay"));
+    DEFINE_STATIC_LOCAL(const String, mediaTimeRemainingDisplay, ("TimeRemainingDisplay"));
+
+    switch (controlType()) {
+    case MediaMuteButton:
+        return mediaMuteButtonName;
+    case MediaPlayButton:
+        return mediaPlayButtonName;
+    case MediaSeekBackButton:
+        return mediaSeekBackButtonName;
+    case MediaSeekForwardButton:
+        return mediaSeekForwardButtonName;
+    case MediaRewindButton:
+        return mediaRewindButtonName;
+    case MediaReturnToRealtimeButton:
+        return mediaReturnToRealtimeButtonName;
+    case MediaUnMuteButton:
+        return mediaUnMuteButtonName;
+    case MediaPauseButton:
+        return mediaPauseButtonName;
+    case MediaStatusDisplay:
+        return mediaStatusDisplayName;
+    case MediaCurrentTimeDisplay:
+        return mediaCurrentTimeDisplay;
+    case MediaTimeRemainingDisplay:
+        return mediaTimeRemainingDisplay;
+
+    default:
+        break;
+    }
+
+    return String();
+}
+
+String AccessibilityMediaControl::title() const
+{
+    DEFINE_STATIC_LOCAL(const String, controlsPanel, ("ControlsPanel"));
+
+    if (controlType() == MediaControlsPanel)
+        return localizedMediaControlElementString(controlsPanel);
+
+    return AccessibilityRenderObject::title();
+}
+
+String AccessibilityMediaControl::accessibilityDescription() const
+{
+    return localizedMediaControlElementString(controlTypeName());
+}
+
+String AccessibilityMediaControl::helpText() const
+{
+    return localizedMediaControlElementHelpText(controlTypeName());
+}
+
+bool AccessibilityMediaControl::accessibilityIsIgnored() const
+{
+    if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE || controlType() == MediaTimelineContainer)
+        return true;
+
+    return false;
+}
+
+AccessibilityRole AccessibilityMediaControl::roleValue() const
+{
+    switch (controlType()) {
+    case MediaFullscreenButton:
+    case MediaMuteButton:
+    case MediaPlayButton:
+    case MediaSeekBackButton:
+    case MediaSeekForwardButton:
+    case MediaRewindButton:
+    case MediaReturnToRealtimeButton:
+    case MediaUnMuteButton:
+    case MediaPauseButton:
+        return ButtonRole;
+
+    case MediaStatusDisplay:
+        return StaticTextRole;
+
+    case MediaTimelineContainer:
+        return GroupRole;
+
+    default:
+        break;
+    }
+
+    return UnknownRole;
+}
+
+
+
+//
+// AccessibilityMediaControlsContainer
+
+AccessibilityMediaControlsContainer::AccessibilityMediaControlsContainer(RenderObject* renderer)
+    : AccessibilityMediaControl(renderer)
+{
+}
+
+PassRefPtr<AccessibilityObject> AccessibilityMediaControlsContainer::create(RenderObject* renderer)
+{
+    return adoptRef(new AccessibilityMediaControlsContainer(renderer));
+}
+
+String AccessibilityMediaControlsContainer::accessibilityDescription() const
+{
+    return localizedMediaControlElementString(elementTypeName());
+}
+
+String AccessibilityMediaControlsContainer::helpText() const
+{
+    return localizedMediaControlElementHelpText(elementTypeName());
+}
+
+bool AccessibilityMediaControlsContainer::controllingVideoElement() const
+{
+    if (!m_renderer->node())
+        return true;
+
+    MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
+
+    return element->mediaElement()->isVideo();
+}
+
+const String AccessibilityMediaControlsContainer::elementTypeName() const
+{
+    DEFINE_STATIC_LOCAL(const String, videoElement, ("VideoElement"));
+    DEFINE_STATIC_LOCAL(const String, audioElement, ("AudioElement"));
+
+    if (controllingVideoElement())
+        return videoElement;
+    return audioElement;
+}
+
+
+//
+// AccessibilityMediaTimeline
+
+AccessibilityMediaTimeline::AccessibilityMediaTimeline(RenderObject* renderer)
+    : AccessibilitySlider(renderer)
+{
+}
+
+PassRefPtr<AccessibilityObject> AccessibilityMediaTimeline::create(RenderObject* renderer)
+{
+    return adoptRef(new AccessibilityMediaTimeline(renderer));
+}
+
+String AccessibilityMediaTimeline::valueDescription() const
+{
+    ASSERT(m_renderer->node()->hasTagName(inputTag));
+
+    float time = static_cast<HTMLInputElement*>(m_renderer->node())->value().toFloat();
+    return localizedMediaTimeDescription(time);
+}
+
+String AccessibilityMediaTimeline::helpText() const
+{
+    DEFINE_STATIC_LOCAL(const String, slider, ("Slider"));
+    return localizedMediaControlElementHelpText(slider);
+}
+
+
+//
+// AccessibilityMediaTimeDisplay
+
+AccessibilityMediaTimeDisplay::AccessibilityMediaTimeDisplay(RenderObject* renderer)
+    : AccessibilityMediaControl(renderer)
+{
+}
+
+PassRefPtr<AccessibilityObject> AccessibilityMediaTimeDisplay::create(RenderObject* renderer)
+{
+    return adoptRef(new AccessibilityMediaTimeDisplay(renderer));
+}
+
+bool AccessibilityMediaTimeDisplay::accessibilityIsIgnored() const
+{
+    if (!m_renderer || !m_renderer->style() || m_renderer->style()->visibility() != VISIBLE)
+        return true;
+
+    return !m_renderer->style()->width().value();
+}
+
+String AccessibilityMediaTimeDisplay::accessibilityDescription() const
+{
+    DEFINE_STATIC_LOCAL(const String, currentTimeDisplay, ("CurrentTimeDisplay"));
+    DEFINE_STATIC_LOCAL(const String, timeRemainingDisplay, ("TimeRemainingDisplay"));
+
+    if (controlType() == MediaCurrentTimeDisplay)
+        return localizedMediaControlElementString(currentTimeDisplay);
+
+    return localizedMediaControlElementString(timeRemainingDisplay);
+}
+
+String AccessibilityMediaTimeDisplay::stringValue() const
+{
+    if (!m_renderer || !m_renderer->node())
+        return String();
+
+    MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
+    float time = element->currentValue();
+    return localizedMediaTimeDescription(fabsf(time));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO)
diff --git a/WebCore/accessibility/AccessibilityMediaControls.h b/WebCore/accessibility/AccessibilityMediaControls.h
new file mode 100644 (file)
index 0000000..9b306fd
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 AccessibilityMediaControls_h
+#define AccessibilityMediaControls_h
+
+#if ENABLE(VIDEO)
+
+#include "AccessibilitySlider.h"
+#include "MediaControlElements.h"
+
+namespace WebCore {
+
+    class AccessibilityMediaControl : public AccessibilityRenderObject {
+
+    public:
+        static PassRefPtr<AccessibilityObject> create(RenderObject*);
+        virtual ~AccessibilityMediaControl() { }
+
+        virtual AccessibilityRole roleValue() const;
+        virtual bool accessibilityIsIgnored() const;
+
+        virtual String title() const;
+        virtual String accessibilityDescription() const;
+        virtual String helpText() const;
+
+    protected:
+        AccessibilityMediaControl(RenderObject*);
+        MediaControlElementType controlType() const;
+        String controlTypeName() const;
+    };
+
+
+    class AccessibilityMediaTimeline : public AccessibilitySlider {
+
+    public:
+        static PassRefPtr<AccessibilityObject> create(RenderObject*);
+        virtual ~AccessibilityMediaTimeline() { }
+
+        virtual bool isMediaTimeline() const { return true; }
+
+        virtual String helpText() const;
+        virtual String valueDescription() const;
+        const AtomicString& getAttribute(const QualifiedName& attribute) const;
+
+    private:
+        AccessibilityMediaTimeline(RenderObject*);
+    };
+
+
+    class AccessibilityMediaControlsContainer : public AccessibilityMediaControl {
+
+    public:
+        static PassRefPtr<AccessibilityObject> create(RenderObject*);
+        virtual ~AccessibilityMediaControlsContainer() { }
+
+        virtual AccessibilityRole roleValue() const { return ToolbarRole; }
+        virtual bool accessibilityIsIgnored() const { return false; }
+
+        virtual String helpText() const;
+        virtual String accessibilityDescription() const;
+
+    private:
+        AccessibilityMediaControlsContainer(RenderObject*);
+        bool controllingVideoElement() const;
+        const String elementTypeName() const;
+    };
+
+
+    class AccessibilityMediaTimeDisplay : public AccessibilityMediaControl {
+
+    public:
+        static PassRefPtr<AccessibilityObject> create(RenderObject*);
+        virtual ~AccessibilityMediaTimeDisplay() { }
+
+        virtual AccessibilityRole roleValue() const { return StaticTextRole; }
+        virtual bool accessibilityIsIgnored() const;
+
+        virtual String stringValue() const;
+        virtual String accessibilityDescription() const;
+
+    private:
+        AccessibilityMediaTimeDisplay(RenderObject*);
+    };
+
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO)
+
+#endif // AccessibilityMediaControls_h
index 4fb4e3a..2f07e5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index 653442a..2e2e6a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nuanti Ltd.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -244,6 +244,7 @@ public:
     virtual bool isWebArea() const { return false; };
     virtual bool isCheckboxOrRadio() const { return false; };
     virtual bool isListBox() const { return roleValue() == ListBoxRole; };
+    virtual bool isMediaTimeline() const { return false; }
     virtual bool isMenuRelated() const { return false; }
     virtual bool isMenu() const { return false; }
     virtual bool isMenuBar() const { return false; }
index eadab08..3a7e65f 100644 (file)
@@ -61,8 +61,10 @@ namespace WebCore {
         virtual void increment();
         virtual void decrement();
 
-    private:
+    protected:
         AccessibilitySlider(RenderObject*);
+
+    private:
         void changeValue(float /*percentChange*/);
         HTMLInputElement* element() const;
     };
index 13b539b..7a3d0d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -122,6 +122,7 @@ using namespace std;
 #ifdef BUILDING_ON_TIGER
 typedef unsigned NSUInteger;
 #define NSAccessibilityValueDescriptionAttribute @"AXValueDescription"
+#define NSAccessibilityTimelineSubrole @"AXTimeline"
 #endif
 
 @interface NSObject (WebKitAccessibilityArrayCategory)
@@ -678,6 +679,7 @@ static WebCoreTextMarkerRange* textMarkerRangeFromVisiblePositions(VisiblePositi
         [tempArray addObject:NSAccessibilityMinValueAttribute];
         [tempArray addObject:NSAccessibilityMaxValueAttribute];
         [tempArray addObject:NSAccessibilityOrientationAttribute];
+        [tempArray addObject:NSAccessibilityValueDescriptionAttribute];
         rangeAttrs = [[NSArray alloc] initWithArray:tempArray];
         [tempArray release];
     }
@@ -1081,6 +1083,9 @@ static NSString* roleValueToNSString(AccessibilityRole value)
             return nil;
     }
     
+    if (m_object->isMediaTimeline())
+        return NSAccessibilityTimelineSubrole;
+
     return nil;
 }
 
@@ -1345,7 +1350,7 @@ static NSString* roleValueToNSString(AccessibilityRole value)
         }
         return m_object->accessibilityDescription();
     }
-    
+
     if ([attributeName isEqualToString: NSAccessibilityValueAttribute]) {
         if (m_object->isAttachment()) {
             if ([[[self attachmentView] accessibilityAttributeNames] containsObject:NSAccessibilityValueAttribute]) 
index 9464863..e082e48 100644 (file)
@@ -180,6 +180,7 @@ public:
     static bool isWMLElement() { return false; }
 #endif
 
+    virtual bool isMediaControlElement() const { return false; }
     virtual bool isStyledElement() const { return false; }
     virtual bool isFrameOwnerElement() const { return false; }
     virtual bool isAttributeNode() const { return false; }
index e114e99..c1b7375 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2003, 2005, 2009 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 - (NSString *)mediaElementLoadingStateText;
 - (NSString *)mediaElementLiveBroadcastStateText;
+- (NSString*)localizedMediaControlElementString:(NSString*)name;
+- (NSString*)localizedMediaControlElementHelpText:(NSString*)name;
+- (NSString*)localizedMediaTimeDescription:(float)time;
+
 
 @end
 
index 99485ce..45855ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2003, 2006, 2009 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -136,6 +136,9 @@ namespace WebCore {
 
     String mediaElementLoadingStateText();
     String mediaElementLiveBroadcastStateText();
+    String localizedMediaControlElementString(const String&);
+    String localizedMediaControlElementHelpText(const String&);
+    String localizedMediaTimeDescription(float);
 }
 
 #endif
index 2ba4fbb..85e071b 100644 (file)
@@ -345,6 +345,9 @@ String imageTitle(const String& filename, const IntSize& size)
     return String::fromUTF8(string.get());
 }
 
+
+#if ENABLE(VIDEO)
+
 String mediaElementLoadingStateText()
 {
     return String::fromUTF8(_("Loading..."));
@@ -355,4 +358,113 @@ String mediaElementLiveBroadcastStateText()
     return String::fromUTF8(_("Live Broadcast"));
 }
 
+String localizedMediaControlElementString(const String& name)
+{
+    if (name == "AudioElement")
+        return String::fromUTF8(_("audio element controller"));
+    if (name == "VideoElement")
+        return String::fromUTF8(_("video element controller"));
+    if (name == "MuteButton")
+        return String::fromUTF8(_("mute"));
+    if (name == "UnMuteButton")
+        return String::fromUTF8(_("unmute"));
+    if (name == "PlayButton")
+        return String::fromUTF8(_("play"));
+    if (name == "PauseButton")
+        return String::fromUTF8(_("pause"));
+    if (name == "Slider")
+        return String::fromUTF8(_("movie time"));
+    if (name == "SliderThumb")
+        return String::fromUTF8(_("timeline slider thumb"));
+    if (name == "RewindButton")
+        return String::fromUTF8(_("back 30 seconds"));
+    if (name == "ReturnToRealtimeButton")
+        return String::fromUTF8(_("return to realtime"));
+    if (name == "CurrentTimeDisplay")
+        return String::fromUTF8(_("elapsed time"));
+    if (name == "TimeRemainingDisplay")
+        return String::fromUTF8(_("remaining time"));
+    if (name == "StatusDisplay")
+        return String::fromUTF8(_("status"));
+    if (name == "FullscreenButton")
+        return String::fromUTF8(_("fullscreen"));
+    if (name == "SeekForwardButton")
+        return String::fromUTF8(_("fast forward"));
+    if (name == "SeekBackButton")
+        return String::fromUTF8(_("fast reverse"));
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+String localizedMediaControlElementHelpText(const String& name)
+{
+    if (name == "AudioElement")
+        return String::fromUTF8(_("audio element playback controls and status display"));
+    if (name == "VideoElement")
+        return String::fromUTF8(_("video element playback controls and status display"));
+    if (name == "MuteButton")
+        return String::fromUTF8(_("mute audio tracks"));
+    if (name == "UnMuteButton")
+        return String::fromUTF8(_("unmute audio tracks"));
+    if (name == "PlayButton")
+        return String::fromUTF8(_("begin playback"));
+    if (name == "PauseButton")
+        return String::fromUTF8(_("pause playback"));
+    if (name == "Slider")
+        return String::fromUTF8(_("movie time scrubber"));
+    if (name == "SliderThumb")
+        return String::fromUTF8(_("movie time scrubber thumb"));
+    if (name == "RewindButton")
+        return String::fromUTF8(_("seek movie back 30 seconds"));
+    if (name == "ReturnToRealtimeButton")
+        return String::fromUTF8(_("return streaming movie to real time"));
+    if (name == "CurrentTimeDisplay")
+        return String::fromUTF8(_("current movie time in seconds"));
+    if (name == "TimeRemainingDisplay")
+        return String::fromUTF8(_("number of seconds of movie remaining"));
+    if (name == "StatusDisplay")
+        return String::fromUTF8(_("current movie status"));
+    if (name == "SeekBackButton")
+        return String::fromUTF8(_("seek quickly back"));
+    if (name == "SeekForwardButton")
+        return String::fromUTF8(_("seek quickly forward"));
+    if (name == "FullscreenButton")
+        return String::fromUTF8(_("Play movie in fullscreen mode"));
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+String localizedMediaTimeDescription(float time)
+{
+    if (!isfinite(time))
+        return String::fromUTF8(_("indefinite time"));
+
+    int seconds = (int)fabsf(time);
+    int days = seconds / (60 * 60 * 24);
+    int hours = seconds / (60 * 60);
+    int minutes = (seconds / 60) % 60;
+    seconds %= 60;
+
+    if (days) {
+        GOwnPtr<gchar> string(g_strdup_printf("%d days %d hours %d minutes %d seconds", days, hours, minutes, seconds));
+        return String::fromUTF8(string.get());
+    }
+
+    if (hours) {
+        GOwnPtr<gchar> string(g_strdup_printf("%d hours %d minutes %d seconds", hours, minutes, seconds));
+        return String::fromUTF8(string.get());
+    }
+
+    if (minutes) {
+        GOwnPtr<gchar> string(g_strdup_printf("%d minutes %d seconds", minutes, seconds));
+        return String::fromUTF8(string.get());
+    }
+
+    GOwnPtr<gchar> string(g_strdup_printf("%d seconds", seconds));
+    return String::fromUTF8(string.get());
+}
+#endif  // ENABLE(VIDEO)
+
 }
index 9c1c6a9..1729061 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2003, 2006, 2009 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -721,4 +721,29 @@ String mediaElementLiveBroadcastStateText()
     return String();
 }
 
+String localizedMediaControlElementString(const String& controlName)
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    return [[WebCoreViewFactory sharedFactory] localizedMediaControlElementString:controlName];
+    END_BLOCK_OBJC_EXCEPTIONS;
+    return String();
+}
+
+String localizedMediaControlElementHelpText(const String& controlName)
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    return [[WebCoreViewFactory sharedFactory] localizedMediaControlElementHelpText:controlName];
+    END_BLOCK_OBJC_EXCEPTIONS;
+    return String();
+}
+
+String localizedMediaTimeDescription(float time)
+{
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    return [[WebCoreViewFactory sharedFactory] localizedMediaTimeDescription:time];
+    END_BLOCK_OBJC_EXCEPTIONS;
+    return String();
+}
+
+
 }
index 37ce963..fccd40f 100644 (file)
@@ -82,6 +82,29 @@ MediaControlElement::MediaControlElement(Document* document, PseudoId pseudo, HT
     , m_pseudoStyleId(pseudo)
 {
     setInDocument(true);
+    switch (pseudo) {
+    case MEDIA_CONTROLS_CURRENT_TIME_DISPLAY:
+        m_displayType = MediaCurrentTimeDisplay;
+        break;
+    case MEDIA_CONTROLS_TIME_REMAINING_DISPLAY:
+        m_displayType = MediaTimeRemainingDisplay;
+        break;
+    case MEDIA_CONTROLS_TIMELINE_CONTAINER:
+        m_displayType = MediaTimelineContainer;
+        break;
+    case MEDIA_CONTROLS_STATUS_DISPLAY:
+        m_displayType = MediaStatusDisplay;
+        break;
+    case MEDIA_CONTROLS_PANEL:
+        m_displayType = MediaControlsPanel;
+        break;
+    case MEDIA_CONTROLS_VOLUME_SLIDER_CONTAINER:
+        m_displayType = MediaVolumeSliderContainer;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
 }
 
 void MediaControlElement::attachToParent(Element* parent)
@@ -275,14 +298,46 @@ bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style)
 
 // ----------------------------
     
-MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+MediaControlInputElement::MediaControlInputElement(Document* document, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement)
     : HTMLInputElement(inputTag, document)
     , m_mediaElement(mediaElement)
     , m_pseudoStyleId(pseudo)
-    , m_displayType(displayType)
 {
     setInputType(type);
     setInDocument(true);
+
+    switch (pseudo) {
+    case MEDIA_CONTROLS_MUTE_BUTTON:
+        m_displayType = MediaMuteButton;
+        break;
+    case MEDIA_CONTROLS_PLAY_BUTTON:
+        m_displayType = MediaPlayButton;
+        break;
+    case MEDIA_CONTROLS_SEEK_FORWARD_BUTTON:
+        m_displayType = MediaSeekForwardButton;
+        break;
+    case MEDIA_CONTROLS_SEEK_BACK_BUTTON:
+        m_displayType = MediaSeekBackButton;
+        break;
+    case MEDIA_CONTROLS_FULLSCREEN_BUTTON:
+        m_displayType = MediaFullscreenButton;
+        break;
+    case MEDIA_CONTROLS_TIMELINE:
+        m_displayType = MediaSlider;
+        break;
+    case MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON:
+        m_displayType = MediaReturnToRealtimeButton;
+        break;
+    case MEDIA_CONTROLS_REWIND_BUTTON:
+        m_displayType = MediaRewindButton;
+        break;
+    case MEDIA_CONTROLS_VOLUME_SLIDER:
+        m_displayType = MediaVolumeSlider;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
 }
 
 void MediaControlInputElement::attachToParent(Element* parent)
@@ -364,14 +419,14 @@ void MediaControlInputElement::setDisplayType(MediaControlElementType displayTyp
         return;
 
     m_displayType = displayType;
-    if (RenderObject* o = renderer())
-        o->repaint();
+    if (RenderObject* object = renderer())
+        object->repaint();
 }
 
 // ----------------------------
 
 MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_MUTE_BUTTON, "button", element, element->muted() ? MediaUnMuteButton : MediaMuteButton)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_MUTE_BUTTON, "button", element)
 {
 }
 
@@ -402,7 +457,7 @@ bool MediaControlMuteButtonElement::rendererIsNeeded(RenderStyle* style)
 // ----------------------------
 
 MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_PLAY_BUTTON, "button", element, element->canPlay() ? MediaPlayButton : MediaPauseButton)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_PLAY_BUTTON, "button", element)
 {
 }
 
@@ -424,7 +479,7 @@ void MediaControlPlayButtonElement::updateDisplayType()
 
 MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document* document, HTMLMediaElement* element, bool forward)
     : MediaControlInputElement(document, forward ? MEDIA_CONTROLS_SEEK_FORWARD_BUTTON : MEDIA_CONTROLS_SEEK_BACK_BUTTON,
-                               "button", element, forward ? MediaSeekForwardButton : MediaSeekBackButton)
+                               "button", element)
     , m_forward(forward)
     , m_seeking(false)
     , m_capturing(false)
@@ -483,7 +538,7 @@ void MediaControlSeekButtonElement::detach()
 // ----------------------------
 
 MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_REWIND_BUTTON, "button", element, MediaRewindButton)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_REWIND_BUTTON, "button", element)
 {
 }
 
@@ -505,7 +560,7 @@ bool MediaControlRewindButtonElement::rendererIsNeeded(RenderStyle* style)
 // ----------------------------
 
 MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element, MediaReturnToRealtimeButton)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element)
 {
 }
 
@@ -526,8 +581,8 @@ bool MediaControlReturnToRealtimeButtonElement::rendererIsNeeded(RenderStyle* st
 // ----------------------------
 
 MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element, MediaTimelineContainer)
-{ 
+    : MediaControlInputElement(document, MEDIA_CONTROLS_TIMELINE, "range", element)
+{
 }
 
 void MediaControlTimelineElement::defaultEventHandler(Event* event)
@@ -571,7 +626,7 @@ void MediaControlTimelineElement::update(bool updateDuration)
 // ----------------------------
 
 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_VOLUME_SLIDER, "range", element, MediaVolumeSlider)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_VOLUME_SLIDER, "range", element)
 {
     setAttribute(maxAttr, "1");
 }
@@ -598,7 +653,7 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
 // ----------------------------
 
 MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document* document, HTMLMediaElement* element)
-    : MediaControlInputElement(document, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element, MediaFullscreenButton)
+    : MediaControlInputElement(document, MEDIA_CONTROLS_FULLSCREEN_BUTTON, "button", element)
 {
 }
 
@@ -620,6 +675,7 @@ bool MediaControlFullscreenButtonElement::rendererIsNeeded(RenderStyle* style)
 
 MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document* document, PseudoId pseudo, HTMLMediaElement* element)
     : MediaControlElement(document, pseudo, element)
+    , m_currentValue(0)
     , m_isVisible(true)
 {
 }
@@ -649,6 +705,32 @@ void MediaControlTimeDisplayElement::setVisible(bool visible)
     renderer()->setStyle(style.get());
 }
 
+String MediaControlTimeDisplayElement::formatTime(float time)
+{
+    if (!isfinite(time))
+        time = 0;
+    int seconds = (int)fabsf(time);
+    int hours = seconds / (60 * 60);
+    int minutes = (seconds / 60) % 60;
+    seconds %= 60;
+    if (hours) {
+        if (hours > 9)
+            return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+
+        return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
+    }
+
+    return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
+}
+
+void MediaControlTimeDisplayElement::setCurrentValue(float time)
+{
+    m_currentValue = time;
+
+    ExceptionCode ec;
+    setInnerText(formatTime(m_currentValue), ec);
+}
+
 
 } //namespace WebCore
 #endif // enable(video)
index d9cde1f..e80f7fa 100644 (file)
@@ -92,9 +92,15 @@ public:
     void update();
     virtual void updateStyle();
 
+    MediaControlElementType displayType() const { return m_displayType; }
+
+    HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+    virtual bool isMediaControlElement() const { return true; }
+
 protected:
     HTMLMediaElement* m_mediaElement;   
     PseudoId m_pseudoStyleId;
+    MediaControlElementType m_displayType;  // some elements can show multiple types (e.g. play/pause)
 };
 
 // ----------------------------
@@ -137,7 +143,7 @@ private:
 
 class MediaControlInputElement : public HTMLInputElement {
 public:
-    MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*, MediaControlElementType);
+    MediaControlInputElement(Document*, PseudoId, const String& type, HTMLMediaElement*);
     virtual void attach();
     virtual bool rendererIsNeeded(RenderStyle*);
 
@@ -152,13 +158,16 @@ public:
     // Some elements are disabled by movie state (eg. mute if no audio).
     virtual bool disabled() const  { return false; }
 
+    HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+    virtual bool isMediaControlElement() const { return true; }
+
 protected:
     virtual void updateDisplayType() { }
     void setDisplayType(MediaControlElementType);
 
     HTMLMediaElement* m_mediaElement;   
     PseudoId m_pseudoStyleId;
-    MediaControlElementType m_displayType;  // some elements can show multiple types (e.g. play/pause)
+    MediaControlElementType m_displayType;
 };
 
 // ----------------------------
@@ -249,7 +258,13 @@ public:
     void setVisible(bool);
     virtual PassRefPtr<RenderStyle> styleForElement();
 
+    void setCurrentValue(float);
+    float currentValue() const { return m_currentValue; }
+
 private:
+    String formatTime(float time);
+
+    float m_currentValue;
     bool m_isVisible;
 };
 
index 78ae06a..5600c20 100644 (file)
@@ -320,22 +320,22 @@ void RenderMedia::updateControls()
         createPanel();
         if (m_panel) {
             createRewindButton();
-            createMuteButton();
             createPlayButton();
             createReturnToRealtimeButton();
             createStatusDisplay();
             createTimelineContainer();
-            createVolumeSliderContainer();
-            createSeekBackButton();
-            createSeekForwardButton();
-            createFullscreenButton();
-            if (m_volumeSliderContainer)
-                createVolumeSlider();
             if (m_timelineContainer) {
                 createCurrentTimeDisplay();
                 createTimeline();
                 createTimeRemainingDisplay();
             }
+            createSeekBackButton();
+            createSeekForwardButton();
+            createFullscreenButton();
+            createMuteButton();
+            createVolumeSliderContainer();
+            if (m_volumeSliderContainer)
+                createVolumeSlider();
             m_panel->attach();
         }
     }
@@ -395,24 +395,6 @@ void RenderMedia::timeUpdateTimerFired(Timer<RenderMedia>*)
     updateTimeDisplay();
 }
     
-String RenderMedia::formatTime(float time)
-{
-    if (!isfinite(time))
-        time = 0;
-    int seconds = (int)fabsf(time); 
-    int hours = seconds / (60 * 60);
-    int minutes = (seconds / 60) % 60;
-    seconds %= 60;
-    if (hours) {
-        if (hours > 9)
-            return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
-        else
-            return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
-    }
-    else
-        return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
-}
-
 void RenderMedia::updateTimeDisplay()
 {
     if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || style()->visibility() != VISIBLE)
@@ -420,12 +402,8 @@ void RenderMedia::updateTimeDisplay()
     float now = mediaElement()->currentTime();
     float duration = mediaElement()->duration();
 
-    String timeString = formatTime(now);
-    ExceptionCode ec;
-    m_currentTimeDisplay->setInnerText(timeString, ec);
-    
-    timeString = formatTime(now - duration);
-    m_timeRemainingDisplay->setInnerText(timeString, ec);
+    m_currentTimeDisplay->setCurrentValue(now);
+    m_timeRemainingDisplay->setCurrentValue(now - duration);
 }
 
 void RenderMedia::updateControlVisibility() 
index 2ce80c7..602cd26 100644 (file)
@@ -62,8 +62,6 @@ public:
     HTMLMediaElement* mediaElement() const;
     MediaPlayer* player() const;
 
-    static String formatTime(float time);
-
     bool shouldShowTimeDisplayControls() const;
 
     void updateFromElement();
index dfd09b7..1435092 100644 (file)
@@ -1,3 +1,14 @@
+2009-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <video> and <audio> controller should be accessible
+        https://bugs.webkit.org/show_bug.cgi?id=28081
+
+        Add localized strings for media controller accessiblility.
+
+        * English.lproj/Localizable.strings:
+
 2009-08-20  Chris Fleizach  <cfleizach@apple.com>
 
         Reviewed by Darin Adler.
index 7f92032..608c1f3 100644 (file)
Binary files a/WebKit/English.lproj/Localizable.strings and b/WebKit/English.lproj/Localizable.strings differ
index d31a31d..54e3d9d 100644 (file)
@@ -1,3 +1,16 @@
+2009-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <video> and <audio> controller should be accessible
+        https://bugs.webkit.org/show_bug.cgi?id=28081
+
+        * WebCoreSupport/WebViewFactory.mm:
+        (-[WebViewFactory localizedMediaControlElementString:]):
+        (-[WebViewFactory localizedMediaControlElementHelpText:]):
+        (-[WebViewFactory localizedMediaTimeDescription:]):
+            New.
+
 2009-08-24  Simon Fraser  <simon.fraser@apple.com>
 
         Reviewed by NOBODY (build fix)
index 9e9466a..9be8bfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2009 Apple Computer, Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
     return UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast");
 }
 
+- (NSString*)localizedMediaControlElementString:(NSString*)name
+{
+    if ([name isEqualToString:@"AudioElement"])
+        return UI_STRING("audio element controller", "accessibility role description for audio element controller");
+    if ([name isEqualToString:@"VideoElement"])
+        return UI_STRING("video element controller", "accessibility role description for video element controller");
+
+    if ([name isEqualToString:@"MuteButton"])
+        return UI_STRING("mute", "accessibility role description for mute button");
+    if ([name isEqualToString:@"UnMuteButton"])
+        return UI_STRING("unmute", "accessibility role description for turn mute off button");
+    if ([name isEqualToString:@"PlayButton"])
+        return UI_STRING("play", "accessibility role description for play button");
+    if ([name isEqualToString:@"PauseButton"])
+        return UI_STRING("pause", "accessibility role description for pause button");
+    if ([name isEqualToString:@"Slider"])
+        return UI_STRING("movie time", "accessibility role description for timeline slider");
+    if ([name isEqualToString:@"SliderThumb"])
+        return UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb");
+    if ([name isEqualToString:@"RewindButton"])
+        return UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button");
+    if ([name isEqualToString:@"ReturnToRealtimeButton"])
+        return UI_STRING("return to realtime", "accessibility role description for return to real time button");
+    if ([name isEqualToString:@"CurrentTimeDisplay"])
+        return UI_STRING("elapsed time", "accessibility role description for elapsed time display");
+    if ([name isEqualToString:@"TimeRemainingDisplay"])
+        return UI_STRING("remaining time", "accessibility role description for time remaining display");
+    if ([name isEqualToString:@"StatusDisplay"])
+        return UI_STRING("status", "accessibility role description for movie status");
+    if ([name isEqualToString:@"FullscreenButton"])
+        return UI_STRING("fullscreen", "accessibility role description for enter fullscreen button");
+    if ([name isEqualToString:@"SeekForwardButton"])
+        return UI_STRING("fast forward", "accessibility role description for fast forward button");
+    if ([name isEqualToString:@"SeekBackButton"])
+        return UI_STRING("fast reverse", "accessibility role description for fast reverse button");
+    ASSERT_NOT_REACHED();
+    return @"";
+}
+
+- (NSString*)localizedMediaControlElementHelpText:(NSString*)name
+{
+    if ([name isEqualToString:@"AudioElement"])
+        return UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller");
+    if ([name isEqualToString:@"VideoElement"])
+        return UI_STRING("video element playback controls and status display", "accessibility role description for video element controller");
+
+    if ([name isEqualToString:@"MuteButton"])
+        return UI_STRING("mute audio tracks", "accessibility help text for mute button");
+    if ([name isEqualToString:@"UnMuteButton"])
+        return UI_STRING("unmute audio tracks", "accessibility help text for un mute button");
+    if ([name isEqualToString:@"PlayButton"])
+        return UI_STRING("begin playback", "accessibility help text for play button");
+    if ([name isEqualToString:@"PauseButton"])
+        return UI_STRING("pause playback", "accessibility help text for pause button");
+    if ([name isEqualToString:@"Slider"])
+        return UI_STRING("movie time scrubber", "accessibility help text for timeline slider");
+    if ([name isEqualToString:@"SliderThumb"])
+        return UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb");
+    if ([name isEqualToString:@"RewindButton"])
+        return UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button");
+    if ([name isEqualToString:@"ReturnToRealtimeButton"])
+        return UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button");
+    if ([name isEqualToString:@"CurrentTimeDisplay"])
+        return UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display");
+    if ([name isEqualToString:@"TimeRemainingDisplay"])
+        return UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display");
+    if ([name isEqualToString:@"StatusDisplay"])
+        return UI_STRING("current movie status", "accessibility help text for movie status display");
+    if ([name isEqualToString:@"SeekBackButton"])
+        return UI_STRING("seek quickly back", "accessibility help text for fast rewind button");
+    if ([name isEqualToString:@"SeekForwardButton"])
+        return UI_STRING("seek quickly forward", "accessibility help text for fast forward button");
+    if ([name isEqualToString:@"FullscreenButton"])
+        return UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button");
+    ASSERT_NOT_REACHED();
+    return @"";
+}
+
+- (NSString*)localizedMediaTimeDescription:(float)time
+{
+    if (!isfinite(time))
+        return UI_STRING("indefinite time", "string for an indefinite movie time");
+
+    int seconds = (int)fabsf(time); 
+    int days = seconds / (60 * 60 * 24);
+    int hours = seconds / (60 * 60);
+    int minutes = (seconds / 60) % 60;
+    seconds %= 60;
+
+    if (days)
+        return [NSString stringWithFormat:UI_STRING("date.format.for.days", "string for days, hours, minutes & seconds"), days, hours, minutes, seconds];
+    else if (hours)
+        return [NSString stringWithFormat:UI_STRING("date.format.for.hours", "string for hours, minutes & seconds"), hours, minutes, seconds];
+    else if (minutes)
+        return [NSString stringWithFormat:UI_STRING("date.format.for.minutes", "string for minutes & seconds"), minutes, seconds];
+
+    return [NSString stringWithFormat:UI_STRING("date.format.for.seconds", "string for seconds"), seconds];
+}
+
 @end
index ce44519..f13f900 100644 (file)
@@ -1,3 +1,16 @@
+2009-08-25  Eric Carlson  <eric.carlson@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        <video> and <audio> controller should be accessible
+        https://bugs.webkit.org/show_bug.cgi?id=28081
+
+        * WebCoreLocalizedStrings.cpp:
+        (WebCore::localizedMediaControlElementString):
+        (WebCore::localizedMediaControlElementHelpText):
+        (WebCore::localizedMediaTimeDescription):
+            New.
+
 2009-08-25  Brent Fulgham  <bfulgham@webkit.org>
 
         Build fix for Windows.
index 389b1c0..03d03e7 100644 (file)
@@ -94,8 +94,6 @@ String WebCore::AXLinkActionVerb() { return String(LPCTSTR_UI_STRING("jump", "Ve
 String WebCore::unknownFileSizeText() { return String(LPCTSTR_UI_STRING("Unknown", "Unknown filesize FTP directory listing item")); }
 String WebCore::uploadFileText() { return String(LPCTSTR_UI_STRING("Upload file", "(Windows) Form submit file upload dialog title")); }
 String WebCore::allFilesText() { return String(LPCTSTR_UI_STRING("All Files", "(Windows) Form submit file upload all files pop-up")); }
-String WebCore::mediaElementLoadingStateText() { return String(LPCTSTR_UI_STRING("Loading...", "Media controller status message when the media is loading")); }
-String WebCore::mediaElementLiveBroadcastStateText() { return String(LPCTSTR_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast")); }
 
 String WebCore::imageTitle(const String& filename, const IntSize& size) 
 { 
@@ -114,3 +112,122 @@ String multipleFileUploadText(unsigned numberOfFiles)
 
     return result.get();
 }
+
+#if ENABLE(VIDEO)
+String WebCore::mediaElementLoadingStateText() { return String(LPCTSTR_UI_STRING("Loading...", "Media controller status message when the media is loading")); }
+String WebCore::mediaElementLiveBroadcastStateText() { return String(LPCTSTR_UI_STRING("Live Broadcast", "Media controller status message when watching a live broadcast")); }
+
+String WebCore::localizedMediaControlElementString(const String& name)
+{
+    if (name == "AudioElement")
+        return String(LPCTSTR_UI_STRING("audio element controller", "accessibility role description for audio element controller"));
+    if (name == "VideoElement")
+        return String(LPCTSTR_UI_STRING("video element controller", "accessibility role description for video element controller"));
+    if (name == "MuteButton")
+        return String(LPCTSTR_UI_STRING("mute", "accessibility role description for mute button"));
+    if (name == "UnMuteButton")
+        return String(LPCTSTR_UI_STRING("unmute", "accessibility role description for turn mute off button"));
+    if (name == "PlayButton")
+        return String(LPCTSTR_UI_STRING("play", "accessibility role description for play button"));
+    if (name == "PauseButton")
+        return String(LPCTSTR_UI_STRING("pause", "accessibility role description for pause button"));
+    if (name == "Slider")
+        return String(LPCTSTR_UI_STRING("movie time", "accessibility role description for timeline slider"));
+    if (name == "SliderThumb")
+        return String(LPCTSTR_UI_STRING("timeline slider thumb", "accessibility role description for timeline thumb"));
+    if (name == "RewindButton")
+        return String(LPCTSTR_UI_STRING("back 30 seconds", "accessibility role description for seek back 30 seconds button"));
+    if (name == "ReturnToRealtimeButton")
+        return String(LPCTSTR_UI_STRING("return to realtime", "accessibility role description for return to real time button"));
+    if (name == "CurrentTimeDisplay")
+        return String(LPCTSTR_UI_STRING("elapsed time", "accessibility role description for elapsed time display"));
+    if (name == "TimeRemainingDisplay")
+        return String(LPCTSTR_UI_STRING("remaining time", "accessibility role description for time remaining display"));
+    if (name == "StatusDisplay")
+        return String(LPCTSTR_UI_STRING("status", "accessibility role description for movie status"));
+    if (name == "FullscreenButton")
+        return String(LPCTSTR_UI_STRING("fullscreen", "accessibility role description for enter fullscreen button"));
+    if (name == "SeekForwardButton")
+        return String(LPCTSTR_UI_STRING("fast forward", "accessibility role description for fast forward button"));
+    if (name == "SeekBackButton")
+        return String(LPCTSTR_UI_STRING("fast reverse", "accessibility role description for fast reverse button"));
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+String WebCore::localizedMediaControlElementHelpText(const String& name)
+{
+    if (name == "AudioElement")
+        return String(LPCTSTR_UI_STRING("audio element playback controls and status display", "accessibility role description for audio element controller"));
+    if (name == "VideoElement")
+        return String(LPCTSTR_UI_STRING("video element playback controls and status display", "accessibility role description for video element controller"));
+    if (name == "MuteButton")
+        return String(LPCTSTR_UI_STRING("mute audio tracks", "accessibility help text for mute button"));
+    if (name == "UnMuteButton")
+        return String(LPCTSTR_UI_STRING("unmute audio tracks", "accessibility help text for un mute button"));
+    if (name == "PlayButton")
+        return String(LPCTSTR_UI_STRING("begin playback", "accessibility help text for play button"));
+    if (name == "PauseButton")
+        return String(LPCTSTR_UI_STRING("pause playback", "accessibility help text for pause button"));
+    if (name == "Slider")
+        return String(LPCTSTR_UI_STRING("movie time scrubber", "accessibility help text for timeline slider"));
+    if (name == "SliderThumb")
+        return String(LPCTSTR_UI_STRING("movie time scrubber thumb", "accessibility help text for timeline slider thumb"));
+    if (name == "RewindButton")
+        return String(LPCTSTR_UI_STRING("seek movie back 30 seconds", "accessibility help text for jump back 30 seconds button"));
+    if (name == "ReturnToRealtimeButton")
+        return String(LPCTSTR_UI_STRING("return streaming movie to real time", "accessibility help text for return streaming movie to real time button"));
+    if (name == "CurrentTimeDisplay")
+        return String(LPCTSTR_UI_STRING("current movie time in seconds", "accessibility help text for elapsed time display"));
+    if (name == "TimeRemainingDisplay")
+        return String(LPCTSTR_UI_STRING("number of seconds of movie remaining", "accessibility help text for remaining time display"));
+    if (name == "StatusDisplay")
+        return String(LPCTSTR_UI_STRING("current movie status", "accessibility help text for movie status display"));
+    if (name == "SeekBackButton")
+        return String(LPCTSTR_UI_STRING("seek quickly back", "accessibility help text for fast rewind button"));
+    if (name == "SeekForwardButton")
+        return String(LPCTSTR_UI_STRING("seek quickly forward", "accessibility help text for fast forward button"));
+    if (name == "FullscreenButton")
+        return String(LPCTSTR_UI_STRING("Play movie in fullscreen mode", "accessibility help text for enter fullscreen button"));
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+String WebCore::localizedMediaTimeDescription(float time)
+{
+    if (!isfinite(time))
+        return String(LPCTSTR_UI_STRING("indefinite time", "string for an indefinite movie time"));
+
+    int seconds = (int)fabsf(time);
+    int days = seconds / (60 * 60 * 24);
+    int hours = seconds / (60 * 60);
+    int minutes = (seconds / 60) % 60;
+    seconds %= 60;
+
+    if (days) {
+        static RetainPtr<CFStringRef> format(AdoptCF, UI_STRING("date.format.for.days", "string for days, hours, minutes & seconds"));
+        RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormat(0, 0, format.get(), days, hours, minutes, seconds));
+        return result.get();
+    }
+
+    if (hours) {
+        static RetainPtr<CFStringRef> format(AdoptCF, UI_STRING("date.format.for.hours", "string for hours, minutes & seconds"));
+        RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormat(0, 0, format.get(), hours, minutes, seconds));
+        return result.get();
+    }
+
+    if (minutes) {
+        static RetainPtr<CFStringRef> format(AdoptCF, UI_STRING("date.format.for.minutes", "string for minutes & seconds"));
+        RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormat(0, 0, format.get(), minutes, seconds));
+        return result.get();
+    }
+
+    static RetainPtr<CFStringRef> format(AdoptCF, UI_STRING("date.format.for.seconds", "string for seconds"));
+    RetainPtr<CFStringRef> result(AdoptCF, CFStringCreateWithFormat(0, 0, format.get(), seconds));
+    return result.get();
+}
+
+#endif  // ENABLE(VIDEO)
+