Changeset 87692 in webkit


Ignore:
Timestamp:
May 30, 2011 10:09:48 AM (13 years ago)
Author:
Darin Adler
Message:

2011-05-30 Jer Noble <jer.noble@apple.com>

Reviewed by Darin Adler and Simon Fraser.

REGRESSION (r87622): Scrubbing a Vimeo movie when in fullscreen stops playback; no way to make it start again
https://bugs.webkit.org/show_bug.cgi?id=61717
rdar://problem/9522272

May be some good way to test this later. No immediate idea about the best way.

When a media element is taken into full-screen mode, stop events from propagating
outside the media element's shadow DOM, EventDispatcher::determineDispatchBehavior()
has been changed to take a shadow root node. In our full screen media element check,
we check to see if the passed shadow root is the shadow root of the full screen media
element, and if so, specify events should StayInsideShadowDOM. The end result is that
inside EventDispatcher::ensureEventAncestors, an ancestor chain is built up all the
way from the SliderThumb to the video element's shadow root, but no further.

  • dom/EventDispatcher.cpp: (WebCore::EventDispatcher::determineDispatchBehavior): Restrict events to the shadow DOM when showing a full screen video.
  • html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::HTMLMediaElement): Removed code to manage full screen controls. The events telling us about activity in the shadow DOM no longer bubble out so we need to handle this inside the shadow DOM on the root element. (WebCore::HTMLMediaElement::play): Ditto. (WebCore::HTMLMediaElement::playbackProgressTimerFired): Ditto. (WebCore::HTMLMediaElement::defaultEventHandler): Ditto. (WebCore::HTMLMediaElement::enterFullscreen): Ditto. (WebCore::HTMLMediaElement::exitFullscreen): Ditto.
  • html/HTMLMediaElement.h: Added isPlaying function, removed things moved to the root element.
  • html/shadow/MediaControlElements.cpp: (WebCore::MediaControlVolumeSliderContainerElement::defaultEventHandler): Rolled out changes that tried to make special rules for events using preDispatchEventHandler and such. This rolls out both r87622 and r87655. (WebCore::MediaControlMuteButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlPanelMuteButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlPlayButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlSeekButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlRewindButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlReturnToRealtimeButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlTimelineElement::defaultEventHandler): Ditto. (WebCore::MediaControlVolumeSliderElement::defaultEventHandler): Ditto. (WebCore::MediaControlFullscreenButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler): Ditto. (WebCore::MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler): Ditto.
  • html/shadow/MediaControlElements.h: Ditto.
  • html/shadow/MediaControlRootElement.cpp: (WebCore::MediaControlRootElement::MediaControlRootElement): Initialize new data members. (WebCore::MediaControlRootElement::playbackStarted): Start the timer so we will consider hiding the controls later. (WebCore::MediaControlRootElement::playbackProgressed): Hide the controls if the mouse is no longer over the controls. (WebCore::MediaControlRootElement::playbackStopped): Stop the timer since we only hide automatically if we're playing. (WebCore::MediaControlRootElement::enteredFullscreen): Start the timer. (WebCore::MediaControlRootElement::exitedFullscreen): Stop the timer since we only care if we are full screen. (WebCore::MediaControlRootElement::containsRelatedTarget): Added. Helper for next function. (WebCore::MediaControlRootElement::defaultEventHandler): Do the hide/show and timer functions as the mouse is moved in and out. (WebCore::MediaControlRootElement::startHideFullscreenControlsTimer): Start the timer if needed. (WebCore::MediaControlRootElement::hideFullscreenControlsTimerFired): Hide if the conditions are met. (WebCore::MediaControlRootElement::stopHideFullscreenControlsTimer): Stop the timer.
  • html/shadow/MediaControlRootElement.h: Added new functions and data members.
Location:
trunk/Source/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r87691 r87692  
     12011-05-30  Jer Noble  <jer.noble@apple.com>
     2
     3        Reviewed by Darin Adler and Simon Fraser.
     4
     5        REGRESSION (r87622): Scrubbing a Vimeo movie when in fullscreen stops playback; no way to make it start again
     6        https://bugs.webkit.org/show_bug.cgi?id=61717
     7        rdar://problem/9522272
     8
     9        May be some good way to test this later. No immediate idea about the best way.
     10
     11        When a media element is taken into full-screen mode, stop events from propagating
     12        outside the media element's shadow DOM, EventDispatcher::determineDispatchBehavior()
     13        has been changed to take a shadow root node. In our full screen media element check,
     14        we check to see if the passed shadow root is the shadow root of the full screen media
     15        element, and if so, specify events should StayInsideShadowDOM. The end result is that
     16        inside EventDispatcher::ensureEventAncestors, an ancestor chain is built up all the
     17        way from the SliderThumb to the video element's shadow root, but no further.
     18
     19        * dom/EventDispatcher.cpp:
     20        (WebCore::EventDispatcher::determineDispatchBehavior): Restrict events to the
     21        shadow DOM when showing a full screen video.
     22
     23        * html/HTMLMediaElement.cpp:
     24        (WebCore::HTMLMediaElement::HTMLMediaElement): Removed code to manage full screen controls.
     25        The events telling us about activity in the shadow DOM no longer bubble out so we need to
     26        handle this inside the shadow DOM on the root element.
     27        (WebCore::HTMLMediaElement::play): Ditto.
     28        (WebCore::HTMLMediaElement::playbackProgressTimerFired): Ditto.
     29        (WebCore::HTMLMediaElement::defaultEventHandler): Ditto.
     30        (WebCore::HTMLMediaElement::enterFullscreen): Ditto.
     31        (WebCore::HTMLMediaElement::exitFullscreen): Ditto.
     32        * html/HTMLMediaElement.h: Added isPlaying function, removed things moved to the root element.
     33
     34        * html/shadow/MediaControlElements.cpp:
     35        (WebCore::MediaControlVolumeSliderContainerElement::defaultEventHandler): Rolled out
     36        changes that tried to make special rules for events using preDispatchEventHandler and such.
     37        This rolls out both r87622 and r87655.
     38        (WebCore::MediaControlMuteButtonElement::defaultEventHandler): Ditto.
     39        (WebCore::MediaControlPanelMuteButtonElement::defaultEventHandler): Ditto.
     40        (WebCore::MediaControlPlayButtonElement::defaultEventHandler): Ditto.
     41        (WebCore::MediaControlSeekButtonElement::defaultEventHandler): Ditto.
     42        (WebCore::MediaControlRewindButtonElement::defaultEventHandler): Ditto.
     43        (WebCore::MediaControlReturnToRealtimeButtonElement::defaultEventHandler): Ditto.
     44        (WebCore::MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler): Ditto.
     45        (WebCore::MediaControlTimelineElement::defaultEventHandler): Ditto.
     46        (WebCore::MediaControlVolumeSliderElement::defaultEventHandler): Ditto.
     47        (WebCore::MediaControlFullscreenButtonElement::defaultEventHandler): Ditto.
     48        (WebCore::MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler): Ditto.
     49        (WebCore::MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler): Ditto.
     50        * html/shadow/MediaControlElements.h: Ditto.
     51
     52        * html/shadow/MediaControlRootElement.cpp:
     53        (WebCore::MediaControlRootElement::MediaControlRootElement): Initialize new data members.
     54        (WebCore::MediaControlRootElement::playbackStarted): Start the timer so we will consider
     55        hiding the controls later.
     56        (WebCore::MediaControlRootElement::playbackProgressed): Hide the controls if the mouse
     57        is no longer over the controls.
     58        (WebCore::MediaControlRootElement::playbackStopped): Stop the timer since we only hide
     59        automatically if we're playing.
     60        (WebCore::MediaControlRootElement::enteredFullscreen): Start the timer.
     61        (WebCore::MediaControlRootElement::exitedFullscreen): Stop the timer since we only care
     62        if we are full screen.
     63        (WebCore::MediaControlRootElement::containsRelatedTarget): Added. Helper for next function.
     64        (WebCore::MediaControlRootElement::defaultEventHandler): Do the hide/show and timer functions
     65        as the mouse is moved in and out.
     66        (WebCore::MediaControlRootElement::startHideFullscreenControlsTimer): Start the timer if
     67        needed.
     68        (WebCore::MediaControlRootElement::hideFullscreenControlsTimerFired): Hide if the conditions
     69        are met.
     70        (WebCore::MediaControlRootElement::stopHideFullscreenControlsTimer): Stop the timer.
     71
     72        * html/shadow/MediaControlRootElement.h: Added new functions and data members.
     73
     74
    1752011-05-30  Gavin Peters  <gavinp@chromium.org>
    276
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r85742 r87692  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2001 Dirk Mueller (mueller@kde.org)
    5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    66 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
    77 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
     
    2727#include "EventDispatcher.h"
    2828
    29 #include "Element.h"
    30 #include "Event.h"
    3129#include "EventContext.h"
    32 #include "EventTarget.h"
    3330#include "FrameView.h"
     31#include "HTMLMediaElement.h"
    3432#include "InspectorInstrumentation.h"
    3533#include "MouseEvent.h"
    36 #include "Node.h"
    3734#include "ScopedEventQueue.h"
     35#include "WindowEventContext.h"
     36#include <wtf/RefPtr.h>
    3837
    3938#if ENABLE(SVG)
     
    4241#include "SVGUseElement.h"
    4342#endif
    44 
    45 #include "UIEvent.h"
    46 #include "UIEventWithKeyState.h"
    47 #include "WindowEventContext.h"
    48 
    49 #include <wtf/RefPtr.h>
    5043
    5144namespace WebCore {
     
    236229void EventDispatcher::ensureEventAncestors(Event* event)
    237230{
    238     EventDispatchBehavior behavior = determineDispatchBehavior(event);
    239 
    240231    if (!m_node->inDocument())
    241232        return;
     
    252243        bool isSVGShadowRoot = ancestor->isSVGShadowRoot();
    253244        if (isSVGShadowRoot || ancestor->isShadowRoot()) {
    254             if (behavior == StayInsideShadowDOM)
     245            if (determineDispatchBehavior(event, ancestor) == StayInsideShadowDOM)
    255246                return;
    256247#if ENABLE(SVG)
     
    376367}
    377368
    378 EventDispatchBehavior EventDispatcher::determineDispatchBehavior(Event* event)
    379 {
     369EventDispatchBehavior EventDispatcher::determineDispatchBehavior(Event* event, Node* shadowRoot)
     370{
     371#if ENABLE(FULLSCREEN_API)
     372    // Video-only full screen is a mode where we use the shadow DOM as an implementation
     373    // detail that should not be detectable by the web content.
     374    if (Element* element = m_node->document()->webkitCurrentFullScreenElement()) {
     375        // FIXME: We assume that if the full screen element is a media element that it's
     376        // the video-only full screen. Both here and elsewhere. But that is probably wrong.
     377        if (element->isMediaElement() && shadowRoot && shadowRoot->shadowHost() == element)
     378            return StayInsideShadowDOM;
     379    }
     380#endif
     381
    380382    // Per XBL 2.0 spec, mutation events should never cross shadow DOM boundary:
    381383    // http://dev.w3.org/2006/xbl2/#event-flow-and-targeting-across-shadow-s
  • trunk/Source/WebCore/dom/EventDispatcher.h

    r83386 r87692  
    6262
    6363    PassRefPtr<EventTarget> adjustToShadowBoundaries(PassRefPtr<Node> relatedTarget, const Vector<Node*> relatedTargetAncestors);
    64     EventDispatchBehavior determineDispatchBehavior(Event*);
     64    EventDispatchBehavior determineDispatchBehavior(Event*, Node* shadowRoot);
    6565    void ensureEventAncestors(Event*);
    6666    const EventContext* topEventContext();
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r87661 r87692  
    124124    , m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
    125125    , m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
    126     , m_hideFullscreenControlsTimer(this, &HTMLMediaElement::hideFullscreenControlsTimerFired)
    127126    , m_playedTimeRanges()
    128127    , m_playbackRate(1.0f)
     
    166165    , m_isFullscreen(false)
    167166    , m_closedCaptionsVisible(false)
    168     , m_mouseOver(false)
    169167#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    170168    , m_needWidgetUpdate(false)
     
    14271425    }
    14281426   
    1429     if (isFullscreen())
    1430         startHideFullscreenControlsTimer();
    1431    
    14321427    playInternal();
    14331428}
     
    16341629
    16351630    scheduleTimeupdateEvent(true);
    1636     if (hasMediaControls()) {
    1637         if (!m_mouseOver && controls() && hasVideo())
    1638             mediaControls()->makeTransparent();
     1631    if (hasMediaControls())
    16391632        mediaControls()->playbackProgressed();
    1640     }
    16411633    // FIXME: deal with cue ranges here
    1642 }
    1643 
    1644 void HTMLMediaElement::startHideFullscreenControlsTimer()
    1645 {
    1646     if (!isFullscreen())
    1647         return;
    1648    
    1649     m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingControls);
    1650 }
    1651 
    1652 void HTMLMediaElement::hideFullscreenControlsTimerFired(Timer<HTMLMediaElement>*)
    1653 {
    1654     if (!m_playing)
    1655         return;
    1656    
    1657     if (!isFullscreen())
    1658         return;
    1659    
    1660     if (!controls() || !hasMediaControls())
    1661         return;
    1662    
    1663     if (!mediaControls()->shouldHideControls())
    1664         return;
    1665        
    1666     mediaControls()->makeTransparent();
    1667 }
    1668 
    1669 void HTMLMediaElement::stopHideFullscreenControlsTimer()
    1670 {
    1671     m_hideFullscreenControlsTimer.stop();
    16721634}
    16731635
     
    24102372        widget->handleEvent(event);
    24112373#else
    2412     if (event->isMouseEvent()) {
    2413         MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    2414         if (mouseEvent->relatedTarget() != this) {
    2415             if (event->type() == eventNames().mouseoverEvent) {
    2416                 m_mouseOver = true;
    2417                 if (hasMediaControls() && controls() && !canPlay()) {
    2418                     mediaControls()->makeOpaque();
    2419                     if (mediaControls()->shouldHideControls())
    2420                         startHideFullscreenControlsTimer();
    2421                 }
    2422             } else if (event->type() == eventNames().mouseoutEvent) {
    2423                 m_mouseOver = false;
    2424                 stopHideFullscreenControlsTimer();
    2425             } else if (event->type() == eventNames().mousemoveEvent) {
    2426                 if (isFullscreen() && hasMediaControls() && controls()) {
    2427                     // When we get a mouse move in fullscreen mode, show the media controls, and start a timer
    2428                     // that will hide the media controls after a 3 seconds without a mouse move.
    2429                     mediaControls()->makeOpaque();
    2430                     if (mediaControls()->shouldHideControls())
    2431                         startHideFullscreenControlsTimer();
    2432                 }
    2433             }
    2434    
    2435         }
    2436     }
    2437 
    24382374    HTMLElement::defaultEventHandler(event);
    24392375#endif
     
    25692505{
    25702506    LOG(Media, "HTMLMediaElement::enterFullscreen");
    2571    
    2572     startHideFullscreenControlsTimer();
    2573    
     2507
    25742508#if ENABLE(FULLSCREEN_API)
    25752509    if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
     
    25912525{
    25922526    LOG(Media, "HTMLMediaElement::exitFullscreen");
    2593    
    2594     stopHideFullscreenControlsTimer();
    2595    
     2527
    25962528#if ENABLE(FULLSCREEN_API)
    25972529    if (document() && document()->settings() && document()->settings()->fullScreenEnabled()) {
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r87661 r87692  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    148148    void endScrubbing();
    149149   
    150     void stopHideFullscreenControlsTimer();
    151 
    152150    bool canPlay() const;
    153151
     
    203201    static void clearMediaCache();
    204202    static void clearMediaCacheForSite(const String&);
     203
     204    bool isPlaying() const { return m_playing; }
    205205
    206206protected:
     
    273273    void progressEventTimerFired(Timer<HTMLMediaElement>*);
    274274    void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
    275     void hideFullscreenControlsTimerFired(Timer<HTMLMediaElement>*);
    276275    void startPlaybackProgressTimer();
    277276    void startProgressEventTimer();
    278     void startHideFullscreenControlsTimer();
    279277    void stopPeriodicTimers();
    280278
     
    346344    Timer<HTMLMediaElement> m_progressEventTimer;
    347345    Timer<HTMLMediaElement> m_playbackProgressTimer;
    348     Timer<HTMLMediaElement> m_hideFullscreenControlsTimer;
    349346    Vector<RefPtr<Event> > m_pendingEvents;
    350347    RefPtr<TimeRanges> m_playedTimeRanges;
     
    422419    bool m_isFullscreen : 1;
    423420    bool m_closedCaptionsVisible : 1;
    424     bool m_mouseOver : 1;
    425421
    426422#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
  • trunk/Source/WebCore/html/shadow/MediaControlElements.cpp

    r87657 r87692  
    11/*
    2  * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7676}
    7777
    78 void* MediaControlElement::preDispatchEventHandler(Event* event)
    79 {
    80     if (event->type() == eventNames().clickEvent) {
    81         event->preventDefault();
    82         event->stopPropagation();
    83     }
    84     return 0;
    85 }
    86 
    8778static const String& displayString()
    8879{
     
    201192}
    202193
    203 void* MediaControlVolumeSliderContainerElement::preDispatchEventHandler(Event* event)
     194void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
    204195{
    205196    if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
    206         return 0;
     197        return;
    207198
    208199    // Poor man's mouseleave event detection.
    209200    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    210201    if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
    211         return 0;
     202        return;
    212203
    213204    if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
    214         return 0;
     205        return;
    215206
    216207    hide();
    217     return 0;
    218208}
    219209
     
    331321}
    332322
    333 void* MediaControlMuteButtonElement::preDispatchEventHandler(Event* event)
     323void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
    334324{
    335325    if (event->type() == eventNames().clickEvent) {
    336326        mediaElement()->setMuted(!mediaElement()->muted());
    337         event->preventDefault();
    338         event->stopPropagation();
    339     }
    340 
    341     return 0;
     327        event->setDefaultHandled();
     328    }
     329
     330    HTMLInputElement::defaultEventHandler(event);
    342331}
    343332
     
    369358}
    370359
    371 void* MediaControlPanelMuteButtonElement::preDispatchEventHandler(Event* event)
     360void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
    372361{
    373362    if (event->type() == eventNames().mouseoverEvent)
    374363        m_controls->showVolumeSlider();
    375364
    376     return 0;
     365    MediaControlMuteButtonElement::defaultEventHandler(event);
    377366}
    378367
     
    417406}
    418407
    419 void* MediaControlPlayButtonElement::preDispatchEventHandler(Event* event)
     408void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
    420409{
    421410    if (event->type() == eventNames().clickEvent) {
    422411        mediaElement()->togglePlayState();
    423412        updateDisplayType();
    424         event->preventDefault();
    425         event->stopPropagation();
    426     }
    427     return 0;
     413        event->setDefaultHandled();
     414    }
     415    HTMLInputElement::defaultEventHandler(event);
    428416}
    429417
     
    449437}
    450438
    451 void* MediaControlSeekButtonElement::preDispatchEventHandler(Event* event)
     439void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
    452440{
    453441    if (event->type() == eventNames().mousedownEvent) {
     
    458446        mediaElement()->pause(event->fromUserGesture());
    459447        m_seekTimer.startRepeating(cSeekRepeatDelay);
    460         event->preventDefault();
    461         event->stopPropagation();
     448        event->setDefaultHandled();
    462449    } else if (event->type() == eventNames().mouseupEvent) {
    463450        if (m_capturing)
     
    474461            m_seekTimer.stop();
    475462            m_seeking = false;
    476             event->preventDefault();
    477             event->stopPropagation();
     463            event->setDefaultHandled();
    478464        }
    479465    }
    480     return 0;
     466    HTMLInputElement::defaultEventHandler(event);
    481467}
    482468
     
    552538}
    553539
    554 void* MediaControlRewindButtonElement::preDispatchEventHandler(Event* event)
     540void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
    555541{
    556542    if (event->type() == eventNames().clickEvent) {
    557543        mediaElement()->rewind(30);
    558         event->preventDefault();
    559         event->stopPropagation();
     544        event->setDefaultHandled();
    560545    }   
    561     return 0;
     546    HTMLInputElement::defaultEventHandler(event);
    562547}
    563548
     
    583568}
    584569
    585 void* MediaControlReturnToRealtimeButtonElement::preDispatchEventHandler(Event* event)
     570void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event)
    586571{
    587572    if (event->type() == eventNames().clickEvent) {
    588573        mediaElement()->returnToRealtime();
    589         event->preventDefault();
    590         event->stopPropagation();
    591     }
    592     return 0;
     574        event->setDefaultHandled();
     575    }
     576    HTMLInputElement::defaultEventHandler(event);
    593577}
    594578
     
    614598}
    615599
    616 void* MediaControlToggleClosedCaptionsButtonElement::preDispatchEventHandler(Event* event)
     600void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
    617601{
    618602    if (event->type() == eventNames().clickEvent) {
     
    620604        setChecked(mediaElement()->closedCaptionsVisible());
    621605        updateDisplayType();
    622         event->preventDefault();
    623         event->stopPropagation();
    624     }
    625 
    626     return 0;
     606        event->setDefaultHandled();
     607    }
     608
     609    HTMLInputElement::defaultEventHandler(event);
    627610}
    628611
     
    656639}
    657640
    658 void* MediaControlTimelineElement::preDispatchEventHandler(Event* event)
     641void MediaControlTimelineElement::defaultEventHandler(Event* event)
    659642{
    660643    // Left button is 0. Rejects mouse events not from left button.
    661644    if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
    662         return 0;
     645        return;
    663646
    664647    if (!attached())
    665         return 0;
     648        return;
    666649
    667650    if (event->type() == eventNames().mousedownEvent)
    668651        mediaElement()->beginScrubbing();
    669652
     653    if (event->type() == eventNames().mouseupEvent)
     654        mediaElement()->endScrubbing();
     655
    670656    MediaControlInputElement::defaultEventHandler(event);
    671657
    672658    if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
    673         return 0;
     659        return;
    674660
    675661    float time = narrowPrecisionToFloat(value().toDouble());
     
    683669    if (slider && slider->inDragMode())
    684670        m_controls->updateTimeDisplay();
    685 
    686     if (event->type() == eventNames().mouseupEvent)
    687         mediaElement()->endScrubbing();
    688     return 0;
    689671}
    690672
     
    723705}
    724706
    725 void* MediaControlVolumeSliderElement::preDispatchEventHandler(Event* event)
     707void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
    726708{
    727709    // Left button is 0. Rejects mouse events not from left button.
    728710    if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
    729         return 0;
     711        return;
    730712
    731713    if (!attached())
    732         return 0;
     714        return;
    733715
    734716    MediaControlInputElement::defaultEventHandler(event);
    735717
    736718    if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
    737         return 0;
     719        return;
    738720
    739721    float volume = narrowPrecisionToFloat(value().toDouble());
     
    743725        ASSERT(!ec);
    744726    }
    745     return 0;
    746727}
    747728
     
    799780}
    800781
    801 void* MediaControlFullscreenButtonElement::preDispatchEventHandler(Event* event)
     782void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
    802783{
    803784    if (event->type() == eventNames().clickEvent) {
     
    816797#endif
    817798            mediaElement()->enterFullscreen();
    818         event->preventDefault();
    819         event->stopPropagation();
    820     }
    821     return 0;
     799        event->setDefaultHandled();
     800    }
     801    HTMLInputElement::defaultEventHandler(event);
    822802}
    823803
     
    842822}
    843823
    844 void* MediaControlFullscreenVolumeMinButtonElement::preDispatchEventHandler(Event* event)
     824void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event)
    845825{
    846826    if (event->type() == eventNames().clickEvent) {
    847827        ExceptionCode code = 0;
    848828        mediaElement()->setVolume(0, code);
    849         event->preventDefault();
    850         event->stopPropagation();
    851     }
    852     return 0;
     829        event->setDefaultHandled();
     830    }
     831    HTMLInputElement::defaultEventHandler(event);
    853832}
    854833
     
    873852}
    874853
    875 void* MediaControlFullscreenVolumeMaxButtonElement::preDispatchEventHandler(Event* event)
     854void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event)
    876855{
    877856    if (event->type() == eventNames().clickEvent) {
    878857        ExceptionCode code = 0;
    879858        mediaElement()->setVolume(1, code);
    880         event->preventDefault();
    881         event->stopPropagation();
    882     }
    883     return 0;
     859        event->setDefaultHandled();
     860    }
     861    HTMLInputElement::defaultEventHandler(event);
    884862}
    885863
  • trunk/Source/WebCore/html/shadow/MediaControlElements.h

    r87622 r87692  
    11/*
    2  * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8888
    8989private:
    90     virtual void *preDispatchEventHandler(Event*);
    9190    virtual bool isMediaControlElement() const { return true; }
    9291
     
    128127    MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
    129128    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    130     virtual void *preDispatchEventHandler(Event*);
     129    virtual void defaultEventHandler(Event*);
    131130    virtual MediaControlElementType displayType() const;
    132131    virtual const AtomicString& shadowPseudoId() const;
     
    184183protected:
    185184    MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
    186     virtual void *preDispatchEventHandler(Event*);
     185    virtual void defaultEventHandler(Event*);
    187186
    188187
     
    200199    MediaControlPanelMuteButtonElement(HTMLMediaElement*, MediaControls*);
    201200
    202     virtual void *preDispatchEventHandler(Event*);
     201    virtual void defaultEventHandler(Event*);
    203202    virtual const AtomicString& shadowPseudoId() const;
    204203
     
    225224    static PassRefPtr<MediaControlPlayButtonElement> create(HTMLMediaElement*);
    226225
    227     virtual void *preDispatchEventHandler(Event*);
     226    virtual void defaultEventHandler(Event*);
    228227    virtual void updateDisplayType();
    229228
     
    238237class MediaControlSeekButtonElement : public MediaControlInputElement {
    239238public:
    240     virtual void *preDispatchEventHandler(Event*);
     239    virtual void defaultEventHandler(Event*);
    241240
    242241protected:
     
    286285    static PassRefPtr<MediaControlRewindButtonElement> create(HTMLMediaElement*);
    287286
    288     virtual void *preDispatchEventHandler(Event*);
     287    virtual void defaultEventHandler(Event*);
    289288
    290289private:
     
    300299    static PassRefPtr<MediaControlReturnToRealtimeButtonElement> create(HTMLMediaElement*);
    301300
    302     virtual void *preDispatchEventHandler(Event*);
     301    virtual void defaultEventHandler(Event*);
    303302
    304303private:
     
    314313    static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(HTMLMediaElement*);
    315314
    316     virtual void *preDispatchEventHandler(Event*);
     315    virtual void defaultEventHandler(Event*);
    317316    virtual void updateDisplayType();
    318317
     
    329328    static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*, MediaControls*);
    330329
    331     virtual void *preDispatchEventHandler(Event*);
     330    virtual void defaultEventHandler(Event*);
    332331    void setPosition(float);
    333332    void setDuration(float);
     
    347346    static PassRefPtr<MediaControlVolumeSliderElement> create(HTMLMediaElement*);
    348347
    349     virtual void *preDispatchEventHandler(Event*);
     348    virtual void defaultEventHandler(Event*);
    350349    void setVolume(float);
    351350
     
    363362    static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*, MediaControls*);
    364363
    365     virtual void *preDispatchEventHandler(Event*);
     364    virtual void defaultEventHandler(Event*);
    366365
    367366private:
     
    391390    static PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> create(HTMLMediaElement*);
    392391   
    393     virtual void *preDispatchEventHandler(Event*);
     392    virtual void defaultEventHandler(Event*);
    394393   
    395394private:
     
    405404    static PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> create(HTMLMediaElement*);
    406405   
    407     virtual void *preDispatchEventHandler(Event*);
     406    virtual void defaultEventHandler(Event*);
    408407   
    409408private:
  • trunk/Source/WebCore/html/shadow/MediaControlRootElement.cpp

    r87661 r87692  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2011 Google Inc. All rights reserved.
    44 *
     
    3131
    3232#include "MediaControlElements.h"
     33#include "MouseEvent.h"
    3334#include "Page.h"
    3435#include "RenderTheme.h"
     
    3738
    3839namespace WebCore {
     40
     41static const double timeWithoutMouseMovementBeforeHidingControls = 3;
    3942
    4043MediaControlRootElement::MediaControlRootElement(HTMLMediaElement* mediaElement)
     
    6265    , m_panel(0)
    6366    , m_opaque(true)
     67    , m_isMouseOverControls(false)
     68    , m_hideFullscreenControlsTimer(this, &MediaControlRootElement::hideFullscreenControlsTimerFired)
    6469{
    6570}
     
    337342    m_timeline->setPosition(m_mediaElement->currentTime());
    338343    updateTimeDisplay();
     344
     345    if (m_mediaElement->isFullscreen())
     346        startHideFullscreenControlsTimer();
    339347}
    340348
     
    343351    m_timeline->setPosition(m_mediaElement->currentTime());
    344352    updateTimeDisplay();
     353   
     354    if (!m_isMouseOverControls && m_mediaElement->hasVideo())
     355        makeTransparent();
    345356}
    346357
     
    352363    makeOpaque();
    353364   
    354     m_mediaElement->stopHideFullscreenControlsTimer();
     365    stopHideFullscreenControlsTimer();
    355366}
    356367
     
    438449        m_returnToRealTimeButton->hide();
    439450    }
     451
     452    startHideFullscreenControlsTimer();
    440453}
    441454
     
    449462    m_seekForwardButton->show();
    450463    m_returnToRealTimeButton->show();
     464
     465    stopHideFullscreenControlsTimer();   
    451466}
    452467
     
    465480}
    466481
     482bool MediaControlRootElement::containsRelatedTarget(Event* event)
     483{
     484    if (!event->isMouseEvent())
     485        return false;
     486    EventTarget* relatedTarget = static_cast<MouseEvent*>(event)->relatedTarget();
     487    if (!relatedTarget)
     488        return false;
     489    return contains(relatedTarget->toNode());
     490}
     491
     492void MediaControlRootElement::defaultEventHandler(Event* event)
     493{
     494    MediaControls::defaultEventHandler(event);
     495
     496    if (event->type() == eventNames().mouseoverEvent) {
     497        if (!containsRelatedTarget(event)) {
     498            m_isMouseOverControls = true;
     499            if (!m_mediaElement->canPlay()) {
     500                makeOpaque();
     501                if (shouldHideControls())
     502                    startHideFullscreenControlsTimer();
     503            }
     504        }
     505    } else if (event->type() == eventNames().mouseoutEvent) {
     506        if (!containsRelatedTarget(event)) {
     507            m_isMouseOverControls = false;
     508            stopHideFullscreenControlsTimer();
     509        }
     510    } else if (event->type() == eventNames().mousemoveEvent) {
     511        if (m_mediaElement->isFullscreen()) {
     512            // When we get a mouse move in fullscreen mode, show the media controls, and start a timer
     513            // that will hide the media controls after a 3 seconds without a mouse move.
     514            makeOpaque();
     515            if (shouldHideControls())
     516                startHideFullscreenControlsTimer();
     517        }
     518    }
     519}
     520
     521void MediaControlRootElement::startHideFullscreenControlsTimer()
     522{
     523    if (!m_mediaElement->isFullscreen())
     524        return;
     525   
     526    m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingControls);
     527}
     528
     529void MediaControlRootElement::hideFullscreenControlsTimerFired(Timer<MediaControlRootElement>*)
     530{
     531    if (!m_mediaElement->isPlaying())
     532        return;
     533   
     534    if (!m_mediaElement->isFullscreen())
     535        return;
     536   
     537    if (!shouldHideControls())
     538        return;
     539   
     540    makeTransparent();
     541}
     542
     543void MediaControlRootElement::stopHideFullscreenControlsTimer()
     544{
     545    m_hideFullscreenControlsTimer.stop();
     546}
     547
    467548const AtomicString& MediaControlRootElement::shadowPseudoId() const
    468549{
  • trunk/Source/WebCore/html/shadow/MediaControlRootElement.h

    r87661 r87692  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
    33 * Copyright (C) 2011 Google Inc. All rights reserved.
    44 *
     
    9898
    9999    virtual bool shouldHideControls();
     100
    100101private:
    101102    MediaControlRootElement(HTMLMediaElement*);
    102103
     104    virtual void defaultEventHandler(Event*);
     105    void hideFullscreenControlsTimerFired(Timer<MediaControlRootElement>*);
     106    void startHideFullscreenControlsTimer();
     107    void stopHideFullscreenControlsTimer();
     108
    103109    virtual const AtomicString& shadowPseudoId() const;
     110
     111    bool containsRelatedTarget(Event*);
    104112
    105113    HTMLMediaElement* m_mediaElement;
     
    125133    MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
    126134    MediaControlPanelElement* m_panel;
    127 
    128135    bool m_opaque;
     136    bool m_isMouseOverControls;
     137    Timer<MediaControlRootElement> m_hideFullscreenControlsTimer;
    129138};
    130139
Note: See TracChangeset for help on using the changeset viewer.