2011-05-28 Jer Noble <jer.noble@apple.com>
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 May 2011 19:41:14 +0000 (19:41 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 May 2011 19:41:14 +0000 (19:41 +0000)
        Reviewed by Maciej Stachowiak.

        Mouse clicks propagate outside full-screen media controls.
        https://bugs.webkit.org/show_bug.cgi?id=61689

        Mouse click events are propagating out of the media controls, so mouse click
        listeners registered on the video element are getting fired when the user
        clicks on media controller buttons.  By default, block propagation of click
        events from MediaControlElements by overriding preDispatchEventHandler, and
        convert all instances of defaultEventHandler -> preDispatchEventHandler.  Change
        all calls of event->setDefaultHandled() to event->stopPropagation().

        * html/shadow/MediaControlElements.cpp:
        (WebCore::MediaControlElement::preDispatchEventHandler): Added.  Block
            propagation of all mouse click events.
        (WebCore::MediaControlVolumeSliderContainerElement::preDispatchEventHandler):
            Renamed from setDefaultHandled.
        (WebCore::MediaControlMuteButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlPanelMuteButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlPlayButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlSeekButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlRewindButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlReturnToRealtimeButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlToggleClosedCaptionsButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlTimelineElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlVolumeSliderElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlFullscreenButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlFullscreenVolumeMinButtonElement::preDispatchEventHandler): Ditto.
        (WebCore::MediaControlFullscreenVolumeMaxButtonElement::preDispatchEventHandler): Ditto.
        * html/shadow/MediaControlElements.h:

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

Source/WebCore/ChangeLog
Source/WebCore/html/shadow/MediaControlElements.cpp
Source/WebCore/html/shadow/MediaControlElements.h

index 06d08e2..4a72c73 100644 (file)
@@ -1,3 +1,36 @@
+2011-05-28  Jer Noble  <jer.noble@apple.com>
+
+        Reviewed by Maciej Stachowiak.
+
+        Mouse clicks propagate outside full-screen media controls.
+        https://bugs.webkit.org/show_bug.cgi?id=61689
+
+        Mouse click events are propagating out of the media controls, so mouse click
+        listeners registered on the video element are getting fired when the user
+        clicks on media controller buttons.  By default, block propagation of click 
+        events from MediaControlElements by overriding preDispatchEventHandler, and
+        convert all instances of defaultEventHandler -> preDispatchEventHandler.  Change
+        all calls of event->setDefaultHandled() to event->stopPropagation().
+
+        * html/shadow/MediaControlElements.cpp:
+        (WebCore::MediaControlElement::preDispatchEventHandler): Added.  Block 
+            propagation of all mouse click events.
+        (WebCore::MediaControlVolumeSliderContainerElement::preDispatchEventHandler):
+            Renamed from setDefaultHandled.
+        (WebCore::MediaControlMuteButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlPanelMuteButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlPlayButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlSeekButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlRewindButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlReturnToRealtimeButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlToggleClosedCaptionsButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlTimelineElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlVolumeSliderElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlFullscreenButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlFullscreenVolumeMinButtonElement::preDispatchEventHandler): Ditto.
+        (WebCore::MediaControlFullscreenVolumeMaxButtonElement::preDispatchEventHandler): Ditto.
+        * html/shadow/MediaControlElements.h:
+
 2011-05-28  Gavin Peters  <gavinp@chromium.org>
 
         Reviewed by Adam Barth.
index 45a1577..4f590a7 100644 (file)
@@ -75,6 +75,14 @@ MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement)
 {
 }
 
+void* MediaControlElement::preDispatchEventHandler(Event* event)
+{
+    if (event->type() == eventNames().clickEvent)
+        event->stopPropagation();
+    
+    return 0;
+}
+
 static const String& displayString()
 {
     DEFINE_STATIC_LOCAL(String, s, ("display"));
@@ -191,20 +199,21 @@ RenderObject* MediaControlVolumeSliderContainerElement::createRenderer(RenderAre
     return new (arena) RenderMediaVolumeSliderContainer(this);
 }
 
-void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
+void* MediaControlVolumeSliderContainerElement::preDispatchEventHandler(Event* event)
 {
     if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
-        return;
+        return 0;
 
     // Poor man's mouseleave event detection.
     MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
     if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
-        return;
+        return 0;
 
     if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
-        return;
+        return 0;
 
     hide();
+    return 0;
 }
 
 
@@ -320,14 +329,14 @@ inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaEle
 {
 }
 
-void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
+void* MediaControlMuteButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         mediaElement()->setMuted(!mediaElement()->muted());
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
 
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 void MediaControlMuteButtonElement::changedMute()
@@ -357,12 +366,12 @@ PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElemen
     return button.release();
 }
 
-void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+void* MediaControlPanelMuteButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().mouseoverEvent)
         m_controls->showVolumeSlider();
 
-    MediaControlMuteButtonElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
@@ -405,14 +414,14 @@ PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(
     return button.release();
 }
 
-void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
+void* MediaControlPlayButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         mediaElement()->togglePlayState();
         updateDisplayType();
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 void MediaControlPlayButtonElement::updateDisplayType()
@@ -436,7 +445,7 @@ inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaEle
 {
 }
 
-void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
+void* MediaControlSeekButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().mousedownEvent) {
         if (Frame* frame = document()->frame()) {
@@ -445,7 +454,7 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
         }
         mediaElement()->pause(event->fromUserGesture());
         m_seekTimer.startRepeating(cSeekRepeatDelay);
-        event->setDefaultHandled();
+        event->stopPropagation();
     } else if (event->type() == eventNames().mouseupEvent) {
         if (m_capturing)
             if (Frame* frame = document()->frame()) {
@@ -460,10 +469,10 @@ void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
             }
             m_seekTimer.stop();
             m_seeking = false;
-            event->setDefaultHandled();
+            event->stopPropagation();
         }
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonElement>*)
@@ -537,13 +546,13 @@ PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::cre
     return button.release();
 }
 
-void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
+void* MediaControlRewindButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         mediaElement()->rewind(30);
-        event->setDefaultHandled();
+        event->stopPropagation();
     }    
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const
@@ -567,13 +576,13 @@ PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealti
     return button.release();
 }
 
-void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event)
+void* MediaControlReturnToRealtimeButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         mediaElement()->returnToRealtime();
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const
@@ -597,16 +606,16 @@ PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClos
     return button.release();
 }
 
-void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
+void* MediaControlToggleClosedCaptionsButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible());
         setChecked(mediaElement()->closedCaptionsVisible());
         updateDisplayType();
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
 
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
@@ -638,14 +647,14 @@ PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTML
     return timeline.release();
 }
 
-void MediaControlTimelineElement::defaultEventHandler(Event* event)
+void* MediaControlTimelineElement::preDispatchEventHandler(Event* event)
 {
     // Left button is 0. Rejects mouse events not from left button.
     if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
-        return;
+        return 0;
 
     if (!attached())
-        return;
+        return 0;
 
     if (event->type() == eventNames().mousedownEvent)
         mediaElement()->beginScrubbing();
@@ -653,7 +662,7 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
     MediaControlInputElement::defaultEventHandler(event);
 
     if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
-        return;
+        return 0;
 
     float time = narrowPrecisionToFloat(value().toDouble());
     if (time != mediaElement()->currentTime()) {
@@ -668,6 +677,7 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
 
     if (event->type() == eventNames().mouseupEvent)
         mediaElement()->endScrubbing();
+    return 0;
 }
 
 void MediaControlTimelineElement::setPosition(float currentTime) 
@@ -704,19 +714,19 @@ PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::cre
     return slider.release();
 }
 
-void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+void* MediaControlVolumeSliderElement::preDispatchEventHandler(Event* event)
 {
     // Left button is 0. Rejects mouse events not from left button.
     if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
-        return;
+        return 0;
 
     if (!attached())
-        return;
+        return 0;
 
     MediaControlInputElement::defaultEventHandler(event);
 
     if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
-        return;
+        return 0;
 
     float volume = narrowPrecisionToFloat(value().toDouble());
     if (volume != mediaElement()->volume()) {
@@ -724,6 +734,7 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
         mediaElement()->setVolume(volume, ec);
         ASSERT(!ec);
     }
+    return 0;
 }
 
 void MediaControlVolumeSliderElement::setVolume(float volume)
@@ -779,7 +790,7 @@ PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElem
     return button.release();
 }
 
-void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
+void* MediaControlFullscreenButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
 #if ENABLE(FULLSCREEN_API)
@@ -799,9 +810,9 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
         } else
 #endif
             mediaElement()->enterFullscreen();
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
@@ -824,14 +835,14 @@ PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenV
     return button.release();
 }
 
-void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event)
+void* MediaControlFullscreenVolumeMinButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         ExceptionCode code = 0;
         mediaElement()->setVolume(0, code);
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlFullscreenVolumeMinButtonElement::shadowPseudoId() const
@@ -854,14 +865,14 @@ PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenV
     return button.release();
 }
 
-void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event)
+void* MediaControlFullscreenVolumeMaxButtonElement::preDispatchEventHandler(Event* event)
 {
     if (event->type() == eventNames().clickEvent) {
         ExceptionCode code = 0;
         mediaElement()->setVolume(1, code);
-        event->setDefaultHandled();
+        event->stopPropagation();
     }
-    HTMLInputElement::defaultEventHandler(event);
+    return 0;
 }
 
 const AtomicString& MediaControlFullscreenVolumeMaxButtonElement::shadowPseudoId() const
index db3158b..f75b448 100644 (file)
@@ -87,6 +87,7 @@ protected:
     MediaControlElement(HTMLMediaElement*);
 
 private:
+    virtual void *preDispatchEventHandler(Event*);
     virtual bool isMediaControlElement() const { return true; }
 
     HTMLMediaElement* m_mediaElement;   
@@ -126,7 +127,7 @@ public:
 private:
     MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     virtual MediaControlElementType displayType() const;
     virtual const AtomicString& shadowPseudoId() const;
 };
@@ -182,7 +183,7 @@ public:
 
 protected:
     MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
 
 
 private:
@@ -198,7 +199,7 @@ public:
 private:
     MediaControlPanelMuteButtonElement(HTMLMediaElement*, MediaControls*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     virtual const AtomicString& shadowPseudoId() const;
 
     MediaControls* m_controls;
@@ -223,7 +224,7 @@ class MediaControlPlayButtonElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlPlayButtonElement> create(HTMLMediaElement*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     virtual void updateDisplayType();
 
 private:
@@ -236,7 +237,7 @@ private:
 
 class MediaControlSeekButtonElement : public MediaControlInputElement {
 public:
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
 
 protected:
     MediaControlSeekButtonElement(HTMLMediaElement*, MediaControlElementType);
@@ -284,7 +285,7 @@ class MediaControlRewindButtonElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlRewindButtonElement> create(HTMLMediaElement*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
 
 private:
     MediaControlRewindButtonElement(HTMLMediaElement*);
@@ -298,7 +299,7 @@ class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElemen
 public:
     static PassRefPtr<MediaControlReturnToRealtimeButtonElement> create(HTMLMediaElement*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
 
 private:
     MediaControlReturnToRealtimeButtonElement(HTMLMediaElement*);
@@ -312,7 +313,7 @@ class MediaControlToggleClosedCaptionsButtonElement : public MediaControlInputEl
 public:
     static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(HTMLMediaElement*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     virtual void updateDisplayType();
 
 private:
@@ -327,7 +328,7 @@ class MediaControlTimelineElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*, MediaControls*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     void setPosition(float);
     void setDuration(float);
 
@@ -345,7 +346,7 @@ class MediaControlVolumeSliderElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlVolumeSliderElement> create(HTMLMediaElement*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     void setVolume(float);
 
 protected:
@@ -361,7 +362,7 @@ class MediaControlFullscreenButtonElement : public MediaControlInputElement {
 public:
     static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*, MediaControls*);
 
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
 
 private:
     MediaControlFullscreenButtonElement(HTMLMediaElement*, MediaControls*);
@@ -389,7 +390,7 @@ class MediaControlFullscreenVolumeMinButtonElement : public MediaControlInputEle
 public:
     static PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> create(HTMLMediaElement*);
     
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     
 private:
     MediaControlFullscreenVolumeMinButtonElement(HTMLMediaElement*);
@@ -403,7 +404,7 @@ class MediaControlFullscreenVolumeMaxButtonElement : public MediaControlInputEle
 public:
     static PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> create(HTMLMediaElement*);
     
-    virtual void defaultEventHandler(Event*);
+    virtual void *preDispatchEventHandler(Event*);
     
 private:
     MediaControlFullscreenVolumeMaxButtonElement(HTMLMediaElement*);