Title: [150371] trunk
Revision
150371
Author
grao...@apple.com
Date
2013-05-20 09:47:07 -0700 (Mon, 20 May 2013)

Log Message

[Mac] captions menu should behave more like a menu
https://bugs.webkit.org/show_bug.cgi?id=116436

Reviewed by Eric Carlson.

Let the captions menu behave more like a native Mac menu by hiding it when
clicking anywhere on the page and preventing the page from scrolling when
attempting to scroll the captions menu when it cannot scroll in the requested
direction.

Test: media/video-controls-captions-trackmenu-hide-on-click-outside.html

* dom/EventListener.h:
Add the new MediaControlsAppleEventListenerType.

* html/shadow/MediaControlsApple.cpp:
(WebCore::MediaControlsApple::defaultEventHandler):
(WebCore::MediaControlsApple::hide):
(WebCore::MediaControlsApple::makeTransparent):
(WebCore::MediaControlsApple::changedClosedCaptionsVisibility):
(WebCore::MediaControlsApple::reportedError):
(WebCore::MediaControlsApple::toggleClosedCaptionTrackList):
Use the hideClosedCaptionTrackList() and showClosedCaptionTrackList()
methods to hide and show the captions menu instead of calling hide()
and show() directly on m_closedCaptionsContainer.

(WebCore::MediaControlsApple::showClosedCaptionTrackList):
Show the m_closedCaptionsContainer and register a "mousewheel" event
listener on it as well as a "click" event listener on the entire document.

(WebCore::MediaControlsApple::hideClosedCaptionTrackList):
Hide the m_closedCaptionsContainer and remove the "mousewheel" event
listener on it as well as the "click" event listener on the entire document.

(WebCore::MediaControlsApple::shouldClosedCaptionsContainerPreventPageScrolling):
New private utility to determine whether the m_closedCaptionsContainer can scroll
in the provided scroll direction.

(WebCore::MediaControlsApple::eventListener):
Obtain the event listener used for "mousewheel" and "click" event handlers.

(WebCore::MediaControlsAppleEventListener::handleEvent):
Event handler for the "mousewheel" and "click" events. If we get a "click" event, we
toggle the captions menu visibility and if we get a "mousewheel" event, we call into
shouldClosedCaptionsContainerPreventPageScrolling() to see if we can scroll in the
current scroll direction, and if not prevent the event from resulting in a scroll by
calling preventDefault().

(WebCore::MediaControlsAppleEventListener::operator==):
Required for the successful subclassing of EventListener.

* html/shadow/MediaControlsApple.h:
(MediaControlsAppleEventListener):
(WebCore::MediaControlsAppleEventListener::create):
(WebCore::MediaControlsAppleEventListener::cast):
(WebCore::MediaControlsAppleEventListener::MediaControlsAppleEventListener):
New subclass of EventListener required to provide a custom event listener for the
"mousewheel" and "click" events registered in showClosedCaptionTrackList() and
hideClosedCaptionTrackList().

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (150370 => 150371)


--- trunk/LayoutTests/ChangeLog	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/LayoutTests/ChangeLog	2013-05-20 16:47:07 UTC (rev 150371)
@@ -1,3 +1,20 @@
+2013-05-20  Antoine Quint  <grao...@apple.com>
+
+        [Mac] captions menu should behave more like a menu
+        https://bugs.webkit.org/show_bug.cgi?id=116436
+
+        Reviewed by Eric Carlson.
+
+        New test that checks that the caption menu hides when clicking outside
+        of the bounds of the media element.
+
+        * media/video-controls-captions-trackmenu-hide-on-click-outside-expected.txt: Added.
+        * media/video-controls-captions-trackmenu-hide-on-click-outside.html: Added.
+        * platform/efl/TestExpectations:
+        * platform/gtk/TestExpectations:
+        * platform/qt/TestExpectations:
+        * platform/win/TestExpectations:
+
 2013-05-18  Rashmi Shyamasundar  <rashmi...@samsung.com>
 
         [Cairo] Canvas-shadow behavior is not being as expected

Added: trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside-expected.txt (0 => 150371)


--- trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside-expected.txt	2013-05-20 16:47:07 UTC (rev 150371)
@@ -0,0 +1,12 @@
+Test that we are able to trigger the list of captions, and then click elsewhere to hide it.
+
+EVENT(canplaythrough)
+
+*** Set the user language preference.
+RUN(internals.setUserPreferredLanguages(['en']))
+*** Track menu should be visible block
+EXPECTED (displayStyle == 'block') OK
+*** Track menu should be invisible none
+EXPECTED (displayStyle == 'none') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside.html (0 => 150371)


--- trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside.html	                        (rev 0)
+++ trunk/LayoutTests/media/video-controls-captions-trackmenu-hide-on-click-outside.html	2013-05-20 16:47:07 UTC (rev 150371)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Test dismissal of track menu when clicking anywhere in the page</title>
+        <script src=""
+        <script src=""
+        <script src=""
+        <script src=""
+        <script>
+            var displayStyle;
+
+            if (window.testRunner)
+                testRunner.dumpAsText();
+
+            function startTest()
+            {
+                testMenuIsVisible();
+            }
+
+            function testMenuIsVisible()
+            {
+                var trackListElement = getTrackListElement();
+                displayStyle = window.getComputedStyle(trackListElement.parentNode).display;
+                consoleWrite("*** Track menu should be visible " + displayStyle);
+                testExpected("displayStyle", "block");
+                // Now, click outside of the video to test that the track menu hides when clicking anywhere else.
+                eventSender.mouseMoveTo(1, 1);
+                eventSender.mouseDown();
+                eventSender.mouseUp();
+                testMenuIsInvisible();
+            }
+
+            function testMenuIsInvisible()
+            {
+                var trackListElement = getTrackListElement();
+                displayStyle = window.getComputedStyle(trackListElement.parentNode).display;
+                consoleWrite("*** Track menu should be invisible " + displayStyle);
+                testExpected("displayStyle", "none");
+                endTest();
+            }
+
+            function start()
+            {
+                findMediaElement();
+                video.src = "" 'content/test');
+                waitForEvent('canplaythrough', function () { startTrackMenuTest(startTest); });
+            }
+        </script>
+    </head>
+
+    <body _onload_="start()">
+        <p>Test that we are able to trigger the list of captions, and then click elsewhere to hide it.</p>
+        <video width="500" height="300" controls>
+            <track kind="captions" src="" srclang="en">
+        </video>
+    </body>
+</html>
+

Modified: trunk/LayoutTests/platform/efl/TestExpectations (150370 => 150371)


--- trunk/LayoutTests/platform/efl/TestExpectations	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/LayoutTests/platform/efl/TestExpectations	2013-05-20 16:47:07 UTC (rev 150371)
@@ -1618,6 +1618,7 @@
 webkit.org/b/101670 media/video-controls-captions-trackmenu-sorted.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-localized.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click.html [ Skip ]
+webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click-outside.html [ Skip ]
 webkit.org/b/101670 media/track/track-user-preferences.html [ Skip ]
 
 # Fails until we enable the Resource Timing API.

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (150370 => 150371)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2013-05-20 16:47:07 UTC (rev 150371)
@@ -744,6 +744,7 @@
 webkit.org/b/101670 media/video-controls-captions-trackmenu-sorted.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-localized.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click.html [ Skip ]
+webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click-outside.html [ Skip ]
 webkit.org/b/101670 media/track/track-user-preferences.html [ Skip ]
 
 webkit.org/b/107194 storage/indexeddb/database-quota.html [ Timeout ]

Modified: trunk/LayoutTests/platform/qt/TestExpectations (150370 => 150371)


--- trunk/LayoutTests/platform/qt/TestExpectations	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/LayoutTests/platform/qt/TestExpectations	2013-05-20 16:47:07 UTC (rev 150371)
@@ -2597,6 +2597,7 @@
 webkit.org/b/101670 media/video-controls-captions-trackmenu-sorted.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-localized.html [ Skip ]
 webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click.html [ Skip ]
+webkit.org/b/101670 media/video-controls-captions-trackmenu-hide-on-click-outside.html [ Skip ]
 webkit.org/b/101670 media/track/track-user-preferences.html [ Skip ]
 
 # New, but failing test

Modified: trunk/LayoutTests/platform/win/TestExpectations (150370 => 150371)


--- trunk/LayoutTests/platform/win/TestExpectations	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/LayoutTests/platform/win/TestExpectations	2013-05-20 16:47:07 UTC (rev 150371)
@@ -2559,6 +2559,7 @@
 media/video-controls-captions-trackmenu-sorted.html
 media/video-controls-captions-trackmenu.html
 media/video-controls-captions-trackmenu-hide-on-click.html
+media/video-controls-captions-trackmenu-hide-on-click-outside.html
 media/video-controls-visible-exiting-fullscreen.html
 
 # Fails on JSC platforms due to gc timing issues

Modified: trunk/Source/WebCore/ChangeLog (150370 => 150371)


--- trunk/Source/WebCore/ChangeLog	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/Source/WebCore/ChangeLog	2013-05-20 16:47:07 UTC (rev 150371)
@@ -1,3 +1,65 @@
+2013-05-20  Antoine Quint  <grao...@apple.com>
+
+        [Mac] captions menu should behave more like a menu
+        https://bugs.webkit.org/show_bug.cgi?id=116436
+
+        Reviewed by Eric Carlson.
+
+        Let the captions menu behave more like a native Mac menu by hiding it when
+        clicking anywhere on the page and preventing the page from scrolling when
+        attempting to scroll the captions menu when it cannot scroll in the requested
+        direction.
+
+        Test: media/video-controls-captions-trackmenu-hide-on-click-outside.html
+
+        * dom/EventListener.h:
+        Add the new MediaControlsAppleEventListenerType.
+
+        * html/shadow/MediaControlsApple.cpp:
+        (WebCore::MediaControlsApple::defaultEventHandler):
+        (WebCore::MediaControlsApple::hide):
+        (WebCore::MediaControlsApple::makeTransparent):
+        (WebCore::MediaControlsApple::changedClosedCaptionsVisibility):
+        (WebCore::MediaControlsApple::reportedError):
+        (WebCore::MediaControlsApple::toggleClosedCaptionTrackList):
+        Use the hideClosedCaptionTrackList() and showClosedCaptionTrackList()
+        methods to hide and show the captions menu instead of calling hide()
+        and show() directly on m_closedCaptionsContainer.
+
+        (WebCore::MediaControlsApple::showClosedCaptionTrackList):
+        Show the m_closedCaptionsContainer and register a "mousewheel" event
+        listener on it as well as a "click" event listener on the entire document.
+
+        (WebCore::MediaControlsApple::hideClosedCaptionTrackList):
+        Hide the m_closedCaptionsContainer and remove the "mousewheel" event
+        listener on it as well as the "click" event listener on the entire document.
+
+        (WebCore::MediaControlsApple::shouldClosedCaptionsContainerPreventPageScrolling):
+        New private utility to determine whether the m_closedCaptionsContainer can scroll
+        in the provided scroll direction.
+
+        (WebCore::MediaControlsApple::eventListener):
+        Obtain the event listener used for "mousewheel" and "click" event handlers.
+
+        (WebCore::MediaControlsAppleEventListener::handleEvent):
+        Event handler for the "mousewheel" and "click" events. If we get a "click" event, we
+        toggle the captions menu visibility and if we get a "mousewheel" event, we call into
+        shouldClosedCaptionsContainerPreventPageScrolling() to see if we can scroll in the
+        current scroll direction, and if not prevent the event from resulting in a scroll by
+        calling preventDefault().
+
+        (WebCore::MediaControlsAppleEventListener::operator==):
+        Required for the successful subclassing of EventListener.
+
+        * html/shadow/MediaControlsApple.h:
+        (MediaControlsAppleEventListener):
+        (WebCore::MediaControlsAppleEventListener::create):
+        (WebCore::MediaControlsAppleEventListener::cast):
+        (WebCore::MediaControlsAppleEventListener::MediaControlsAppleEventListener):
+        New subclass of EventListener required to provide a custom event listener for the
+        "mousewheel" and "click" events registered in showClosedCaptionTrackList() and
+        hideClosedCaptionTrackList().
+
 2013-05-18  Rashmi Shyamasundar  <rashmi...@samsung.com>
 
         [Cairo] Canvas-shadow behavior is not being as expected

Modified: trunk/Source/WebCore/dom/EventListener.h (150370 => 150371)


--- trunk/Source/WebCore/dom/EventListener.h	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/Source/WebCore/dom/EventListener.h	2013-05-20 16:47:07 UTC (rev 150371)
@@ -43,7 +43,8 @@
             ConditionEventListenerType,
             GObjectEventListenerType,
             NativeEventListenerType,
-            SVGTRefTargetEventListenerType
+            SVGTRefTargetEventListenerType,
+            MediaControlsAppleEventListenerType 
         };
 
         virtual ~EventListener() { }

Modified: trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp (150370 => 150371)


--- trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/Source/WebCore/html/shadow/MediaControlsApple.cpp	2013-05-20 16:47:07 UTC (rev 150371)
@@ -38,6 +38,7 @@
 #include "Page.h"
 #include "RenderTheme.h"
 #include "Text.h"
+#include "WheelEvent.h"
 
 #if ENABLE(VIDEO_TRACK)
 #include "TextTrackCue.h"
@@ -278,7 +279,7 @@
 {
     if (event->type() == eventNames().clickEvent) {
         if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing()) {
-            m_closedCaptionsContainer->hide();
+            hideClosedCaptionTrackList();
             event->setDefaultHandled();
         }
     }
@@ -291,7 +292,7 @@
     MediaControls::hide();
     m_volumeSliderContainer->hide();
     if (m_closedCaptionsContainer)
-        m_closedCaptionsContainer->hide();
+        hideClosedCaptionTrackList();
 }
 
 void MediaControlsApple::makeTransparent()
@@ -299,14 +300,14 @@
     MediaControls::makeTransparent();
     m_volumeSliderContainer->hide();
     if (m_closedCaptionsContainer)
-        m_closedCaptionsContainer->hide();
+        hideClosedCaptionTrackList();
 }
 
 void MediaControlsApple::changedClosedCaptionsVisibility()
 {
     MediaControls::changedClosedCaptionsVisibility();
     if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing())
-        m_closedCaptionsContainer->hide();
+        hideClosedCaptionTrackList();
 
 }
 
@@ -414,7 +415,7 @@
     if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
         m_toggleClosedCaptionsButton->hide();
     if (m_closedCaptionsContainer)
-        m_closedCaptionsContainer->hide();
+        hideClosedCaptionTrackList();
 }
 
 void MediaControlsApple::updateStatusDisplay()
@@ -498,15 +499,51 @@
 
     if (m_closedCaptionsContainer) {
         if (m_closedCaptionsContainer->isShowing())
-            m_closedCaptionsContainer->hide();
+            hideClosedCaptionTrackList();
         else {
             if (m_closedCaptionsTrackList)
                 m_closedCaptionsTrackList->updateDisplay();
-            m_closedCaptionsContainer->show();
+            showClosedCaptionTrackList();
         }
     }
 }
 
+void MediaControlsApple::showClosedCaptionTrackList()
+{
+    if (!m_closedCaptionsContainer || m_closedCaptionsContainer->isShowing())
+        return;
+
+    m_closedCaptionsContainer->show();
+
+    RefPtr<EventListener> listener = eventListener();
+    m_closedCaptionsContainer->addEventListener(eventNames().mousewheelEvent, listener, true);
+    document()->addEventListener(eventNames().clickEvent, listener, true);
+}
+
+void MediaControlsApple::hideClosedCaptionTrackList()
+{
+    if (!m_closedCaptionsContainer || !m_closedCaptionsContainer->isShowing())
+        return;
+
+    m_closedCaptionsContainer->hide();
+
+    EventListener* listener = eventListener().get();
+    m_closedCaptionsContainer->removeEventListener(eventNames().mousewheelEvent, listener, true);
+    document()->removeEventListener(eventNames().clickEvent, listener, true);
+}
+
+bool MediaControlsApple::shouldClosedCaptionsContainerPreventPageScrolling(int wheelDeltaY)
+{
+    int scrollTop = m_closedCaptionsContainer->scrollTop();
+    // Scrolling down.
+    if (wheelDeltaY < 0 && (scrollTop + m_closedCaptionsContainer->offsetHeight()) >= m_closedCaptionsContainer->scrollHeight())
+        return true;
+    // Scrolling up.
+    if (wheelDeltaY > 0 && scrollTop <= 0)
+        return true;
+    return false;
+}
+
 void MediaControlsApple::closedCaptionTracksChanged()
 {
     if (m_toggleClosedCaptionsButton) {
@@ -517,6 +554,34 @@
     }
 }
 
+PassRefPtr<MediaControlsAppleEventListener> MediaControlsApple::eventListener()
+{
+    if (!m_eventListener)
+        m_eventListener = MediaControlsAppleEventListener::create(this);
+    return m_eventListener;
 }
 
+// --------
+
+void MediaControlsAppleEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+{
+    if (event->type() == eventNames().clickEvent && !m_mediaControls->contains(event->target()->toNode()))
+        m_mediaControls->toggleClosedCaptionTrackList();
+
+    if (event->type() == eventNames().mousewheelEvent && event->hasInterface(eventNames().interfaceForWheelEvent)) {
+        WheelEvent* wheelEvent = static_cast<WheelEvent*>(event);
+        if (m_mediaControls->shouldClosedCaptionsContainerPreventPageScrolling(wheelEvent->wheelDeltaY()))
+            event->preventDefault();
+    }
+}
+
+bool MediaControlsAppleEventListener::operator==(const EventListener& listener)
+{
+    if (const MediaControlsAppleEventListener* mediaControlsAppleEventListener = MediaControlsAppleEventListener::cast(&listener))
+        return m_mediaControls == mediaControlsAppleEventListener->m_mediaControls;
+    return false;
+}
+
+}
+
 #endif

Modified: trunk/Source/WebCore/html/shadow/MediaControlsApple.h (150370 => 150371)


--- trunk/Source/WebCore/html/shadow/MediaControlsApple.h	2013-05-20 16:39:30 UTC (rev 150370)
+++ trunk/Source/WebCore/html/shadow/MediaControlsApple.h	2013-05-20 16:47:07 UTC (rev 150371)
@@ -33,6 +33,32 @@
 
 namespace WebCore {
 
+class MediaControlsApple;
+
+class MediaControlsAppleEventListener : public EventListener {
+public:
+    static PassRefPtr<MediaControlsAppleEventListener> create(MediaControlsApple* mediaControls) { return adoptRef(new MediaControlsAppleEventListener(mediaControls)); }
+    static const MediaControlsAppleEventListener* cast(const EventListener* listener)
+    {
+        return listener->type() == MediaControlsAppleEventListenerType
+            ? static_cast<const MediaControlsAppleEventListener*>(listener)
+            : 0;
+    }
+
+    virtual bool operator==(const EventListener& other);
+
+private:
+    MediaControlsAppleEventListener(MediaControlsApple* mediaControls)
+        : EventListener(MediaControlsAppleEventListenerType)
+        , m_mediaControls(mediaControls)
+    {
+    }
+
+    virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+    MediaControlsApple* m_mediaControls;
+};
+
 class MediaControlsApple : public MediaControls {
 public:
     static PassRefPtr<MediaControlsApple> createControls(Document*);
@@ -62,11 +88,17 @@
     virtual void toggleClosedCaptionTrackList() OVERRIDE;
     virtual void closedCaptionTracksChanged() OVERRIDE;
 
+    bool shouldClosedCaptionsContainerPreventPageScrolling(int wheelDeltaY);
+
 private:
     MediaControlsApple(Document*);
 
     virtual void defaultEventHandler(Event*) OVERRIDE;
+    PassRefPtr<MediaControlsAppleEventListener> eventListener();
 
+    void showClosedCaptionTrackList();
+    void hideClosedCaptionTrackList();
+
     MediaControlRewindButtonElement* m_rewindButton;
     MediaControlReturnToRealtimeButtonElement* m_returnToRealTimeButton;
     MediaControlStatusDisplayElement* m_statusDisplay;
@@ -81,6 +113,7 @@
     MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;
     MediaControlFullscreenVolumeSliderElement* m_fullScreenVolumeSlider;
     MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
+    RefPtr<MediaControlsAppleEventListener> m_eventListener;
 };
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to