Changeset 83397 in webkit


Ignore:
Timestamp:
Apr 10, 2011 7:57:13 AM (13 years ago)
Author:
Dimitri Glazkov
Message:

2011-04-07 Dimitri Glazkov <Dimitri Glazkov>

Reviewed by Eric Carlson.

[Meta] Convert HTMLMediaElement to use the new shadow DOM
https://bugs.webkit.org/show_bug.cgi?id=53020

This conversion is non-trivial, for several reasons:

1) Since HTMLMediaElement now hosts the shadow DOM for controls, hiding
and showing controls does not result in destroying and re-creating the
shadow DOM tree. Instead, the tree is created as needed and shown/hidden
using inline styles.

2) Instead of detaching/attaching on each style change, the control parts
are now using a set of higher fidelity callbacks that notify MediaControls
about changes to which it should react. Each reaction results in hiding,
showing, or changing the state of the control parts using inline styles
and DOM APIs.

3) Hiding and showing controls is accomplished using inline styles, rather
than wiring rendererIsNeeded, because renderers are now re-created less
frequently.

4) Instead of constantly querying RenderTheme about visibility of a particular
control part, we let the theme determine which parts are supported and
which parts are visible in certain conditions.

5) Custom hit-testing, event forwarding, and style updates are completely
removed, since they are now unnecessary.

6) Fading controls in/out is now done as CSS animation, since shadow DOM
supports it.

Test: manual-tests/media-controls.html

Location:
trunk/Source/WebCore
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r83396 r83397  
     12011-04-07  Dimitri Glazkov  <dglazkov@chromium.org>
     2
     3        Reviewed by Eric Carlson.
     4
     5        [Meta] Convert HTMLMediaElement to use the new shadow DOM
     6        https://bugs.webkit.org/show_bug.cgi?id=53020
     7
     8        This conversion is non-trivial, for several reasons:
     9
     10        1) Since HTMLMediaElement now hosts the shadow DOM for controls, hiding
     11        and showing controls does not result in destroying and re-creating the
     12        shadow DOM tree. Instead, the tree is created as needed and shown/hidden
     13        using inline styles.
     14       
     15        2) Instead of detaching/attaching on each style change, the control parts
     16        are now using a set of higher fidelity callbacks that notify MediaControls
     17        about changes to which it should react. Each reaction results in hiding,
     18        showing, or changing the state of the control parts using inline styles
     19        and DOM APIs.
     20
     21        3) Hiding and showing controls is accomplished using inline styles, rather
     22        than wiring rendererIsNeeded, because renderers are now re-created less
     23        frequently.
     24
     25        4) Instead of constantly querying RenderTheme about visibility of a particular
     26        control part, we let the theme determine which parts are supported and
     27        which parts are visible in certain conditions.
     28
     29        5) Custom hit-testing, event forwarding, and style updates are completely
     30        removed, since they are now unnecessary.
     31
     32        6) Fading controls in/out is now done as CSS animation, since shadow DOM
     33        supports it.
     34
     35        Test: manual-tests/media-controls.html
     36
    1372011-04-09  Dan Bernstein  <mitz@apple.com>
    238
  • trunk/Source/WebCore/css/mediaControls.css

    r82053 r83397  
    2828    width: 200px;
    2929    height: 16px;
     30}
     31
     32::-webkit-media-controls {
     33    width: inherit;
     34    height: inherit;
     35    position: relative;
     36    display: block;
    3037}
    3138
     
    99106}
    100107
    101 audio::-webkit-media-controls-volume-slider-container, video::-webkit-media-controls-volume-slider-container {
    102     display: none;
    103 }
    104 
    105108audio::-webkit-media-controls-volume-slider, video::-webkit-media-controls-volume-slider {
    106     display: none;
    107109    background-color: initial;
    108110    border: initial;
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r83373 r83397  
    5555#include "MediaPlayer.h"
    5656#include "MediaQueryEvaluator.h"
     57#include "MouseEvent.h"
    5758#include "MIMETypeRegistry.h"
    5859#include "Page.h"
     
    6162#include "ScriptEventListener.h"
    6263#include "Settings.h"
     64#include "ShadowRoot.h"
    6365#include "TimeRanges.h"
    6466#include <limits>
     
    162164    , m_isFullscreen(false)
    163165    , m_closedCaptionsVisible(false)
     166    , m_mouseOver(false)
    164167#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    165168    , m_needWidgetUpdate(false)
     
    219222    else if (attrName == controlsAttr) {
    220223#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
    221         if (!isVideo() && attached() && (controls() != (renderer() != 0))) {
    222             detach();
    223             attach();
    224         }
    225         if (hasMediaControls())
    226             mediaControls()->reset();
     224        if (controls()) {
     225            if (!hasMediaControls()) {
     226                ensureMediaControls();
     227                mediaControls()->reset();
     228            }
     229            mediaControls()->show();
     230        } else if (hasMediaControls())
     231            mediaControls()->hide();
    227232#else
    228233        if (m_player)
     
    890895
    891896        updateDisplayState();
     897        if (hasMediaControls())
     898            mediaControls()->reportedError();
    892899        return;
    893900    }
     
    919926        m_completelyLoaded = true;
    920927    }
     928
     929    if (hasMediaControls())
     930        mediaControls()->changedNetworkState();
    921931}
    922932
     
    968978        scheduleEvent(eventNames().durationchangeEvent);
    969979        scheduleEvent(eventNames().loadedmetadataEvent);
     980        if (hasMediaControls())
     981            mediaControls()->loadedMetadata();
    970982        if (renderer())
    971983            renderer()->updateFromElement();
     
    15951607
    15961608    scheduleTimeupdateEvent(true);
    1597     if (hasMediaControls())
     1609    if (hasMediaControls()) {
     1610        if (!m_mouseOver && controls())
     1611            mediaControls()->makeTransparent();
    15981612        mediaControls()->playbackProgressed();
    1599 
     1613    }
    16001614    // FIXME: deal with cue ranges here
    16011615}
     
    23152329        widget->handleEvent(event);
    23162330#else
    2317     if (hasMediaControls())
    2318         mediaControls()->forwardEvent(event);
    2319     if (event->defaultHandled())
    2320         return;
     2331    if (event->isMouseEvent()) {
     2332        MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
     2333        if (mouseEvent->relatedTarget() != this) {
     2334            if (event->type() == eventNames().mouseoverEvent) {
     2335                m_mouseOver = true;
     2336                if (hasMediaControls() && controls() && !canPlay())
     2337                    mediaControls()->makeOpaque();
     2338            } else if (event->type() == eventNames().mouseoutEvent)
     2339                m_mouseOver = false;
     2340        }
     2341    }
     2342
    23212343    HTMLElement::defaultEventHandler(event);
    23222344#endif
     
    24592481    ASSERT(!m_isFullscreen);
    24602482    m_isFullscreen = true;
     2483    if (hasMediaControls())
     2484        mediaControls()->enteredFullscreen();
    24612485    if (document() && document()->page()) {
    24622486        document()->page()->chrome()->client()->enterFullscreenForNode(this);
     
    24772501    ASSERT(m_isFullscreen);
    24782502    m_isFullscreen = false;
     2503    if (hasMediaControls())
     2504        mediaControls()->exitedFullscreen();
    24792505    if (document() && document()->page()) {
    24802506        if (document()->page()->chrome()->requiresFullscreenForVideoPlayback())
     
    26092635MediaControls* HTMLMediaElement::mediaControls()
    26102636{
    2611     ASSERT(renderer());
    2612     return toRenderMedia(renderer())->controls();
    2613 }
    2614 
    2615 bool HTMLMediaElement::hasMediaControls() const
    2616 {
    2617     return renderer() && renderer()->isMedia();
    2618 }
    2619 
    2620 }
    2621 
    2622 #endif
     2637    return shadowRoot() ? toMediaControls(shadowRoot()->firstChild()) : 0;
     2638}
     2639
     2640bool HTMLMediaElement::hasMediaControls()
     2641{
     2642    return shadowRoot();
     2643}
     2644
     2645void HTMLMediaElement::ensureMediaControls()
     2646{
     2647    if (hasMediaControls())
     2648        return;
     2649
     2650    ExceptionCode ec;
     2651    ensureShadowRoot()->appendChild(MediaControls::create(this), ec);
     2652}
     2653
     2654}
     2655
     2656#endif
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r82053 r83397  
    324324    void refreshCachedTime() const;
    325325
    326     bool hasMediaControls() const;
     326    bool hasMediaControls();
     327    void ensureMediaControls();
    327328
    328329    Timer<HTMLMediaElement> m_loadTimer;
     
    405406    bool m_isFullscreen : 1;
    406407    bool m_closedCaptionsVisible : 1;
     408    bool m_mouseOver : 1;
    407409
    408410#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
  • trunk/Source/WebCore/html/shadow/MediaControls.cpp

    r82053 r83397  
    4848using namespace HTMLNames;
    4949
    50 static const double cOpacityAnimationRepeatDelay = 0.05;
    51 
    5250MediaControls::MediaControls(HTMLMediaElement* mediaElement)
    53     : m_mediaElement(mediaElement)
    54     , m_opacityAnimationTimer(this, &MediaControls::opacityAnimationTimerFired)
    55     , m_opacityAnimationStartTime(0)
    56     , m_opacityAnimationDuration(0)
    57     , m_opacityAnimationFrom(0)
    58     , m_opacityAnimationTo(1.0f)
    59     , m_mouseOver(false)
    60 {
    61 }
    62 
    63 // FIXME: This will turn into the standard element factory method once shadow DOM conversion is complete.
    64 // (see https://bugs.webkit.org/show_bug.cgi?id=53020)
    65 PassRefPtr<MediaControlShadowRootElement> MediaControls::create(HTMLMediaElement* mediaElement)
    66 {
    67     ASSERT(!m_panel);
    68     ASSERT(!m_muteButton);
    69     ASSERT(!m_playButton);
    70     ASSERT(!m_returnToRealtimeButton);
    71     ASSERT(!m_statusDisplay);
    72     ASSERT(!m_timelineContainer);
    73     ASSERT(!m_currentTimeDisplay);
    74     ASSERT(!m_timeline);
    75     ASSERT(!m_timeRemainingDisplay);
    76     ASSERT(!m_seekBackButton);
    77     ASSERT(!m_seekForwardButton);
    78     ASSERT(!m_toggleClosedCaptionsButton);
    79     ASSERT(!m_fullscreenButton);
    80     ASSERT(!m_muteButton);
    81     ASSERT(!m_volumeSliderContainer);
    82     ASSERT(!m_volumeSlider);
    83     ASSERT(!m_volumeSliderMuteButton);
    84     ASSERT(!m_fullScreenMinVolumeButton);
    85     ASSERT(!m_fullScreenMaxVolumeButton);
    86     ASSERT(!m_fullScreenVolumeSlider);
    87 
    88     RefPtr<MediaControlShadowRootElement> controls = MediaControlShadowRootElement::create(mediaElement);
    89 
    90     m_panel = MediaControlPanelElement::create(mediaElement);
    91 
    92     m_rewindButton = MediaControlRewindButtonElement::create(mediaElement);
    93     m_rewindButton->attachToParent(m_panel.get());
    94 
    95     m_playButton = MediaControlPlayButtonElement::create(mediaElement);
    96     m_playButton->attachToParent(m_panel.get());
    97 
    98     m_returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement);
    99     m_returnToRealtimeButton->attachToParent(m_panel.get());
    100 
    101     m_statusDisplay = MediaControlStatusDisplayElement::create(mediaElement);
    102     m_statusDisplay->attachToParent(m_panel.get());
    103 
    104     m_timelineContainer = MediaControlTimelineContainerElement::create(mediaElement);
    105 
    106     m_currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement);
    107     m_currentTimeDisplay->attachToParent(m_timelineContainer.get());
    108 
    109     m_timeline = MediaControlTimelineElement::create(mediaElement);
    110     m_timeline->attachToParent(m_timelineContainer.get());
    111 
    112     m_timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement);
    113     m_timeRemainingDisplay->attachToParent(m_timelineContainer.get());
    114 
    115     m_timelineContainer->attachToParent(m_panel.get());
    116 
    117     m_seekBackButton = MediaControlSeekBackButtonElement::create(mediaElement);
    118     m_seekBackButton->attachToParent(m_panel.get());
    119 
    120     m_seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement);
    121     m_seekForwardButton->attachToParent(m_panel.get());
    122 
    123     m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
    124     m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
    125 
    126     m_fullscreenButton = MediaControlFullscreenButtonElement::create(mediaElement);
    127     m_fullscreenButton->attachToParent(m_panel.get());
    128 
    129     m_muteButton = MediaControlPanelMuteButtonElement::create(mediaElement);
    130     m_muteButton->attachToParent(m_panel.get());
    131 
    132     m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);
    133 
    134     m_volumeSlider = MediaControlVolumeSliderElement::create(mediaElement);
    135     m_volumeSlider->attachToParent(m_volumeSliderContainer.get());
    136 
    137     m_volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
    138     m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get());
    139 
    140     m_volumeSliderContainer->attachToParent(m_panel.get());
    141    
    142     // FIXME: These controls, and others, should be created dynamically when needed, instead of
    143     // always created.  <http://webkit.org/b/57163>
    144     m_fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement);
    145     m_fullScreenMinVolumeButton->attachToParent(m_panel.get());
    146    
    147     m_fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement);
    148     m_fullScreenVolumeSlider->attachToParent(m_panel.get());
    149    
    150     m_fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement);
    151     m_fullScreenMaxVolumeButton->attachToParent(m_panel.get());
    152    
    153     m_panel->attachToParent(controls.get());
     51    : HTMLDivElement(divTag, mediaElement->document())
     52    , m_mediaElement(mediaElement)
     53    , m_rewindButton(0)
     54    , m_playButton(0)
     55    , m_returnToRealTimeButton(0)
     56    , m_statusDisplay(0)
     57    , m_currentTimeDisplay(0)
     58    , m_timeline(0)
     59    , m_timeRemainingDisplay(0)
     60    , m_timelineContainer(0)
     61    , m_seekBackButton(0)
     62    , m_seekForwardButton(0)
     63    , m_toggleClosedCaptionsButton(0)
     64    , m_panelMuteButton(0)
     65    , m_volumeSlider(0)
     66    , m_volumeSliderMuteButton(0)
     67    , m_volumeSliderContainer(0)
     68    , m_fullScreenButton(0)
     69    , m_fullScreenMinVolumeButton(0)
     70    , m_fullScreenVolumeSlider(0)
     71    , m_fullScreenMaxVolumeButton(0)
     72    , m_panel(0)
     73    , m_opaque(true)
     74{
     75}
     76
     77PassRefPtr<MediaControls> MediaControls::create(HTMLMediaElement* mediaElement)
     78{
     79    if (!mediaElement->document()->page())
     80        return 0;
     81
     82    RefPtr<MediaControls> controls = adoptRef(new MediaControls(mediaElement));
     83
     84    RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(mediaElement);
     85
     86    // FIXME: WHAT TO DO WITH ec??!?!?!?!
     87    ExceptionCode ec;
     88
     89    RefPtr<MediaControlRewindButtonElement> rewindButton = MediaControlRewindButtonElement::create(mediaElement);
     90    controls->m_rewindButton = rewindButton.get();
     91    panel->appendChild(rewindButton.release(), ec, true);
     92    if (ec)
     93        return 0;
     94
     95    RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(mediaElement);
     96    controls->m_playButton = playButton.get();
     97    panel->appendChild(playButton.release(), ec, true);
     98    if (ec)
     99        return 0;
     100
     101    RefPtr<MediaControlReturnToRealtimeButtonElement> returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement);
     102    controls->m_returnToRealTimeButton = returnToRealtimeButton.get();
     103    panel->appendChild(returnToRealtimeButton.release(), ec, true);
     104    if (ec)
     105        return 0;
     106
     107    if (mediaElement->document()->page()->theme()->usesMediaControlStatusDisplay()) {
     108        RefPtr<MediaControlStatusDisplayElement> statusDisplay = MediaControlStatusDisplayElement::create(mediaElement);
     109        controls->m_statusDisplay = statusDisplay.get();
     110        panel->appendChild(statusDisplay.release(), ec, true);
     111        if (ec)
     112            return 0;
     113    }
     114
     115    RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(mediaElement);
     116
     117    RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement);
     118    controls->m_currentTimeDisplay = currentTimeDisplay.get();
     119    timelineContainer->appendChild(currentTimeDisplay.release(), ec, true);
     120    if (ec)
     121        return 0;
     122
     123    RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(mediaElement, controls.get());
     124    controls->m_timeline = timeline.get();
     125    timelineContainer->appendChild(timeline.release(), ec, true);
     126    if (ec)
     127        return 0;
     128
     129    RefPtr<MediaControlTimeRemainingDisplayElement> timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement);
     130    controls->m_timeRemainingDisplay = timeRemainingDisplay.get();
     131    timelineContainer->appendChild(timeRemainingDisplay.release(), ec, true);
     132    if (ec)
     133        return 0;
     134
     135    controls->m_timelineContainer = timelineContainer.get();
     136    panel->appendChild(timelineContainer.release(), ec, true);
     137    if (ec)
     138        return 0;
     139
     140    // FIXME: Only create when needed <http://webkit.org/b/57163>
     141    RefPtr<MediaControlSeekBackButtonElement> seekBackButton = MediaControlSeekBackButtonElement::create(mediaElement);
     142    controls->m_seekBackButton = seekBackButton.get();
     143    panel->appendChild(seekBackButton.release(), ec, true);
     144    if (ec)
     145        return 0;
     146
     147    // FIXME: Only create when needed <http://webkit.org/b/57163>
     148    RefPtr<MediaControlSeekForwardButtonElement> seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement);
     149    controls->m_seekForwardButton = seekForwardButton.get();
     150    panel->appendChild(seekForwardButton.release(), ec, true);
     151    if (ec)
     152        return 0;
     153
     154    if (mediaElement->document()->page()->theme()->supportsClosedCaptioning()) {
     155        RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
     156        controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
     157        panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
     158        if (ec)
     159            return 0;
     160    }
     161
     162    // FIXME: Only create when needed <http://webkit.org/b/57163>
     163    RefPtr<MediaControlFullscreenButtonElement> fullScreenButton = MediaControlFullscreenButtonElement::create(mediaElement, controls.get());
     164    controls->m_fullScreenButton = fullScreenButton.get();
     165    panel->appendChild(fullScreenButton.release(), ec, true);
     166
     167    RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(mediaElement, controls.get());
     168    controls->m_panelMuteButton = panelMuteButton.get();
     169    panel->appendChild(panelMuteButton.release(), ec, true);
     170    if (ec)
     171        return 0;
     172
     173    if (mediaElement->document()->page()->theme()->usesMediaControlVolumeSlider()) {
     174        RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);
     175
     176        RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(mediaElement);
     177        controls->m_volumeSlider = slider.get();
     178        volumeSliderContainer->appendChild(slider.release(), ec, true);
     179        if (ec)
     180            return 0;
     181
     182        RefPtr<MediaControlVolumeSliderMuteButtonElement> volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
     183        controls->m_volumeSliderMuteButton = volumeSliderMuteButton.get();
     184        volumeSliderContainer->appendChild(volumeSliderMuteButton.release(), ec, true);
     185        if (ec)
     186            return 0;
     187
     188        controls->m_volumeSliderContainer = volumeSliderContainer.get();
     189        panel->appendChild(volumeSliderContainer.release(), ec, true);
     190        if (ec)
     191            return 0;
     192    }
     193
     194    // FIXME: Only create when needed <http://webkit.org/b/57163>
     195    RefPtr<MediaControlFullscreenVolumeMinButtonElement> fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement);
     196    controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.get();
     197    panel->appendChild(fullScreenMinVolumeButton.release(), ec, true);
     198    if (ec)
     199        return 0;
     200
     201    RefPtr<MediaControlFullscreenVolumeSliderElement> fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement);
     202    controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.get();
     203    panel->appendChild(fullScreenVolumeSlider.release(), ec, true);
     204    if (ec)
     205        return 0;
     206
     207    RefPtr<MediaControlFullscreenVolumeMaxButtonElement> fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement);
     208    controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.get();
     209    panel->appendChild(fullScreenMaxVolumeButton.release(), ec, true);
     210    if (ec)
     211        return 0;
     212
     213    controls->m_panel = panel.get();
     214    controls->appendChild(panel.release(), ec, true);
     215    if (ec)
     216        return 0;
     217
    154218    return controls.release();
    155219}
    156220
     221void MediaControls::show()
     222{
     223    m_panel->show();
     224}
     225
     226void MediaControls::hide()
     227{
     228    m_panel->hide();
     229}
     230
     231static const String& webkitTransitionString()
     232{
     233    DEFINE_STATIC_LOCAL(String, s, ("-webkit-transition"));
     234    return s;
     235}
     236
     237static const String& opacityString()
     238{
     239    DEFINE_STATIC_LOCAL(String, s, ("opacity"));
     240    return s;
     241}
     242
     243void MediaControls::makeOpaque()
     244{
     245    if (m_opaque)
     246        return;
     247
     248    DEFINE_STATIC_LOCAL(String, transitionValue, ());
     249    if (transitionValue.isNull())
     250        transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeInDuration());
     251    DEFINE_STATIC_LOCAL(String, opacityValue, ("1"));
     252
     253    ExceptionCode ec;
     254    // FIXME: Make more efficient <http://webkit.org/b/58157>
     255    m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
     256    m_panel->style()->setProperty(opacityString(), opacityValue, ec);
     257    m_opaque = true;
     258}
     259
     260void MediaControls::makeTransparent()
     261{
     262    if (!m_opaque)
     263        return;
     264
     265    DEFINE_STATIC_LOCAL(String, transitionValue, ());
     266    if (transitionValue.isNull())
     267        transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeOutDuration());
     268    DEFINE_STATIC_LOCAL(String, opacityValue, ("0"));
     269
     270    ExceptionCode ec;
     271    // FIXME: Make more efficient <http://webkit.org/b/58157>
     272    m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
     273    m_panel->style()->setProperty(opacityString(), opacityValue, ec);
     274    m_opaque = false;
     275}
     276
    157277void MediaControls::reset()
    158278{
    159     update();
     279    Page* page = document()->page();
     280    if (!page)
     281        return;
     282
     283    changedNetworkState();
     284    float duration = m_mediaElement->duration();
     285    if (!isnan(duration) || page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
     286        m_timeline->setDuration(duration);
     287        m_timelineContainer->show();
     288        m_timeline->setPosition(m_mediaElement->currentTime());
     289        updateTimeDisplay();
     290    } else
     291        m_timelineContainer->hide();
     292
     293    if (m_mediaElement->hasAudio() || page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
     294        m_panelMuteButton->show();
     295    else
     296        m_panelMuteButton->hide();
     297
     298    if (m_volumeSlider)
     299        m_volumeSlider->setVolume(m_mediaElement->volume());
     300
     301    if (m_toggleClosedCaptionsButton) {
     302        if (m_mediaElement->hasClosedCaptions())
     303            m_toggleClosedCaptionsButton->show();
     304        else
     305            m_toggleClosedCaptionsButton->hide();
     306    }
     307
     308    if (m_mediaElement->movieLoadType() != MediaPlayer::LiveStream) {
     309        m_returnToRealTimeButton->hide();
     310        m_rewindButton->show();
     311    } else {
     312        m_returnToRealTimeButton->show();
     313        m_rewindButton->hide();
     314    }
     315
     316    makeOpaque();
     317}
     318
     319void MediaControls::playbackStarted()
     320{
     321    m_playButton->updateDisplayType();
     322    m_timeline->setPosition(m_mediaElement->currentTime());
     323    updateTimeDisplay();
    160324}
    161325
    162326void MediaControls::playbackProgressed()
    163327{
    164     if (m_timeline)
    165         m_timeline->update(false);
     328    m_timeline->setPosition(m_mediaElement->currentTime());
    166329    updateTimeDisplay();
    167330}
    168331
    169 void MediaControls::playbackStarted()
    170 {
    171     playbackProgressed();
    172 }
    173 
    174332void MediaControls::playbackStopped()
    175333{
    176     playbackProgressed();
    177 }
    178 
    179 void MediaControls::changedMute()
    180 {
    181     update();
    182 }
    183 
    184 void MediaControls::changedVolume()
    185 {
    186     update();
    187 }
    188 
    189 void MediaControls::changedClosedCaptionsVisibility()
    190 {
    191     update();
    192 }
    193 
    194 void MediaControls::updateStyle()
    195 {
    196     if (!m_controlsShadowRoot)
    197         return;
    198 
    199     if (m_panel)
    200         m_panel->updateStyle();
    201     if (m_muteButton)
    202         m_muteButton->updateStyle();
    203     if (m_playButton)
    204         m_playButton->updateStyle();
    205     if (m_seekBackButton)
    206         m_seekBackButton->updateStyle();
    207     if (m_seekForwardButton)
    208         m_seekForwardButton->updateStyle();
    209     if (m_rewindButton)
    210         m_rewindButton->updateStyle();
    211     if (m_returnToRealtimeButton)
    212         m_returnToRealtimeButton->updateStyle();
    213     if (m_toggleClosedCaptionsButton)
    214         m_toggleClosedCaptionsButton->updateStyle();
    215     if (m_statusDisplay)
    216         m_statusDisplay->updateStyle();
    217     if (m_timelineContainer)
    218         m_timelineContainer->updateStyle();
    219     if (m_timeline)
    220         m_timeline->updateStyle();
    221     if (m_fullscreenButton)
    222         m_fullscreenButton->updateStyle();
    223     if (m_currentTimeDisplay)
    224         m_currentTimeDisplay->updateStyle();
    225     if (m_timeRemainingDisplay)
    226         m_timeRemainingDisplay->updateStyle();
     334    m_playButton->updateDisplayType();
     335    m_timeline->setPosition(m_mediaElement->currentTime());
     336    updateTimeDisplay();
     337    makeOpaque();
     338}
     339
     340void MediaControls::updateTimeDisplay()
     341{
     342    float now = m_mediaElement->currentTime();
     343    float duration = m_mediaElement->duration();
     344
     345    Page* page = document()->page();
     346    if (!page)
     347        return;
     348
     349    // Allow the theme to format the time.
     350    ExceptionCode ec;
     351    m_currentTimeDisplay->setInnerText(page->theme()->formatMediaControlsCurrentTime(now, duration), ec);
     352    m_currentTimeDisplay->setCurrentValue(now);
     353    m_timeRemainingDisplay->setInnerText(page->theme()->formatMediaControlsRemainingTime(now, duration), ec);
     354    m_timeRemainingDisplay->setCurrentValue(now - duration);
     355}
     356
     357void MediaControls::reportedError()
     358{
     359    Page* page = document()->page();
     360    if (!page)
     361        return;
     362
     363    if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart))
     364        m_timelineContainer->hide();
     365
     366    if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
     367        m_panelMuteButton->hide();
     368
     369     m_fullScreenButton->hide();
     370
    227371    if (m_volumeSliderContainer)
    228         m_volumeSliderContainer->updateStyle();
    229     if (m_volumeSliderMuteButton)
    230         m_volumeSliderMuteButton->updateStyle();
    231     if (m_volumeSlider)
    232         m_volumeSlider->updateStyle();
    233     if (m_fullScreenMinVolumeButton)
    234         m_fullScreenMinVolumeButton->updateStyle();
    235     if (m_fullScreenVolumeSlider)
    236         m_fullScreenVolumeSlider->updateStyle();
    237     if (m_fullScreenMaxVolumeButton)
    238         m_fullScreenMaxVolumeButton->updateStyle();
    239 }
    240 
    241 void MediaControls::destroy()
    242 {
    243     ASSERT(m_mediaElement->renderer());
    244 
    245     if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) {
    246 
    247         // detach the panel before removing the shadow renderer to prevent a crash in m_controlsShadowRoot->detach()
    248         //  when display: style changes
    249         m_panel->detach();
    250 
    251         m_mediaElement->renderer()->removeChild(m_controlsShadowRoot->renderer());
    252         m_controlsShadowRoot->detach();
    253         m_controlsShadowRoot = 0;
    254     }
    255 }
    256 
    257 void MediaControls::update()
    258 {
    259     HTMLMediaElement* media = m_mediaElement;
    260     if (!media->controls() || !media->inActiveDocument()) {
    261         if (m_controlsShadowRoot) {
    262             m_controlsShadowRoot->detach();
    263             m_panel = 0;
    264             m_muteButton = 0;
    265             m_playButton = 0;
    266             m_statusDisplay = 0;
    267             m_timelineContainer = 0;
    268             m_timeline = 0;
    269             m_seekBackButton = 0;
    270             m_seekForwardButton = 0;
    271             m_rewindButton = 0;
    272             m_returnToRealtimeButton = 0;
    273             m_currentTimeDisplay = 0;
    274             m_timeRemainingDisplay = 0;
    275             m_fullscreenButton = 0;
    276             m_volumeSliderContainer = 0;
    277             m_volumeSlider = 0;
    278             m_volumeSliderMuteButton = 0;
    279             m_controlsShadowRoot = 0;
    280             m_toggleClosedCaptionsButton = 0;
    281             m_fullScreenMinVolumeButton = 0;
    282             m_fullScreenVolumeSlider = 0;
    283             m_fullScreenMaxVolumeButton = 0;
    284         }
    285         m_opacityAnimationTo = 1.0f;
    286         m_opacityAnimationTimer.stop();
    287         return;
    288     }
    289 
    290     if (!m_controlsShadowRoot) {
    291         m_controlsShadowRoot = create(m_mediaElement);
    292         m_mediaElement->renderer()->addChild(m_controlsShadowRoot->renderer());
    293         m_panel->attach();
    294     }
    295 
    296     if (m_panel) {
    297         // update() might alter the opacity of the element, especially if we are in the middle
    298         // of an animation. This is the only element concerned as we animate only this element.
    299         float opacityBeforeChangingStyle = m_panel->renderer() ? m_panel->renderer()->style()->opacity() : 0;
    300         m_panel->update();
    301         changeOpacity(m_panel.get(), opacityBeforeChangingStyle);
    302     }
    303     if (m_muteButton)
    304         m_muteButton->update();
    305     if (m_playButton)
    306         m_playButton->update();
    307     if (m_timelineContainer)
    308         m_timelineContainer->update();
    309     if (m_volumeSliderContainer)
    310         m_volumeSliderContainer->update();
    311     if (m_timeline)
    312         m_timeline->update();
    313     if (m_currentTimeDisplay)
    314         m_currentTimeDisplay->update();
    315     if (m_timeRemainingDisplay)
    316         m_timeRemainingDisplay->update();
    317     if (m_seekBackButton)
    318         m_seekBackButton->update();
    319     if (m_seekForwardButton)
    320         m_seekForwardButton->update();
    321     if (m_rewindButton)
    322         m_rewindButton->update();
    323     if (m_returnToRealtimeButton)
    324         m_returnToRealtimeButton->update();
    325     if (m_toggleClosedCaptionsButton)
    326         m_toggleClosedCaptionsButton->update();
     372        m_volumeSliderContainer->hide();
     373    if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
     374        m_toggleClosedCaptionsButton->hide();
     375}
     376
     377void MediaControls::changedNetworkState()
     378{
     379    // FIXME: Why are we changing fullscreen button visibility here? <http://webkit.org/b/58163>
     380    if (m_mediaElement->supportsFullscreen())
     381        m_fullScreenButton->show();
     382    else
     383        m_fullScreenButton->hide();
     384
    327385    if (m_statusDisplay)
    328386        m_statusDisplay->update();
    329     if (m_fullscreenButton)
    330         m_fullscreenButton->update();
     387}
     388
     389void MediaControls::loadedMetadata()
     390{
     391    if (m_statusDisplay)
     392        m_statusDisplay->hide();
     393
     394    reset();
     395}
     396
     397void MediaControls::changedClosedCaptionsVisibility()
     398{
     399    if (m_toggleClosedCaptionsButton)
     400        m_toggleClosedCaptionsButton->updateDisplayType();
     401}
     402
     403void MediaControls::changedMute()
     404{
     405    m_panelMuteButton->changedMute();
     406    if (m_volumeSliderMuteButton)
     407        m_volumeSliderMuteButton->changedMute();
     408}
     409
     410void MediaControls::changedVolume()
     411{
    331412    if (m_volumeSlider)
    332         m_volumeSlider->update();
    333     if (m_volumeSliderMuteButton)
    334         m_volumeSliderMuteButton->update();
    335     if (m_fullScreenMinVolumeButton)
    336         m_fullScreenMinVolumeButton->update();
    337     if (m_fullScreenVolumeSlider)
    338         m_fullScreenVolumeSlider->update();
    339     if (m_fullScreenMaxVolumeButton)
    340         m_fullScreenMaxVolumeButton->update();
    341     updateTimeDisplay();
    342     updateControlVisibility();
    343 }
    344 
    345 void MediaControls::updateTimeDisplay()
    346 {
    347     ASSERT(m_mediaElement->renderer());
    348 
    349     if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || m_mediaElement->renderer()->style()->visibility() != VISIBLE)
    350         return;
    351 
    352     float now = m_mediaElement->currentTime();
    353     float duration = m_mediaElement->duration();
    354 
    355     // Allow the theme to format the time
    356     ExceptionCode ec;
    357     m_currentTimeDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsCurrentTime(now, duration), ec);
    358     m_currentTimeDisplay->setCurrentValue(now);
    359     m_timeRemainingDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsRemainingTime(now, duration), ec);
    360     m_timeRemainingDisplay->setCurrentValue(now - duration);
    361 }
    362 
    363 RenderBox* MediaControls::renderBox()
    364 {
    365     return m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
    366 }
    367 
    368 void MediaControls::updateControlVisibility()
    369 {
    370     if (!m_panel || !m_panel->renderer())
    371         return;
    372 
    373     // Don't fade for audio controls.
    374     HTMLMediaElement* media = m_mediaElement;
    375     if (!media->hasVideo())
    376         return;
    377 
    378     ASSERT(media->renderer());
    379 
    380     // Don't fade if the media element is not visible
    381     if (media->renderer()->style()->visibility() != VISIBLE)
    382         return;
    383    
    384     bool shouldHideController = !m_mouseOver && !media->canPlay();
    385 
    386     // Do fading manually, css animations don't work with shadow trees
    387 
    388     float animateFrom = m_panel->renderer()->style()->opacity();
    389     float animateTo = shouldHideController ? 0.0f : 1.0f;
    390 
    391     if (animateFrom == animateTo)
    392         return;
    393 
    394     if (m_opacityAnimationTimer.isActive()) {
    395         if (m_opacityAnimationTo == animateTo)
    396             return;
    397         m_opacityAnimationTimer.stop();
    398     }
    399 
    400     if (animateFrom < animateTo)
    401         m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration();
    402     else
    403         m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration();
    404 
    405     m_opacityAnimationFrom = animateFrom;
    406     m_opacityAnimationTo = animateTo;
    407 
    408     m_opacityAnimationStartTime = currentTime();
    409     m_opacityAnimationTimer.startRepeating(cOpacityAnimationRepeatDelay);
    410 }
    411 
    412 void MediaControls::changeOpacity(HTMLElement* e, float opacity)
    413 {
    414     if (!e || !e->renderer() || !e->renderer()->style())
    415         return;
    416     RefPtr<RenderStyle> s = RenderStyle::clone(e->renderer()->style());
    417     s->setOpacity(opacity);
    418     // z-index can't be auto if opacity is used
    419     s->setZIndex(0);
    420     e->renderer()->setStyle(s.release());
    421 }
    422 
    423 void MediaControls::opacityAnimationTimerFired(Timer<MediaControls>*)
    424 {
    425     double time = currentTime() - m_opacityAnimationStartTime;
    426     if (time >= m_opacityAnimationDuration) {
    427         time = m_opacityAnimationDuration;
    428         m_opacityAnimationTimer.stop();
    429     }
    430     float opacity = narrowPrecisionToFloat(m_opacityAnimationFrom + (m_opacityAnimationTo - m_opacityAnimationFrom) * time / m_opacityAnimationDuration);
    431     changeOpacity(m_panel.get(), opacity);
    432 }
    433 
    434 void MediaControls::updateVolumeSliderContainer(bool visible)
    435 {
    436     if (!m_mediaElement->hasAudio() || !m_volumeSliderContainer || !m_volumeSlider)
    437         return;
    438 
    439     if (visible && !m_volumeSliderContainer->isVisible()) {
    440         if (!m_muteButton || !m_muteButton->renderer() || !m_muteButton->renderBox())
    441             return;
    442 
    443         RefPtr<RenderStyle> s = m_volumeSliderContainer->styleForElement();
    444         m_volumeSliderContainer->setVisible(true);
    445         m_volumeSliderContainer->update();
    446         m_volumeSlider->update();
    447     } else if (!visible && m_volumeSliderContainer->isVisible()) {
    448         m_volumeSliderContainer->setVisible(false);
    449         m_volumeSliderContainer->updateStyle();
    450     }
    451 }
    452 
    453 void MediaControls::forwardEvent(Event* event)
    454 {
    455     ASSERT(m_mediaElement->renderer());
    456 
    457     if (event->isMouseEvent() && m_controlsShadowRoot) {
    458         MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
    459         IntPoint point(mouseEvent->absoluteLocation());
    460 
    461         bool defaultHandled = false;
    462         if (m_volumeSliderMuteButton && m_volumeSliderMuteButton->hitTest(point)) {
    463             m_volumeSliderMuteButton->defaultEventHandler(event);
    464             defaultHandled = event->defaultHandled();
    465         }
    466 
    467         bool showVolumeSlider = false;
    468         if (!defaultHandled && m_muteButton && m_muteButton->hitTest(point)) {
    469             m_muteButton->defaultEventHandler(event);
    470             if (event->type() != eventNames().mouseoutEvent)
    471                 showVolumeSlider = true;
    472         }
    473 
    474         if (m_volumeSliderContainer && m_volumeSliderContainer->hitTest(point))
    475             showVolumeSlider = true;
    476 
    477         if (m_volumeSlider && m_volumeSlider->hitTest(point)) {
    478             m_volumeSlider->defaultEventHandler(event);
    479             showVolumeSlider = true;
    480         }
    481 
    482         updateVolumeSliderContainer(showVolumeSlider);
    483 
    484         if (m_playButton && m_playButton->hitTest(point))
    485             m_playButton->defaultEventHandler(event);
    486 
    487         if (m_seekBackButton && m_seekBackButton->hitTest(point))
    488             m_seekBackButton->defaultEventHandler(event);
    489 
    490         if (m_seekForwardButton && m_seekForwardButton->hitTest(point))
    491             m_seekForwardButton->defaultEventHandler(event);
    492 
    493         if (m_rewindButton && m_rewindButton->hitTest(point))
    494             m_rewindButton->defaultEventHandler(event);
    495 
    496         if (m_returnToRealtimeButton && m_returnToRealtimeButton->hitTest(point))
    497             m_returnToRealtimeButton->defaultEventHandler(event);
    498 
    499        if (m_toggleClosedCaptionsButton && m_toggleClosedCaptionsButton->hitTest(point))
    500             m_toggleClosedCaptionsButton->defaultEventHandler(event);
    501 
    502         if (m_timeline && m_timeline->hitTest(point))
    503             m_timeline->defaultEventHandler(event);
    504 
    505         if (m_fullscreenButton && m_fullscreenButton->hitTest(point))
    506             m_fullscreenButton->defaultEventHandler(event);
    507 
    508         if (event->type() == eventNames().mouseoverEvent) {
    509             m_mouseOver = true;
    510             updateControlVisibility();
    511         }
    512         if (event->type() == eventNames().mouseoutEvent) {
    513             // When the scrollbar thumb captures mouse events, we should treat the mouse as still being over our renderer if the new target is a descendant
    514             Node* mouseOverNode = mouseEvent->relatedTarget() ? mouseEvent->relatedTarget()->toNode() : 0;
    515             RenderObject* mouseOverRenderer = mouseOverNode ? mouseOverNode->renderer() : 0;
    516             m_mouseOver = mouseOverRenderer && mouseOverRenderer->isDescendantOf(m_mediaElement->renderer());
    517             updateControlVisibility();
    518         }
    519     }
     413        m_volumeSlider->setVolume(m_mediaElement->volume());
     414}
     415
     416void MediaControls::enteredFullscreen()
     417{
     418    if (m_mediaElement->movieLoadType() == MediaPlayer::LiveStream || m_mediaElement->movieLoadType() == MediaPlayer::StoredStream) {
     419        m_seekBackButton->hide();
     420        m_seekForwardButton->hide();
     421    } else
     422        m_rewindButton->hide();
     423}
     424
     425void MediaControls::exitedFullscreen()
     426{
     427    // "show" actually means removal of display:none style, so we are just clearing styles
     428    // when exiting fullscreen.
     429    // FIXME: Clarify naming of show/hide <http://webkit.org/b/58157>
     430    m_rewindButton->show();
     431    m_seekBackButton->show();
     432    m_seekForwardButton->show();
     433}
     434
     435void MediaControls::showVolumeSlider()
     436{
     437    if (!m_mediaElement->hasAudio())
     438        return;
     439
     440    if (m_volumeSliderContainer)
     441        m_volumeSliderContainer->show();
     442}
     443
     444const AtomicString& MediaControls::shadowPseudoId() const
     445{
     446    DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
     447    return id;
    520448}
    521449
  • trunk/Source/WebCore/html/shadow/MediaControls.h

    r82053 r83397  
    3030#if ENABLE(VIDEO)
    3131
     32#include "HTMLDivElement.h"
    3233#include "Timer.h"
    3334#include <wtf/RefPtr.h>
     
    3940class HTMLMediaElement;
    4041class Event;
    41 class MediaControlMuteButtonElement;
     42class MediaControlPanelMuteButtonElement;
    4243class MediaControlPlayButtonElement;
    4344class MediaControlSeekButtonElement;
    44 class MediaControlShadowRootElement;
    4545class MediaControlRewindButtonElement;
    4646class MediaControlReturnToRealtimeButtonElement;
    4747class MediaControlToggleClosedCaptionsButtonElement;
     48class MediaControlCurrentTimeDisplayElement;
    4849class MediaControlTimelineElement;
     50class MediaControlTimeRemainingDisplayElement;
    4951class MediaControlVolumeSliderElement;
    5052class MediaControlFullscreenButtonElement;
     
    5254class MediaControlStatusDisplayElement;
    5355class MediaControlTimelineContainerElement;
     56class MediaControlSeekBackButtonElement;
     57class MediaControlSeekForwardButtonElement;
     58class MediaControlMuteButtonElement;
     59class MediaControlVolumeSliderElement;
     60class MediaControlVolumeSliderMuteButtonElement;
    5461class MediaControlVolumeSliderContainerElement;
    55 class MediaControlElement;
    5662class MediaControlFullscreenVolumeMinButtonElement;
    5763class MediaControlFullscreenVolumeSliderElement;
    5864class MediaControlFullscreenVolumeMaxButtonElement;
     65class MediaControlPanelElement;
    5966class MediaPlayer;
    6067
     
    6269class RenderMedia;
    6370
    64 class MediaControls {
     71// FIXME: Rename to MediaControlRootElement.
     72class MediaControls : public HTMLDivElement {
    6573public:
    66     MediaControls(HTMLMediaElement*);
     74    static PassRefPtr<MediaControls> create(HTMLMediaElement*);
     75
     76    void show();
     77    void hide();
     78    void makeOpaque();
     79    void makeTransparent();
    6780
    6881    void reset();
     
    7487    void changedMute();
    7588    void changedVolume();
     89
     90    void enteredFullscreen();
     91    void exitedFullscreen();
     92
     93    void reportedError();
     94    void changedNetworkState();
     95    void loadedMetadata();
    7696    void changedClosedCaptionsVisibility();
    7797
    78     void destroy();
    79     void update();
    80     void updateStyle();
    81     void forwardEvent(Event*);
     98    void showVolumeSlider();
    8299    void updateTimeDisplay();
    83100
    84     // FIXME: This is temporary to allow RenderMedia::layout tweak the position of controls.
    85     // Once shadow DOM refactoring is complete, the tweaking will be in MediaControlsShadowRoot and this accessor will no longer be necessary.
    86     RenderBox* renderBox();
     101private:
     102    MediaControls(HTMLMediaElement*);
    87103
    88 private:
    89     PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
    90 
    91     void updateControlVisibility();
    92     void changeOpacity(HTMLElement*, float opacity);
    93     void opacityAnimationTimerFired(Timer<MediaControls>*);
    94 
    95     void updateVolumeSliderContainer(bool visible);
    96 
    97 private:
    98     RefPtr<MediaControlShadowRootElement> m_controlsShadowRoot;
    99     RefPtr<MediaControlElement> m_panel;
    100     RefPtr<MediaControlMuteButtonElement> m_muteButton;
    101     RefPtr<MediaControlPlayButtonElement> m_playButton;
    102     RefPtr<MediaControlSeekButtonElement> m_seekBackButton;
    103     RefPtr<MediaControlSeekButtonElement> m_seekForwardButton;
    104     RefPtr<MediaControlRewindButtonElement> m_rewindButton;
    105     RefPtr<MediaControlReturnToRealtimeButtonElement> m_returnToRealtimeButton;
    106     RefPtr<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
    107     RefPtr<MediaControlTimelineElement> m_timeline;
    108     RefPtr<MediaControlVolumeSliderElement> m_volumeSlider;
    109     RefPtr<MediaControlMuteButtonElement> m_volumeSliderMuteButton;
    110     RefPtr<MediaControlFullscreenButtonElement> m_fullscreenButton;
    111     RefPtr<MediaControlTimelineContainerElement> m_timelineContainer;
    112     RefPtr<MediaControlVolumeSliderContainerElement> m_volumeSliderContainer;
    113     RefPtr<MediaControlTimeDisplayElement> m_currentTimeDisplay;
    114     RefPtr<MediaControlTimeDisplayElement> m_timeRemainingDisplay;
    115     RefPtr<MediaControlStatusDisplayElement> m_statusDisplay;
    116     RefPtr<MediaControlFullscreenVolumeMinButtonElement> m_fullScreenMinVolumeButton;
    117     RefPtr<MediaControlFullscreenVolumeSliderElement> m_fullScreenVolumeSlider;
    118     RefPtr<MediaControlFullscreenVolumeMaxButtonElement> m_fullScreenMaxVolumeButton;
     104    virtual const AtomicString& shadowPseudoId() const;
    119105
    120106    HTMLMediaElement* m_mediaElement;
    121     Timer<MediaControls> m_opacityAnimationTimer;
    122107
    123     double m_opacityAnimationStartTime;
    124     double m_opacityAnimationDuration;
    125     float m_opacityAnimationFrom;
    126     float m_opacityAnimationTo;
     108    MediaControlRewindButtonElement* m_rewindButton;
     109    MediaControlPlayButtonElement* m_playButton;
     110    MediaControlReturnToRealtimeButtonElement* m_returnToRealTimeButton;
     111    MediaControlStatusDisplayElement* m_statusDisplay;
     112    MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
     113    MediaControlTimelineElement* m_timeline;
     114    MediaControlTimeRemainingDisplayElement* m_timeRemainingDisplay;
     115    MediaControlTimelineContainerElement* m_timelineContainer;
     116    MediaControlSeekBackButtonElement* m_seekBackButton;
     117    MediaControlSeekForwardButtonElement* m_seekForwardButton;
     118    MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
     119    MediaControlPanelMuteButtonElement* m_panelMuteButton;
     120    MediaControlVolumeSliderElement* m_volumeSlider;
     121    MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
     122    MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
     123    MediaControlFullscreenButtonElement* m_fullScreenButton;
     124    MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;
     125    MediaControlFullscreenVolumeSliderElement* m_fullScreenVolumeSlider;
     126    MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
     127    MediaControlPanelElement* m_panel;
    127128
    128     bool m_mouseOver;
     129    bool m_opaque;
    129130};
    130131
     132inline MediaControls* toMediaControls(Node* node)
     133{
     134    ASSERT(node->isHTMLElement());
     135    return static_cast<MediaControls*>(node);
     136}
    131137
    132138}
  • trunk/Source/WebCore/rendering/MediaControlElements.cpp

    r83256 r83397  
    6868static const float cSeekTime = 0.2f;
    6969
    70 inline MediaControlShadowRootElement::MediaControlShadowRootElement(HTMLMediaElement* mediaElement)
    71     : HTMLDivElement(divTag, mediaElement->document())
    72 {
    73     setShadowHost(mediaElement);
    74 }
    75 
    76 PassRefPtr<MediaControlShadowRootElement> MediaControlShadowRootElement::create(HTMLMediaElement* mediaElement)
    77 {
    78     RefPtr<MediaControlShadowRootElement> element = adoptRef(new MediaControlShadowRootElement(mediaElement));
    79 
    80     RefPtr<RenderStyle> rootStyle = RenderStyle::create();
    81     rootStyle->inheritFrom(mediaElement->renderer()->style());
    82     rootStyle->setDisplay(BLOCK);
    83     rootStyle->setPosition(RelativePosition);
    84 
    85     RenderMediaControlShadowRoot* renderer = new (mediaElement->renderer()->renderArena()) RenderMediaControlShadowRoot(element.get());
    86     renderer->setStyle(rootStyle.release());
    87 
    88     element->setRenderer(renderer);
    89     element->setAttached();
    90     element->setInDocument();
    91 
    92     return element.release();
    93 }
    94 
    95 void MediaControlShadowRootElement::detach()
    96 {
    97     HTMLDivElement::detach();
    98     // FIXME: Remove once shadow DOM uses Element::setShadowRoot().
    99     setShadowHost(0);
    100 }
    101 
    10270// ----------------------------
    10371
     
    10674    , m_mediaElement(mediaElement)
    10775{
    108     setInDocument();
    109 }
    110 
    111 void MediaControlElement::attachToParent(Element* parent)
    112 {
    113     // FIXME: This code seems very wrong.  Why are we magically adding |this| to the DOM here?
    114     //        We shouldn't be calling parser API methods outside of the parser!
    115     parent->parserAddChild(this);
    116 }
    117 
    118 void MediaControlElement::update()
    119 {
    120     if (renderer())
    121         renderer()->updateFromElement();
    122     updateStyle();
    123 }
    124 
    125 PassRefPtr<RenderStyle> MediaControlElement::styleForElement()
    126 {
    127     ASSERT(m_mediaElement->renderer());
    128     RefPtr<RenderStyle> style = document()->styleSelector()->styleForElement(this, m_mediaElement->renderer()->style(), true);
    129     if (!style)
    130         return 0;
    131    
    132     // text-decoration can't be overrided from CSS. So we do it here.
    133     // See https://bugs.webkit.org/show_bug.cgi?id=27015
    134     style->setTextDecoration(TDNONE);
    135     style->setTextDecorationsInEffect(TDNONE);
    136 
    137     return style;
    138 }
    139 
    140 bool MediaControlElement::rendererIsNeeded(RenderStyle* style)
    141 {
    142     ASSERT(document()->page());
    143 
    144     return HTMLDivElement::rendererIsNeeded(style) && parentNode() && parentNode()->renderer()
    145         && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), m_mediaElement));
    146 }
    147    
    148 void MediaControlElement::attach()
    149 {
    150     RefPtr<RenderStyle> style = styleForElement();
    151     if (!style)
    152         return;
    153     bool needsRenderer = rendererIsNeeded(style.get());
    154     if (!needsRenderer)
    155         return;
    156     RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style.get());
    157     if (!renderer)
    158         return;
    159     renderer->setStyle(style.get());
    160     setRenderer(renderer);
    161     if (parentNode() && parentNode()->renderer()) {
    162         // Find next sibling with a renderer to determine where to insert.
    163         Node* sibling = nextSibling();
    164         while (sibling && !sibling->renderer())
    165             sibling = sibling->nextSibling();
    166         parentNode()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
    167     }
    168     ContainerNode::attach();
    169 }
    170 
    171 void MediaControlElement::updateStyle()
    172 {
    173     if (!m_mediaElement || !m_mediaElement->renderer())
    174         return;
    175 
    176     RefPtr<RenderStyle> style = styleForElement();
    177     if (!style)
    178         return;
    179 
    180     bool needsRenderer = rendererIsNeeded(style.get()) && parentNode() && parentNode()->renderer();
    181     if (renderer() && !needsRenderer)
    182         detach();
    183     else if (!renderer() && needsRenderer)
    184         attach();
    185     else if (renderer()) {
    186         renderer()->setStyle(style.get());
    187 
    188         // Make sure that if there is any innerText renderer, it is updated as well.
    189         if (firstChild() && firstChild()->renderer())
    190             firstChild()->renderer()->setStyle(style.get());
    191     }
     76}
     77
     78static const String& displayString()
     79{
     80    DEFINE_STATIC_LOCAL(String, s, ("display"));
     81    return s;
     82}
     83
     84void MediaControlElement::show()
     85{
     86    ExceptionCode ec;
     87    // FIXME: Make more efficient <http://webkit.org/b/58157>
     88    style()->removeProperty(displayString(), ec);
     89}
     90
     91void MediaControlElement::hide()
     92{
     93    ExceptionCode ec;
     94    // FIXME: Make more efficient <http://webkit.org/b/58157>
     95    DEFINE_STATIC_LOCAL(String, none, ("none"));
     96    style()->setProperty(displayString(), none, ec);
    19297}
    19398
     
    224129PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(HTMLMediaElement* mediaElement)
    225130{
    226     return adoptRef(new MediaControlTimelineContainerElement(mediaElement));
    227 }
    228 
    229 bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style)
    230 {
    231     if (!MediaControlElement::rendererIsNeeded(style))
    232         return false;
    233 
    234     // Always show the timeline if the theme doesn't use status display (MediaControllerThemeClassic, for instance).
    235     if (!document()->page()->theme()->usesMediaControlStatusDisplay())
    236         return true;
    237 
    238     float duration = mediaElement()->duration();
    239     return !isnan(duration) && !isinf(duration);
     131    RefPtr<MediaControlTimelineContainerElement> element = adoptRef(new MediaControlTimelineContainerElement(mediaElement));
     132    element->hide();
     133    return element.release();
    240134}
    241135
     
    287181inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement)
    288182    : MediaControlElement(mediaElement)
    289     , m_isVisible(false)
    290183{
    291184}
     
    293186PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(HTMLMediaElement* mediaElement)
    294187{
    295     return adoptRef(new MediaControlVolumeSliderContainerElement(mediaElement));
     188    RefPtr<MediaControlVolumeSliderContainerElement> element = adoptRef(new MediaControlVolumeSliderContainerElement(mediaElement));
     189    element->hide();
     190    return element.release();
    296191}
    297192
     
    301196}
    302197
    303 PassRefPtr<RenderStyle> MediaControlVolumeSliderContainerElement::styleForElement()
    304 {
    305     RefPtr<RenderStyle> style = MediaControlElement::styleForElement();
    306     style->setPosition(AbsolutePosition);
    307     style->setDisplay(m_isVisible ? BLOCK : NONE);
    308     return style;
    309 }
    310 
    311 void MediaControlVolumeSliderContainerElement::setVisible(bool visible)
    312 {
    313     if (visible == m_isVisible)
    314         return;
    315     m_isVisible = visible;
    316 }
    317 
    318 bool MediaControlVolumeSliderContainerElement::hitTest(const IntPoint& absPoint)
    319 {
    320     if (renderer() && renderer()->style()->hasAppearance())
    321         return renderer()->theme()->hitTestMediaControlPart(renderer(), absPoint);
    322 
    323     return false;
    324 }
     198void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
     199{
     200    if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
     201        return;
     202
     203    // Poor man's mouseleave event detection.
     204    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
     205    if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
     206        return;
     207
     208    if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
     209        return;
     210
     211    hide();
     212}
     213
    325214
    326215MediaControlElementType MediaControlVolumeSliderContainerElement::displayType() const
     
    345234PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(HTMLMediaElement* mediaElement)
    346235{
    347     return adoptRef(new MediaControlStatusDisplayElement(mediaElement));
     236    RefPtr<MediaControlStatusDisplayElement> element = adoptRef(new MediaControlStatusDisplayElement(mediaElement));
     237    element->hide();
     238    return element.release();
    348239}
    349240
    350241void MediaControlStatusDisplayElement::update()
    351242{
    352     MediaControlElement::update();
    353 
    354243    // Get the new state that we'll have to display.
    355244    StateBeingDisplayed newStateToDisplay = Nothing;
     
    360249        newStateToDisplay = LiveBroadcast;
    361250
    362     // Propagate only if needed.
    363251    if (newStateToDisplay == m_stateBeingDisplayed)
    364252        return;
     253
     254    ExceptionCode e;
     255
     256    if (m_stateBeingDisplayed == Nothing)
     257        show();
     258    else if (newStateToDisplay == Nothing)
     259        hide();
     260
    365261    m_stateBeingDisplayed = newStateToDisplay;
    366262
    367     ExceptionCode e;
    368263    switch (m_stateBeingDisplayed) {
    369264    case Nothing:
     
    379274}
    380275
    381 bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style)
    382 {
    383     if (!MediaControlElement::rendererIsNeeded(style) || !document()->page()->theme()->usesMediaControlStatusDisplay())
    384         return false;
    385     float duration = mediaElement()->duration();
    386     return (isnan(duration) || isinf(duration));
    387 }
    388 
    389276MediaControlElementType MediaControlStatusDisplayElement::displayType() const
    390277{
     
    407294}
    408295
    409 void MediaControlInputElement::attachToParent(Element* parent)
    410 {
    411     // FIXME: This code seems very wrong.  Why are we magically adding |this| to the DOM here?
    412     //        We shouldn't be calling parser API methods outside of the parser!
    413     parent->parserAddChild(this);
    414 }
    415 
    416 void MediaControlInputElement::update()
    417 {
    418     updateDisplayType();
    419     if (renderer())
    420         renderer()->updateFromElement();
    421     updateStyle();
    422 }
    423 
    424 PassRefPtr<RenderStyle> MediaControlInputElement::styleForElement()
    425 {
    426     return document()->styleSelector()->styleForElement(this, 0, true);
    427 }
    428 
    429 bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style)
    430 {
    431     ASSERT(document()->page());
    432 
    433     return HTMLInputElement::rendererIsNeeded(style) && parentNode() && parentNode()->renderer()
    434         && (!style->hasAppearance() || document()->page()->theme()->shouldRenderMediaControlPart(style->appearance(), mediaElement()));
    435 }
    436 
    437 void MediaControlInputElement::attach()
    438 {
    439     RefPtr<RenderStyle> style = styleForElement();
    440     if (!style)
    441         return;
    442    
    443     bool needsRenderer = rendererIsNeeded(style.get());
    444     if (!needsRenderer)
    445         return;
    446     RenderObject* renderer = createRenderer(mediaElement()->renderer()->renderArena(), style.get());
    447     if (!renderer)
    448         return;
    449     renderer->setStyle(style.get());
    450     setRenderer(renderer);
    451     if (parentNode() && parentNode()->renderer()) {
    452         // Find next sibling with a renderer to determine where to insert.
    453         Node* sibling = nextSibling();
    454         while (sibling && !sibling->renderer())
    455             sibling = sibling->nextSibling();
    456         parentNode()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0);
    457     } 
    458     ContainerNode::attach();
    459     // FIXME: Currently, MediaControlInput circumvents the normal attachment
    460     // and style recalc cycle and thus we need to add extra logic to be aware of
    461     // the shadow DOM. Remove this once all media controls are transitioned to use the regular
    462     // style calculation.
    463     if (Node* shadowNode = shadowRoot())
    464         shadowNode->attach();
    465 }
    466 
    467 void MediaControlInputElement::updateStyle()
    468 {
    469     if (!mediaElement() || !mediaElement()->renderer())
    470         return;
    471    
    472     RefPtr<RenderStyle> style = styleForElement();
    473     if (!style)
    474         return;
    475    
    476     bool needsRenderer = rendererIsNeeded(style.get()) && parentNode() && parentNode()->renderer();
    477     if (renderer() && !needsRenderer)
    478         detach();
    479     else if (!renderer() && needsRenderer)
    480         attach();
    481     else if (renderer())
    482         renderer()->setStyle(style.get());
    483 
    484     // FIXME: Currently, MediaControlInput circumvents the normal attachment
    485     // and style recalc cycle and thus we need to add extra logic to be aware of
    486     // the shadow DOM. Remove this once all media controls are transitioned to use
    487     // the new shadow DOM.
    488     if (Node* shadowNode = shadowRoot())
    489         shadowNode->recalcStyle(Node::Force);
    490 }
    491 
    492 bool MediaControlInputElement::hitTest(const IntPoint& absPoint)
    493 {
    494     if (renderer() && renderer()->style()->hasAppearance())
    495         return renderer()->theme()->hitTestMediaControlPart(renderer(), absPoint);
    496 
    497     return false;
    498 }
     296void MediaControlInputElement::show()
     297{
     298    ExceptionCode ec;
     299    style()->removeProperty(displayString(), ec);
     300}
     301
     302void MediaControlInputElement::hide()
     303{
     304    ExceptionCode ec;
     305    DEFINE_STATIC_LOCAL(String, none, ("none"));
     306    style()->setProperty(displayString(), none, ec);
     307}
     308
    499309
    500310void MediaControlInputElement::setDisplayType(MediaControlElementType displayType)
     
    521331        event->setDefaultHandled();
    522332    }
     333
    523334    HTMLInputElement::defaultEventHandler(event);
    524335}
    525336
     337void MediaControlMuteButtonElement::changedMute()
     338{
     339    updateDisplayType();
     340}
     341
    526342void MediaControlMuteButtonElement::updateDisplayType()
    527343{
     
    531347// ----------------------------
    532348
    533 inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement)
     349inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
    534350    : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
    535 {
    536 }
    537 
    538 PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement)
    539 {
    540     RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement));
    541     button->setType("button");
    542     return button.release();
     351    , m_controls(controls)
     352{
     353}
     354
     355PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
     356{
     357    ASSERT(controls);
     358
     359    RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement, controls));
     360    button->setType("button");
     361    return button.release();
     362}
     363
     364void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
     365{
     366    if (event->type() == eventNames().mouseoverEvent)
     367        m_controls->showVolumeSlider();
     368
     369    MediaControlMuteButtonElement::defaultEventHandler(event);
    543370}
    544371
     
    552379
    553380inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
    554     : MediaControlMuteButtonElement(mediaElement, MediaVolumeSliderMuteButton)
     381    : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
    555382{
    556383}
     
    587414    if (event->type() == eventNames().clickEvent) {
    588415        mediaElement()->togglePlayState();
     416        updateDisplayType();
    589417        event->setDefaultHandled();
    590418    }
     
    740568    RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(mediaElement));
    741569    button->setType("button");
     570    button->hide();
    742571    return button.release();
    743572}
     
    769598    RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(mediaElement));
    770599    button->setType("button");
     600    button->hide();
    771601    return button.release();
    772602}
     
    777607        mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible());
    778608        setChecked(mediaElement()->closedCaptionsVisible());
     609        updateDisplayType();
    779610        event->setDefaultHandled();
    780611    }
     612
    781613    HTMLInputElement::defaultEventHandler(event);
    782614}
     
    795627// ----------------------------
    796628
    797 MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement)
     629MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement, MediaControls* controls)
    798630    : MediaControlInputElement(mediaElement, MediaSlider)
    799 {
    800 }
    801 
    802 PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement)
    803 {
    804     RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement));
     631    , m_controls(controls)
     632{
     633}
     634
     635PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
     636{
     637    ASSERT(controls);
     638
     639    RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement, controls));
    805640    timeline->setType("range");
    806641    timeline->setAttribute(precisionAttr, "float");
     
    827662    float time = narrowPrecisionToFloat(value().toDouble());
    828663    if (time != mediaElement()->currentTime()) {
     664        // FIXME: This is fired 3 times on every click. We should not be doing that <http:/webkit.org/b/58160>.
    829665        ExceptionCode ec;
    830666        mediaElement()->setCurrentTime(time, ec);
     
    833669    RenderSlider* slider = toRenderSlider(renderer());
    834670    if (slider && slider->inDragMode())
    835         toRenderMedia(mediaElement()->renderer())->controls()->updateTimeDisplay();
     671        m_controls->updateTimeDisplay();
    836672
    837673    if (event->type() == eventNames().mouseupEvent)
     
    839675}
    840676
    841 void MediaControlTimelineElement::update(bool updateDuration)
    842 {
    843     if (updateDuration) {
    844         float duration = mediaElement()->duration();
    845         setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0));
    846     }
    847     setValue(String::number(mediaElement()->currentTime()));
    848     MediaControlInputElement::update();
    849 }
     677void MediaControlTimelineElement::setPosition(float currentTime)
     678{
     679    setValue(String::number(currentTime));
     680}
     681
     682void MediaControlTimelineElement::setDuration(float duration)
     683{
     684    setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0));
     685}
     686
    850687
    851688const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
     
    894731}
    895732
    896 void MediaControlVolumeSliderElement::update()
    897 {
    898     float volume = mediaElement()->volume();
     733void MediaControlVolumeSliderElement::setVolume(float volume)
     734{
    899735    if (value().toFloat() != volume)
    900736        setValue(String::number(volume));
    901     MediaControlInputElement::update();
    902737}
    903738
     
    911746
    912747inline MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(HTMLMediaElement* mediaElement)
    913 : MediaControlVolumeSliderElement(mediaElement)
     748    : MediaControlVolumeSliderElement(mediaElement)
    914749{
    915750}
     
    933768// ----------------------------
    934769
    935 inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement)
     770inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
    936771    : MediaControlInputElement(mediaElement, MediaFullscreenButton)
    937 {
    938 }
    939 
    940 PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(HTMLMediaElement* mediaElement)
    941 {
    942     RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaElement));
    943     button->setType("button");
     772    , m_controls(controls)
     773{
     774}
     775
     776PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
     777{
     778    ASSERT(controls);
     779
     780    RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaElement, controls));
     781    button->setType("button");
     782    button->hide();
    944783    return button.release();
    945784}
     
    955794        // screen behavior.
    956795        if (document()->settings() && document()->settings()->fullScreenEnabled()) {
    957             if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement())
     796            if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement()) {
    958797                document()->webkitCancelFullScreen();
    959             else
     798                m_controls->exitedFullscreen();
     799            } else {
    960800                mediaElement()->webkitRequestFullScreen(0);
     801                m_controls->enteredFullscreen();
     802            }
    961803        } else
    962804#endif
     
    976818
    977819inline MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(HTMLMediaElement* mediaElement)
    978 : MediaControlInputElement(mediaElement, MediaUnMuteButton)
     820    : MediaControlInputElement(mediaElement, MediaUnMuteButton)
    979821{
    980822}
  • trunk/Source/WebCore/rendering/MediaControlElements.h

    r82053 r83397  
    4343class Event;
    4444class Frame;
     45class MediaControls;
    4546
    4647// Must match WebKitSystemInterface.h
     
    7273HTMLMediaElement* toParentMediaElement(RenderObject*);
    7374
    74 class MediaControlShadowRootElement : public HTMLDivElement {
    75 public:
    76     static PassRefPtr<MediaControlShadowRootElement> create(HTMLMediaElement*);
    77 
    78     virtual void detach();
    79    
    80 private:
    81     MediaControlShadowRootElement(HTMLMediaElement*);
    82 };
    83 
    8475// ----------------------------
    8576
    8677class MediaControlElement : public HTMLDivElement {
    8778public:
    88     virtual void attach();
    89     void attachToParent(Element*);
     79    void hide();
     80    void show();
     81
     82    virtual MediaControlElementType displayType() const = 0;
     83
     84    HTMLMediaElement* mediaElement() const { return m_mediaElement; }
     85
     86protected:
     87    MediaControlElement(HTMLMediaElement*);
     88
     89private:
     90    virtual bool isMediaControlElement() const { return true; }
     91
     92    HTMLMediaElement* m_mediaElement;   
     93};
     94
     95// ----------------------------
     96
     97class MediaControlPanelElement : public MediaControlElement {
     98public:
     99    static PassRefPtr<MediaControlPanelElement> create(HTMLMediaElement*);
     100
     101private:
     102    MediaControlPanelElement(HTMLMediaElement*);
     103    virtual MediaControlElementType displayType() const;
     104    virtual const AtomicString& shadowPseudoId() const;
     105};
     106
     107// ----------------------------
     108
     109class MediaControlTimelineContainerElement : public MediaControlElement {
     110public:
     111    static PassRefPtr<MediaControlTimelineContainerElement> create(HTMLMediaElement*);
     112
     113private:
     114    MediaControlTimelineContainerElement(HTMLMediaElement*);
     115    virtual const AtomicString& shadowPseudoId() const;
     116
     117    virtual MediaControlElementType displayType() const;
     118};
     119
     120// ----------------------------
     121
     122class MediaControlVolumeSliderContainerElement : public MediaControlElement {
     123public:
     124    static PassRefPtr<MediaControlVolumeSliderContainerElement> create(HTMLMediaElement*);
     125
     126private:
     127    MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
     128    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     129    virtual void defaultEventHandler(Event*);
     130    virtual MediaControlElementType displayType() const;
     131    virtual const AtomicString& shadowPseudoId() const;
     132};
     133
     134// ----------------------------
     135
     136class MediaControlStatusDisplayElement : public MediaControlElement {
     137public:
     138    static PassRefPtr<MediaControlStatusDisplayElement> create(HTMLMediaElement*);
     139
    90140    void update();
    91     void updateStyle();
    92 
    93     virtual MediaControlElementType displayType() const = 0;
    94 
    95     HTMLMediaElement* mediaElement() const { return m_mediaElement; }
    96 
    97 protected:
    98     MediaControlElement(HTMLMediaElement*);
    99 
    100     virtual bool rendererIsNeeded(RenderStyle*);
    101 
    102     virtual PassRefPtr<RenderStyle> styleForElement();
    103 
    104 private:
    105     virtual bool isMediaControlElement() const { return true; }
    106 
    107     HTMLMediaElement* m_mediaElement;   
    108 };
    109 
    110 // ----------------------------
    111 
    112 class MediaControlPanelElement : public MediaControlElement {
    113 public:
    114     static PassRefPtr<MediaControlPanelElement> create(HTMLMediaElement*);
    115 
    116 private:
    117     MediaControlPanelElement(HTMLMediaElement*);
    118     virtual MediaControlElementType displayType() const;
    119     virtual const AtomicString& shadowPseudoId() const;
    120 };
    121 
    122 
    123 // ----------------------------
    124 
    125 class MediaControlTimelineContainerElement : public MediaControlElement {
    126 public:
    127     static PassRefPtr<MediaControlTimelineContainerElement> create(HTMLMediaElement*);
    128 
    129 private:
    130     MediaControlTimelineContainerElement(HTMLMediaElement*);
    131     virtual MediaControlElementType displayType() const;
    132     virtual bool rendererIsNeeded(RenderStyle*);
    133     virtual const AtomicString& shadowPseudoId() const;
    134 };
    135 
    136 // ----------------------------
    137 
    138 class MediaControlVolumeSliderContainerElement : public MediaControlElement {
    139 public:
    140     static PassRefPtr<MediaControlVolumeSliderContainerElement> create(HTMLMediaElement*);
    141 
    142     virtual PassRefPtr<RenderStyle> styleForElement();
    143     void setVisible(bool);
    144     bool isVisible() { return m_isVisible; }
    145     bool hitTest(const IntPoint& absPoint);
    146 
    147 private:
    148     MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
    149 
    150     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    151     virtual MediaControlElementType displayType() const;
    152     virtual const AtomicString& shadowPseudoId() const;
    153 
    154     bool m_isVisible;
    155 };
    156 
    157 // ----------------------------
    158 
    159 class MediaControlStatusDisplayElement : public MediaControlElement {
    160 public:
    161     static PassRefPtr<MediaControlStatusDisplayElement> create(HTMLMediaElement*);
    162 
    163     void update();
    164141
    165142private:
     
    167144
    168145    virtual MediaControlElementType displayType() const;
    169     virtual bool rendererIsNeeded(RenderStyle*);
    170146    virtual const AtomicString& shadowPseudoId() const;
    171147
     
    178154class MediaControlInputElement : public HTMLInputElement {
    179155public:
    180     void attachToParent(Element*);
    181     void update();
    182     void updateStyle();
    183 
    184     bool hitTest(const IntPoint& absPoint);
     156    void hide();
     157    void show();
    185158
    186159    MediaControlElementType displayType() const { return m_displayType; }
     
    194167
    195168private:
    196     virtual void attach();
    197     virtual bool rendererIsNeeded(RenderStyle*);
    198 
    199     virtual PassRefPtr<RenderStyle> styleForElement();
    200 
    201169    virtual bool isMediaControlElement() const { return true; }
    202170
     
    211179class MediaControlMuteButtonElement : public MediaControlInputElement {
    212180public:
    213     virtual void defaultEventHandler(Event*);
     181    void changedMute();
    214182
    215183protected:
    216184    MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
     185    virtual void defaultEventHandler(Event*);
     186
    217187
    218188private:
     
    224194class MediaControlPanelMuteButtonElement : public MediaControlMuteButtonElement {
    225195public:
    226     static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*);
    227 
    228 private:
    229     MediaControlPanelMuteButtonElement(HTMLMediaElement*);
    230 
    231     virtual const AtomicString& shadowPseudoId() const;
     196    static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*, MediaControls*);
     197
     198private:
     199    MediaControlPanelMuteButtonElement(HTMLMediaElement*, MediaControls*);
     200
     201    virtual void defaultEventHandler(Event*);
     202    virtual const AtomicString& shadowPseudoId() const;
     203
     204    MediaControls* m_controls;
    232205};
    233206
     
    252225
    253226    virtual void defaultEventHandler(Event*);
     227    virtual void updateDisplayType();
    254228
    255229private:
    256230    MediaControlPlayButtonElement(HTMLMediaElement*);
    257231
    258     virtual void updateDisplayType();
    259232    virtual const AtomicString& shadowPseudoId() const;
    260233};
     
    341314
    342315    virtual void defaultEventHandler(Event*);
     316    virtual void updateDisplayType();
    343317
    344318private:
    345319    MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement*);
    346320
    347     virtual void updateDisplayType();
    348321    virtual const AtomicString& shadowPseudoId() const;
    349322};   
     
    353326class MediaControlTimelineElement : public MediaControlInputElement {
    354327public:
    355     static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*);
    356 
    357     virtual void defaultEventHandler(Event*);
    358     void update(bool updateDuration = true);
    359 
    360 private:
    361     MediaControlTimelineElement(HTMLMediaElement*);
    362 
    363     virtual const AtomicString& shadowPseudoId() const;
     328    static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*, MediaControls*);
     329
     330    virtual void defaultEventHandler(Event*);
     331    void setPosition(float);
     332    void setDuration(float);
     333
     334private:
     335    MediaControlTimelineElement(HTMLMediaElement*, MediaControls*);
     336
     337    virtual const AtomicString& shadowPseudoId() const;
     338
     339    MediaControls* m_controls;
    364340};
    365341
     
    371347
    372348    virtual void defaultEventHandler(Event*);
    373     void update();
     349    void setVolume(float);
    374350
    375351protected:
     
    384360class MediaControlFullscreenButtonElement : public MediaControlInputElement {
    385361public:
    386     static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*);
    387 
    388     virtual void defaultEventHandler(Event*);
    389 
    390 private:
    391     MediaControlFullscreenButtonElement(HTMLMediaElement*);
    392 
    393     virtual const AtomicString& shadowPseudoId() const;
     362    static PassRefPtr<MediaControlFullscreenButtonElement> create(HTMLMediaElement*, MediaControls*);
     363
     364    virtual void defaultEventHandler(Event*);
     365
     366private:
     367    MediaControlFullscreenButtonElement(HTMLMediaElement*, MediaControls*);
     368
     369    virtual const AtomicString& shadowPseudoId() const;
     370
     371    MediaControls* m_controls;
    394372};
    395373
     
    475453    virtual const AtomicString& shadowPseudoId() const;
    476454};
    477 
    478 // ----------------------------
    479 
    480 class RenderMediaControlShadowRoot : public RenderBlock {
    481 public:
    482     RenderMediaControlShadowRoot(Element* e) : RenderBlock(e) { }
    483     void setParent(RenderObject* p) { RenderObject::setParent(p); }
    484 };
    485    
     455 
    486456// ----------------------------
    487457
  • trunk/Source/WebCore/rendering/RenderMedia.cpp

    r80857 r83397  
    3030
    3131#include "HTMLMediaElement.h"
    32 #include "MediaControlElements.h"
    33 #include "MediaControls.h"
    3432#include "RenderView.h"
    3533
     
    3836RenderMedia::RenderMedia(HTMLMediaElement* video)
    3937    : RenderImage(video)
    40     , m_controls(new MediaControls(video))
    4138{
    4239    setImageResource(RenderImageResource::create());
     
    4542RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
    4643    : RenderImage(video)
    47     , m_controls(new MediaControls(video))
    4844{
    4945    setImageResource(RenderImageResource::create());
     
    5551}
    5652
    57 void RenderMedia::destroy()
    58 {
    59     m_controls->destroy();
    60     RenderImage::destroy();
    61 }
    62 
    6353HTMLMediaElement* RenderMedia::mediaElement() const
    6454{
    6555    return static_cast<HTMLMediaElement*>(node());
    66 }
    67 
    68 void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    69 {
    70     RenderImage::styleDidChange(diff, oldStyle);
    71     m_controls->updateStyle();
    7256}
    7357
     
    7862    RenderImage::layout();
    7963
    80     RenderBox* controlsRenderer = m_controls->renderBox();
     64    RenderBox* controlsRenderer = toRenderBox(m_children.firstChild());
    8165    if (!controlsRenderer)
    8266        return;
     67
    8368    IntSize newSize = contentBoxRect().size();
    8469    if (newSize == oldSize && !controlsRenderer->needsLayout())
     
    10085}
    10186
    102 void RenderMedia::updateFromElement()
    103 {
    104     m_controls->update();
    105 }
    106 
    10787} // namespace WebCore
    10888
  • trunk/Source/WebCore/rendering/RenderMedia.h

    r76950 r83397  
    3434
    3535class HTMLMediaElement;
    36 class MediaControls;
    3736
    3837class RenderMedia : public RenderImage {
     
    4645
    4746    HTMLMediaElement* mediaElement() const;
    48     MediaControls* controls() const;
    49 
    50     virtual void updateFromElement();
    5147
    5248protected:
     
    5753    virtual const RenderObjectChildList* virtualChildren() const { return children(); }
    5854
    59     virtual void destroy();
    60    
    6155    virtual const char* renderName() const { return "RenderMedia"; }
    6256    virtual bool isMedia() const { return true; }
    6357    virtual bool isImage() const { return false; }
    6458
    65 
    66     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    67 
    6859    virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
    6960
    70     OwnPtr<MediaControls> m_controls;
    7161    RenderObjectChildList m_children;
    7262};
     
    7868}
    7969
    80 inline MediaControls* RenderMedia::controls() const
    81 {
    82     return m_controls.get();
    83 }
    84 
    8570// This will catch anyone doing an unnecessary cast.
    8671void toRenderMedia(const RenderMedia*);
  • trunk/Source/WebCore/rendering/RenderMediaControlsChromium.cpp

    r75837 r83397  
    241241    }
    242242    return true;
    243 }
    244 
    245 bool RenderMediaControlsChromium::shouldRenderMediaControlPart(ControlPart part, Element* e)
    246 {
    247     UNUSED_PARAM(e);
    248 
    249     switch (part) {
    250     case MediaMuteButtonPart:
    251     case MediaPlayButtonPart:
    252     case MediaSliderPart:
    253     case MediaSliderThumbPart:
    254     case MediaVolumeSliderContainerPart:
    255     case MediaVolumeSliderPart:
    256     case MediaVolumeSliderThumbPart:
    257     case MediaControlsBackgroundPart:
    258     case MediaCurrentTimePart:
    259     case MediaTimeRemainingPart:
    260         return true;
    261     default:
    262         ;
    263     }
    264     return false;
    265243}
    266244
  • trunk/Source/WebCore/rendering/RenderMediaControlsChromium.h

    r62104 r83397  
    3737class RenderMediaControlsChromium {
    3838public:
    39     static bool shouldRenderMediaControlPart(ControlPart, Element*);
    4039    static bool paintMediaControlsPart(MediaControlElementType, RenderObject*, const PaintInfo&, const IntRect&);
    4140    static void adjustMediaSliderThumbSize(RenderObject*);
  • trunk/Source/WebCore/rendering/RenderTheme.cpp

    r82686 r83397  
    482482
    483483#if ENABLE(VIDEO)
    484 bool RenderTheme::hitTestMediaControlPart(RenderObject* o, const IntPoint& absPoint)
    485 {
    486     if (!o->isBox())
    487         return false;
    488 
    489     FloatPoint localPoint = o->absoluteToLocal(absPoint, false, true);  // respect transforms
    490     return toRenderBox(o)->borderBoxRect().contains(roundedIntPoint(localPoint));
    491 }
    492 
    493 bool RenderTheme::shouldRenderMediaControlPart(ControlPart part, Element* e)
    494 {
    495     HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(e);
    496     switch (part) {
    497     case MediaMuteButtonPart:
    498         return mediaElement->hasAudio();
    499     case MediaRewindButtonPart:
    500         return mediaElement->movieLoadType() != MediaPlayer::LiveStream;
    501     case MediaReturnToRealtimeButtonPart:
    502         return mediaElement->movieLoadType() == MediaPlayer::LiveStream;
    503     case MediaFullscreenButtonPart:
    504         return mediaElement->supportsFullscreen();
    505     case MediaToggleClosedCaptionsButtonPart:
    506         return mediaElement->hasClosedCaptions();
    507     default:
    508         return true;
    509     }
    510 }
    511484
    512485String RenderTheme::formatMediaControlsTime(float time) const
  • trunk/Source/WebCore/rendering/RenderTheme.h

    r82686 r83397  
    182182#if ENABLE(VIDEO)
    183183    // Media controls
    184     virtual bool hitTestMediaControlPart(RenderObject*, const IntPoint& absPoint);
    185     virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
     184    virtual bool supportsClosedCaptioning() const { return false; }
     185    virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return false; }
    186186    virtual bool usesMediaControlStatusDisplay() { return false; }
     187    virtual bool usesMediaControlVolumeSlider() const { return true; }
    187188    virtual double mediaControlsFadeInDuration() { return 0.1; }
    188189    virtual double mediaControlsFadeOutDuration() { return 0.3; }
  • trunk/Source/WebCore/rendering/RenderThemeChromiumMac.h

    r82863 r83397  
    3939    virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
    4040    virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
    41     virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
    4241    virtual String extraMediaControlsStyleSheet();
    4342#if ENABLE(FULLSCREEN_API)
     
    5150    virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
    5251    virtual bool usesMediaControlStatusDisplay() { return false; }
    53 
     52    virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
    5453#endif
    5554
  • trunk/Source/WebCore/rendering/RenderThemeChromiumMac.mm

    r82863 r83397  
    106106}
    107107
    108 bool RenderThemeChromiumMac::shouldRenderMediaControlPart(ControlPart part, Element* e)
    109 {
    110     return RenderMediaControlsChromium::shouldRenderMediaControlPart(part, e);
    111 }
    112 
    113108bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
    114109{
  • trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.cpp

    r82923 r83397  
    502502}
    503503
    504 #if ENABLE(VIDEO)
    505 bool RenderThemeChromiumSkia::shouldRenderMediaControlPart(ControlPart part, Element* e)
    506 {
    507     return RenderMediaControlsChromium::shouldRenderMediaControlPart(part, e);
    508 }
    509 #endif
    510 
    511504// static
    512505void RenderThemeChromiumSkia::setDefaultFontSize(int fontSize)
  • trunk/Source/WebCore/rendering/RenderThemeChromiumSkia.h

    r76379 r83397  
    124124#if ENABLE(VIDEO)
    125125        // Media controls
    126         virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
     126        virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
    127127#endif
    128128
  • trunk/Source/WebCore/rendering/RenderThemeMac.h

    r82686 r83397  
    167167#endif
    168168
    169     virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
     169    virtual bool supportsClosedCaptioning() const { return true; }
     170    virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const;
    170171    virtual bool usesMediaControlStatusDisplay();
     172    virtual bool usesMediaControlVolumeSlider() const;
    171173    virtual void adjustMediaSliderThumbSize(RenderObject*) const;
    172174    virtual IntPoint volumeSliderOffsetFromMuteButton(RenderBox*, const IntSize&) const;
  • trunk/Source/WebCore/rendering/RenderThemeMac.mm

    r82686 r83397  
    19731973#endif
    19741974
    1975 bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* element)
    1976 {
    1977     HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(element);
    1978     switch (part) {
    1979     case MediaVolumeSliderContainerPart:
    1980     case MediaVolumeSliderPart:
    1981     case MediaVolumeSliderMuteButtonPart:
    1982     case MediaVolumeSliderThumbPart: {
    1983         return mediaControllerTheme() == MediaControllerThemeQuickTime && mediaElement->hasAudio();
    1984     }
    1985     case MediaToggleClosedCaptionsButtonPart:
    1986         // We rely on QTKit to render captions so don't enable the button unless it will be able to do so.
    1987         if (!element->hasTagName(videoTag))
    1988             return false;
    1989         break;
    1990     case MediaRewindButtonPart:
    1991         if (mediaElement->isFullscreen())
    1992             return mediaElement->movieLoadType() == MediaPlayer::LiveStream
    1993                 || mediaElement->movieLoadType() == MediaPlayer::StoredStream;
    1994     case MediaSeekForwardButtonPart:
    1995     case MediaSeekBackButtonPart:
    1996         if (mediaElement->isFullscreen())
    1997             return mediaElement->movieLoadType() != MediaPlayer::StoredStream
    1998                 && mediaElement->movieLoadType() != MediaPlayer::LiveStream;
    1999     default:
    2000         break;
    2001     }
    2002 
    2003     return RenderTheme::shouldRenderMediaControlPart(part, element);
     1975bool RenderThemeMac::hasOwnDisabledStateHandlingFor(ControlPart part) const
     1976{
     1977    if (part == MediaMuteButtonPart)
     1978        return false;
     1979
     1980    return mediaControllerTheme() == MediaControllerThemeClassic;
    20041981}
    20051982
    20061983bool RenderThemeMac::usesMediaControlStatusDisplay()
     1984{
     1985    return mediaControllerTheme() == MediaControllerThemeQuickTime;
     1986}
     1987
     1988bool RenderThemeMac::usesMediaControlVolumeSlider() const
    20071989{
    20081990    return mediaControllerTheme() == MediaControllerThemeQuickTime;
  • trunk/Source/WebCore/rendering/RenderThemeWin.cpp

    r80688 r83397  
    10301030}
    10311031
    1032 bool RenderThemeWin::shouldRenderMediaControlPart(ControlPart part, Element* element)
    1033 {
    1034     if (part == MediaToggleClosedCaptionsButtonPart) {
     1032bool RenderThemeWin::supportsClosedCaptioning() const
     1033{
    10351034        // We rely on QuickTime to render captions so only enable the button for a video element.
    10361035#if SAFARI_THEME_VERSION >= 4
    1037         if (!element->hasTagName(videoTag))
    1038             return false;
     1036    return true;
    10391037#else
    1040         return false;
     1038    return false;
    10411039#endif
    1042     }
    1043 
    1044     return RenderTheme::shouldRenderMediaControlPart(part, element);
    1045 }
    1046 
     1040}
    10471041
    10481042bool RenderThemeWin::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
  • trunk/Source/WebCore/rendering/RenderThemeWin.h

    r80278 r83397  
    125125#if ENABLE(VIDEO)
    126126    virtual String extraMediaControlsStyleSheet();
    127     virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
     127    virtual bool supportsClosedCaptioning() const;
    128128    virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
    129129    virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
Note: See TracChangeset for help on using the changeset viewer.