Source/WebCore/ChangeLog

 12011-04-07 Dimitri Glazkov <dglazkov@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 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 set of hooks 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
 37 * css/mediaControls.css:
 38 (::-webkit-media-controls): Added new pseudo-element to describe media controls container.
 39 * html/HTMLMediaElement.cpp:
 40 (WebCore::HTMLMediaElement::HTMLMediaElement):
 41 (WebCore::HTMLMediaElement::attributeChanged):
 42 (WebCore::HTMLMediaElement::setNetworkState):
 43 (WebCore::HTMLMediaElement::setReadyState):
 44 (WebCore::HTMLMediaElement::playbackProgressTimerFired):
 45 (WebCore::HTMLMediaElement::defaultEventHandler):
 46 (WebCore::HTMLMediaElement::mediaControls):
 47 (WebCore::HTMLMediaElement::hasMediaControls):
 48 (WebCore::HTMLMediaElement::ensureMediaControls):
 49 * html/HTMLMediaElement.h:
 50 * html/shadow/MediaControls.cpp:
 51 (WebCore::MediaControls::MediaControls):
 52 (WebCore::MediaControls::create):
 53 (WebCore::MediaControls::show):
 54 (WebCore::MediaControls::hide):
 55 (WebCore::webkitTransitionString):
 56 (WebCore::opacityString):
 57 (WebCore::MediaControls::makeOpaque):
 58 (WebCore::MediaControls::makeTransparent):
 59 (WebCore::MediaControls::reset):
 60 (WebCore::MediaControls::playbackStarted):
 61 (WebCore::MediaControls::playbackProgressed):
 62 (WebCore::MediaControls::playbackStopped):
 63 (WebCore::MediaControls::updateTimeDisplay):
 64 (WebCore::MediaControls::reportedError):
 65 (WebCore::MediaControls::changedNetworkState):
 66 (WebCore::MediaControls::loadedMetadata):
 67 (WebCore::MediaControls::changedClosedCaptionsVisibility):
 68 (WebCore::MediaControls::changedMute):
 69 (WebCore::MediaControls::changedVolume):
 70 (WebCore::MediaControls::showVolumeSlider):
 71 (WebCore::MediaControls::shadowPseudoId):
 72 * html/shadow/MediaControls.h:
 73 (WebCore::toMediaControls):
 74 * rendering/MediaControlElements.cpp:
 75 (WebCore::MediaControlElement::MediaControlElement):
 76 (WebCore::displayString):
 77 (WebCore::MediaControlElement::show):
 78 (WebCore::MediaControlElement::hide):
 79 (WebCore::MediaControlTimelineContainerElement::create):
 80 (WebCore::MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement):
 81 (WebCore::MediaControlVolumeSliderContainerElement::create):
 82 (WebCore::MediaControlVolumeSliderContainerElement::defaultEventHandler):
 83 (WebCore::MediaControlStatusDisplayElement::create):
 84 (WebCore::MediaControlStatusDisplayElement::update):
 85 (WebCore::MediaControlInputElement::show):
 86 (WebCore::MediaControlInputElement::hide):
 87 (WebCore::MediaControlMuteButtonElement::defaultEventHandler):
 88 (WebCore::MediaControlMuteButtonElement::changedMute):
 89 (WebCore::MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement):
 90 (WebCore::MediaControlPanelMuteButtonElement::create):
 91 (WebCore::MediaControlPanelMuteButtonElement::defaultEventHandler):
 92 (WebCore::MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement):
 93 (WebCore::MediaControlPlayButtonElement::defaultEventHandler):
 94 (WebCore::MediaControlReturnToRealtimeButtonElement::create):
 95 (WebCore::MediaControlToggleClosedCaptionsButtonElement::create):
 96 (WebCore::MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler):
 97 (WebCore::MediaControlTimelineElement::MediaControlTimelineElement):
 98 (WebCore::MediaControlTimelineElement::create):
 99 (WebCore::MediaControlTimelineElement::defaultEventHandler):
 100 (WebCore::MediaControlTimelineElement::setPosition):
 101 (WebCore::MediaControlTimelineElement::setDuration):
 102 (WebCore::MediaControlVolumeSliderElement::MediaControlVolumeSliderElement):
 103 (WebCore::MediaControlVolumeSliderElement::setVolume):
 104 (WebCore::MediaControlFullscreenButtonElement::create):
 105 * rendering/MediaControlElements.h:
 106 * rendering/RenderMedia.cpp:
 107 (WebCore::RenderMedia::RenderMedia):
 108 (WebCore::RenderMedia::layout):
 109 (WebCore::RenderMedia::paint):
 110 * rendering/RenderMedia.h:
 111 * rendering/RenderMediaControlsChromium.cpp:
 112 * rendering/RenderMediaControlsChromium.h:
 113 * rendering/RenderTheme.cpp:
 114 * rendering/RenderTheme.h:
 115 (WebCore::RenderTheme::supportsClosedCaptioning):
 116 (WebCore::RenderTheme::hasOwnDisabledStateHandlingFor):
 117 (WebCore::RenderTheme::usesMediaControlVolumeSlider):
 118 * rendering/RenderThemeChromiumMac.h:
 119 (WebCore::RenderThemeChromiumMac::hasOwnDisabledStateHandlingFor):
 120 * rendering/RenderThemeChromiumMac.mm:
 121 * rendering/RenderThemeChromiumSkia.cpp:
 122 * rendering/RenderThemeChromiumSkia.h:
 123 (WebCore::RenderThemeChromiumSkia::hasOwnDisabledStateHandlingFor):
 124 * rendering/RenderThemeMac.h:
 125 (WebCore::RenderThemeMac::supportsClosedCaptioning):
 126 * rendering/RenderThemeMac.mm:
 127 (WebCore::RenderThemeMac::hasOwnDisabledStateHandlingFor):
 128 (WebCore::RenderThemeMac::usesMediaControlVolumeSlider):
 129 * rendering/RenderThemeWin.cpp:
 130 (WebCore::RenderThemeWin::supportsClosedCaptioning):
 131 * rendering/RenderThemeWin.h:
 132 (WebCore::RenderThemeWin::supportsClosedCaptioning):
 133
11342011-04-02 Dimitri Glazkov <dglazkov@chromium.org>
2135
3136 Reviewed by NOBODY (OOPS!).

Source/WebCore/css/mediaControls.css

@@audio {
2929 height: 16px;
3030}
3131
 32::-webkit-media-controls {
 33 width: inherit;
 34 height: inherit;
 35 position: relative;
 36 display: block;
 37}
 38
3239audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
3340 display: -webkit-box;
3441 -webkit-box-orient: horizontal;

@@audio::-webkit-media-controls-timeline, video::-webkit-media-controls-timeline {
98105 margin: initial;
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;
109111 color: inherit;

Source/WebCore/html/HTMLMediaElement.cpp

5454#include "MediaList.h"
5555#include "MediaPlayer.h"
5656#include "MediaQueryEvaluator.h"
 57#include "MouseEvent.h"
5758#include "MIMETypeRegistry.h"
5859#include "Page.h"
5960#include "RenderVideo.h"

@@HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
161162 , m_sendProgressEvents(true)
162163 , m_isFullscreen(false)
163164 , m_closedCaptionsVisible(false)
 165 , m_mouseOver(false)
164166#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
165167 , m_needWidgetUpdate(false)
166168#endif

@@void HTMLMediaElement::attributeChanged(Attribute* attr, bool preserveDecls)
218220 }
219221 else if (attrName == controlsAttr) {
220222#if !ENABLE(PLUGIN_PROXY_FOR_VIDEO)
221  if (!isVideo() && attached() && (controls() != (renderer() != 0))) {
222  detach();
223  attach();
224  }
225  if (hasMediaControls())
226  mediaControls()->reset();
 223 if (controls()) {
 224 if (!hasMediaControls()) {
 225 ensureMediaControls();
 226 mediaControls()->reset();
 227 }
 228 mediaControls()->show();
 229 } else if (hasMediaControls())
 230 mediaControls()->hide();
227231#else
228232 if (m_player)
229233 m_player->setControls(controls());

@@void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
889893 noneSupported();
890894
891895 updateDisplayState();
 896 if (hasMediaControls())
 897 mediaControls()->reportedError();
892898 return;
893899 }
894900

@@void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
918924 m_networkState = NETWORK_IDLE;
919925 m_completelyLoaded = true;
920926 }
 927
 928 if (hasMediaControls())
 929 mediaControls()->changedNetworkState();
921930}
922931
923932void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)

@@void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
967976 if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
968977 scheduleEvent(eventNames().durationchangeEvent);
969978 scheduleEvent(eventNames().loadedmetadataEvent);
 979 if (hasMediaControls())
 980 mediaControls()->loadedMetadata();
970981 if (renderer())
971982 renderer()->updateFromElement();
972983 m_player->seek(0);

@@void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
15941605 return;
15951606
15961607 scheduleTimeupdateEvent(true);
1597  if (hasMediaControls())
 1608 if (hasMediaControls()) {
 1609 if (!m_mouseOver && controls())
 1610 mediaControls()->makeTransparent();
15981611 mediaControls()->playbackProgressed();
1599 
 1612 }
16001613 // FIXME: deal with cue ranges here
16011614}
16021615

@@void HTMLMediaElement::defaultEventHandler(Event* event)
23122325 if (widget)
23132326 widget->handleEvent(event);
23142327#else
2315  if (hasMediaControls())
2316  mediaControls()->forwardEvent(event);
2317  if (event->defaultHandled())
2318  return;
 2328 if (event->isMouseEvent()) {
 2329 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
 2330 if (mouseEvent->relatedTarget() != this) {
 2331 if (event->type() == eventNames().mouseoverEvent) {
 2332 m_mouseOver = true;
 2333 if (hasMediaControls() && controls() && !canPlay())
 2334 mediaControls()->makeOpaque();
 2335 } else if (event->type() == eventNames().mouseoutEvent)
 2336 m_mouseOver = false;
 2337 }
 2338 }
 2339
23192340 HTMLElement::defaultEventHandler(event);
23202341#endif
23212342}

@@void HTMLMediaElement::privateBrowsingStateDidChange()
25952616
25962617MediaControls* HTMLMediaElement::mediaControls()
25972618{
2598  ASSERT(renderer());
2599  return toRenderMedia(renderer())->controls();
 2619 return toMediaControls(shadowRoot());
 2620}
 2621
 2622bool HTMLMediaElement::hasMediaControls()
 2623{
 2624 return shadowRoot();
26002625}
26012626
2602 bool HTMLMediaElement::hasMediaControls() const
 2627void HTMLMediaElement::ensureMediaControls()
26032628{
2604  return renderer() && renderer()->isMedia();
 2629 if (!hasMediaControls())
 2630 setShadowRoot(MediaControls::create(this));
26052631}
26062632
26072633}

Source/WebCore/html/HTMLMediaElement.h

@@private:
323323 void invalidateCachedTime();
324324 void refreshCachedTime() const;
325325
326  bool hasMediaControls() const;
 326 bool hasMediaControls();
 327 void ensureMediaControls();
327328
328329 Timer<HTMLMediaElement> m_loadTimer;
329330 Timer<HTMLMediaElement> m_asyncEventTimer;

@@private:
404405
405406 bool m_isFullscreen : 1;
406407 bool m_closedCaptionsVisible : 1;
 408 bool m_mouseOver : 1;
407409
408410#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
409411 bool m_needWidgetUpdate : 1;

Source/WebCore/html/shadow/MediaControls.cpp

@@namespace WebCore {
4747
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)
 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_toggleClosedCaptionsButton(0)
 62 , m_panelMuteButton(0)
 63 , m_volumeSlider(0)
 64 , m_volumeSliderMuteButton(0)
 65 , m_volumeSliderContainer(0)
 66 , m_fullScreenButton(0)
 67 , m_fullScreenMinVolumeButton(0)
 68 , m_fullScreenVolumeSlider(0)
 69 , m_fullScreenMaxVolumeButton(0)
 70 , m_panel(0)
 71 , m_opaque(true)
6072{
6173}
6274
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)
 75PassRefPtr<MediaControls> MediaControls::create(HTMLMediaElement* mediaElement)
6676{
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());
 77 if (!mediaElement->document()->page())
 78 return 0;
11979
120  m_seekForwardButton = MediaControlSeekForwardButtonElement::create(mediaElement);
121  m_seekForwardButton->attachToParent(m_panel.get());
 80 RefPtr<MediaControls> controls = adoptRef(new MediaControls(mediaElement));
12281
123  m_toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
124  m_toggleClosedCaptionsButton->attachToParent(m_panel.get());
 82 RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(mediaElement);
12583
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());
 84 // FIXME: WHAT TO DO WITH ec??!?!?!?!
 85 ExceptionCode ec;
13186
132  m_volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);
 87 RefPtr<MediaControlRewindButtonElement> rewindButton = MediaControlRewindButtonElement::create(mediaElement);
 88 controls->m_rewindButton = rewindButton.get();
 89 panel->appendChild(rewindButton.release(), ec, true);
 90 if (ec)
 91 return 0;
 92
 93 RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(mediaElement);
 94 controls->m_playButton = playButton.get();
 95 panel->appendChild(playButton.release(), ec, true);
 96 if (ec)
 97 return 0;
 98
 99 RefPtr<MediaControlReturnToRealtimeButtonElement> returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(mediaElement);
 100 controls->m_returnToRealTimeButton = returnToRealtimeButton.get();
 101 panel->appendChild(returnToRealtimeButton.release(), ec, true);
 102 if (ec)
 103 return 0;
 104
 105 if (mediaElement->document()->page()->theme()->usesMediaControlStatusDisplay()) {
 106 RefPtr<MediaControlStatusDisplayElement> statusDisplay = MediaControlStatusDisplayElement::create(mediaElement);
 107 controls->m_statusDisplay = statusDisplay.get();
 108 panel->appendChild(statusDisplay.release(), ec, true);
 109 if (ec)
 110 return 0;
 111 }
133112
134  m_volumeSlider = MediaControlVolumeSliderElement::create(mediaElement);
135  m_volumeSlider->attachToParent(m_volumeSliderContainer.get());
 113 RefPtr<MediaControlTimelineContainerElement> timelineContainer = MediaControlTimelineContainerElement::create(mediaElement);
 114
 115 RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(mediaElement);
 116 controls->m_currentTimeDisplay = currentTimeDisplay.get();
 117 timelineContainer->appendChild(currentTimeDisplay.release(), ec, true);
 118 if (ec)
 119 return 0;
 120
 121 RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(mediaElement, controls.get());
 122 controls->m_timeline = timeline.get();
 123 timelineContainer->appendChild(timeline.release(), ec, true);
 124 if (ec)
 125 return 0;
 126
 127 RefPtr<MediaControlTimeRemainingDisplayElement> timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(mediaElement);
 128 controls->m_timeRemainingDisplay = timeRemainingDisplay.get();
 129 timelineContainer->appendChild(timeRemainingDisplay.release(), ec, true);
 130 if (ec)
 131 return 0;
 132
 133 controls->m_timelineContainer = timelineContainer.get();
 134 panel->appendChild(timelineContainer.release(), ec, true);
 135 if (ec)
 136 return 0;
 137
 138 // FIXME: ONLY APPEND WHEN SUPPORTS SEEKBACK
 139 panel->appendChild(MediaControlSeekBackButtonElement::create(mediaElement), ec, true);
 140 if (ec)
 141 return 0;
 142
 143 // FIXME: ONLY APPEND WHEN SUPPORTS SEEKFORWARD
 144 panel->appendChild(MediaControlSeekForwardButtonElement::create(mediaElement), ec, true);
 145 if (ec)
 146 return 0;
 147
 148 if (mediaElement->document()->page()->theme()->supportsClosedCaptioning()) {
 149 RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(mediaElement);
 150 controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
 151 panel->appendChild(toggleClosedCaptionsButton.release(), ec, true);
 152 if (ec)
 153 return 0;
 154 }
136155
137  m_volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
138  m_volumeSliderMuteButton->attachToParent(m_volumeSliderContainer.get());
 156 RefPtr<MediaControlFullscreenButtonElement> fullScreenButton = MediaControlFullscreenButtonElement::create(mediaElement);
 157 controls->m_fullScreenButton = fullScreenButton.get();
 158 panel->appendChild(fullScreenButton.release(), ec, true);
 159
 160 RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(mediaElement, controls.get());
 161 controls->m_panelMuteButton = panelMuteButton.get();
 162 panel->appendChild(panelMuteButton.release(), ec, true);
 163 if (ec)
 164 return 0;
 165
 166 if (mediaElement->document()->page()->theme()->usesMediaControlVolumeSlider()) {
 167 RefPtr<MediaControlVolumeSliderContainerElement> volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(mediaElement);
 168
 169 RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(mediaElement);
 170 controls->m_volumeSlider = slider.get();
 171 volumeSliderContainer->appendChild(slider.release(), ec, true);
 172 if (ec)
 173 return 0;
 174
 175 RefPtr<MediaControlVolumeSliderMuteButtonElement> volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(mediaElement);
 176 controls->m_volumeSliderMuteButton = volumeSliderMuteButton.get();
 177 volumeSliderContainer->appendChild(volumeSliderMuteButton.release(), ec, true);
 178 if (ec)
 179 return 0;
 180
 181 controls->m_volumeSliderContainer = volumeSliderContainer.get();
 182 panel->appendChild(volumeSliderContainer.release(), ec, true);
 183 if (ec)
 184 return 0;
 185 }
139186
140  m_volumeSliderContainer->attachToParent(m_panel.get());
141 
142187 // FIXME: These controls, and others, should be created dynamically when needed, instead of
143188 // 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());
 189 RefPtr<MediaControlFullscreenVolumeMinButtonElement> fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(mediaElement);
 190 controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.get();
 191 panel->appendChild(fullScreenMinVolumeButton.release(), ec, true);
 192 if (ec)
 193 return 0;
 194
 195 RefPtr<MediaControlFullscreenVolumeSliderElement> fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(mediaElement);
 196 controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.get();
 197 panel->appendChild(fullScreenVolumeSlider.release(), ec, true);
 198 if (ec)
 199 return 0;
 200
 201 RefPtr<MediaControlFullscreenVolumeMaxButtonElement> fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(mediaElement);
 202 controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.get();
 203 panel->appendChild(fullScreenMaxVolumeButton.release(), ec, true);
 204 if (ec)
 205 return 0;
 206
 207 controls->m_panel = panel.get();
 208 controls->appendChild(panel.release(), ec, true);
 209 if (ec)
 210 return 0;
 211
154212 return controls.release();
155213}
156214
157 void MediaControls::reset()
 215void MediaControls::show()
158216{
159  update();
 217 m_panel->show();
160218}
161219
162 void MediaControls::playbackProgressed()
 220void MediaControls::hide()
163221{
164  if (m_timeline)
165  m_timeline->update(false);
166  updateTimeDisplay();
 222 m_panel->hide();
167223}
168224
169 void MediaControls::playbackStarted()
 225static const String& webkitTransitionString()
170226{
171  playbackProgressed();
 227 DEFINE_STATIC_LOCAL(String, s, ("-webkit-transition"));
 228 return s;
172229}
173230
174 void MediaControls::playbackStopped()
 231static const String& opacityString()
175232{
176  playbackProgressed();
 233 DEFINE_STATIC_LOCAL(String, s, ("opacity"));
 234 return s;
177235}
178236
179 void MediaControls::changedMute()
 237void MediaControls::makeOpaque()
180238{
181  update();
182 }
 239 if (m_opaque)
 240 return;
183241
184 void MediaControls::changedVolume()
185 {
186  update();
187 }
 242 DEFINE_STATIC_LOCAL(String, transitionValue, ());
 243 if (transitionValue.isNull())
 244 transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeInDuration());
 245 DEFINE_STATIC_LOCAL(String, opacityValue, ("1"));
188246
189 void MediaControls::changedClosedCaptionsVisibility()
190 {
191  update();
 247 ExceptionCode ec;
 248 m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
 249 m_panel->style()->setProperty(opacityString(), opacityValue, ec);
 250 m_opaque = true;
192251}
193252
194 void MediaControls::updateStyle()
 253void MediaControls::makeTransparent()
195254{
196  if (!m_controlsShadowRoot)
 255 if (!m_opaque)
197256 return;
198257
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();
227  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();
 258 DEFINE_STATIC_LOCAL(String, transitionValue, ());
 259 if (transitionValue.isNull())
 260 transitionValue = String::format("opacity %.1gs", document()->page()->theme()->mediaControlsFadeOutDuration());
 261 DEFINE_STATIC_LOCAL(String, opacityValue, ("0"));
 262
 263 ExceptionCode ec;
 264 // FIXME: Make more efficient.
 265 m_panel->style()->setProperty(webkitTransitionString(), transitionValue, ec);
 266 m_panel->style()->setProperty(opacityString(), opacityValue, ec);
 267 m_opaque = false;
239268}
240269
241 void MediaControls::destroy()
 270void MediaControls::reset()
242271{
243  ASSERT(m_mediaElement->renderer());
 272 Page* page = document()->page();
 273 if (!page)
 274 return;
244275
245  if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) {
 276 changedNetworkState();
 277 float duration = m_mediaElement->duration();
 278 if (!isnan(duration) || page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
 279 m_timeline->setDuration(duration);
 280 m_timelineContainer->show();
 281 m_timeline->setPosition(m_mediaElement->currentTime());
 282 updateTimeDisplay();
 283 } else
 284 m_timelineContainer->hide();
 285
 286 if (m_mediaElement->hasAudio() || page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
 287 m_panelMuteButton->show();
 288 else
 289 m_panelMuteButton->hide();
246290
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();
 291 if (m_volumeSlider)
 292 m_volumeSlider->setVolume(m_mediaElement->volume());
250293
251  m_mediaElement->renderer()->removeChild(m_controlsShadowRoot->renderer());
252  m_controlsShadowRoot->detach();
253  m_controlsShadowRoot = 0;
 294 if (m_toggleClosedCaptionsButton) {
 295 if (m_mediaElement->hasClosedCaptions())
 296 m_toggleClosedCaptionsButton->show();
 297 else
 298 m_toggleClosedCaptionsButton->hide();
254299 }
255 }
256300
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;
 301 if (m_mediaElement->movieLoadType() != MediaPlayer::LiveStream) {
 302 m_returnToRealTimeButton->hide();
 303 m_rewindButton->show();
 304 } else {
 305 m_returnToRealTimeButton->show();
 306 m_rewindButton->hide();
288307 }
289308
290  if (!m_controlsShadowRoot) {
291  m_controlsShadowRoot = create(m_mediaElement);
292  m_mediaElement->renderer()->addChild(m_controlsShadowRoot->renderer());
293  m_panel->attach();
294  }
 309 makeOpaque();
 310}
295311
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();
327  if (m_statusDisplay)
328  m_statusDisplay->update();
329  if (m_fullscreenButton)
330  m_fullscreenButton->update();
331  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();
 312void MediaControls::playbackStarted()
 313{
 314 m_playButton->updateDisplayType();
 315 m_timeline->setPosition(m_mediaElement->currentTime());
341316 updateTimeDisplay();
342  updateControlVisibility();
343317}
344318
345 void MediaControls::updateTimeDisplay()
 319void MediaControls::playbackProgressed()
346320{
347  ASSERT(m_mediaElement->renderer());
 321 m_timeline->setPosition(m_mediaElement->currentTime());
 322 updateTimeDisplay();
 323}
348324
349  if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || m_mediaElement->renderer()->style()->visibility() != VISIBLE)
350  return;
 325void MediaControls::playbackStopped()
 326{
 327 m_playButton->updateDisplayType();
 328 m_timeline->setPosition(m_mediaElement->currentTime());
 329 updateTimeDisplay();
 330 makeOpaque();
 331}
351332
 333void MediaControls::updateTimeDisplay()
 334{
352335 float now = m_mediaElement->currentTime();
353336 float duration = m_mediaElement->duration();
354337
355  // Allow the theme to format the time
 338 Page* page = document()->page();
 339 if (!page)
 340 return;
 341
 342 // Allow the theme to format the time.
356343 ExceptionCode ec;
357  m_currentTimeDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsCurrentTime(now, duration), ec);
 344 m_currentTimeDisplay->setInnerText(page->theme()->formatMediaControlsCurrentTime(now, duration), ec);
358345 m_currentTimeDisplay->setCurrentValue(now);
359  m_timeRemainingDisplay->setInnerText(m_mediaElement->renderer()->theme()->formatMediaControlsRemainingTime(now, duration), ec);
 346 m_timeRemainingDisplay->setInnerText(page->theme()->formatMediaControlsRemainingTime(now, duration), ec);
360347 m_timeRemainingDisplay->setCurrentValue(now - duration);
361348}
362349
363 RenderBox* MediaControls::renderBox()
 350void MediaControls::reportedError()
364351{
365  return m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0;
366 }
367 
368 void MediaControls::updateControlVisibility()
369 {
370  if (!m_panel || !m_panel->renderer())
 352 Page* page = document()->page();
 353 if (!page)
371354 return;
372355
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();
 356 if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaSliderPart))
 357 m_timelineContainer->hide();
385358
386  // Do fading manually, css animations don't work with shadow trees
 359 if (!page->theme()->hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
 360 m_panelMuteButton->hide();
387361
388  float animateFrom = m_panel->renderer()->style()->opacity();
389  float animateTo = shouldHideController ? 0.0f : 1.0f;
 362 if (m_volumeSliderContainer)
 363 m_volumeSliderContainer->hide();
 364 if (m_toggleClosedCaptionsButton && !page->theme()->hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
 365 m_toggleClosedCaptionsButton->hide();
 366}
390367
391  if (animateFrom == animateTo)
392  return;
 368void MediaControls::changedNetworkState()
 369{
 370 if (m_mediaElement->supportsFullscreen())
 371 m_fullScreenButton->show();
 372 else
 373 m_fullScreenButton->hide();
393374
394  if (m_opacityAnimationTimer.isActive()) {
395  if (m_opacityAnimationTo == animateTo)
396  return;
397  m_opacityAnimationTimer.stop();
398  }
 375 if (m_statusDisplay)
 376 m_statusDisplay->update();
 377}
399378
400  if (animateFrom < animateTo)
401  m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeInDuration();
402  else
403  m_opacityAnimationDuration = m_panel->renderer()->theme()->mediaControlsFadeOutDuration();
 379void MediaControls::loadedMetadata()
 380{
 381 if (m_statusDisplay)
 382 m_statusDisplay->hide();
404383
405  m_opacityAnimationFrom = animateFrom;
406  m_opacityAnimationTo = animateTo;
 384 reset();
 385}
407386
408  m_opacityAnimationStartTime = currentTime();
409  m_opacityAnimationTimer.startRepeating(cOpacityAnimationRepeatDelay);
 387void MediaControls::changedClosedCaptionsVisibility()
 388{
 389 if (m_toggleClosedCaptionsButton)
 390 m_toggleClosedCaptionsButton->updateDisplayType();
410391}
411392
412 void MediaControls::changeOpacity(HTMLElement* e, float opacity)
 393void MediaControls::changedMute()
413394{
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());
 395 m_panelMuteButton->changedMute();
 396 if (m_volumeSliderMuteButton)
 397 m_volumeSliderMuteButton->changedMute();
421398}
422399
423 void MediaControls::opacityAnimationTimerFired(Timer<MediaControls>*)
 400void MediaControls::changedVolume()
424401{
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);
 402 if (m_volumeSlider)
 403 m_volumeSlider->setVolume(m_mediaElement->volume());
432404}
433405
434 void MediaControls::updateVolumeSliderContainer(bool visible)
 406void MediaControls::showVolumeSlider()
435407{
436  if (!m_mediaElement->hasAudio() || !m_volumeSliderContainer || !m_volumeSlider)
 408 if (!m_mediaElement->hasAudio())
437409 return;
438410
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  }
 411 if (m_volumeSliderContainer)
 412 m_volumeSliderContainer->show();
451413}
452414
453 void MediaControls::forwardEvent(Event* event)
 415const AtomicString& MediaControls::shadowPseudoId() const
454416{
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  }
 417 DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
 418 return id;
520419}
521420
522421}

Source/WebCore/html/shadow/MediaControls.h

2929
3030#if ENABLE(VIDEO)
3131
 32#include "HTMLDivElement.h"
3233#include "Timer.h"
3334#include <wtf/RefPtr.h>
3435

@@class HTMLElement;
3839class HTMLInputElement;
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;
5153class MediaControlTimeDisplayElement;
5254class MediaControlStatusDisplayElement;
5355class MediaControlTimelineContainerElement;
 56class MediaControlMuteButtonElement;
 57class MediaControlVolumeSliderElement;
 58class MediaControlVolumeSliderMuteButtonElement;
5459class MediaControlVolumeSliderContainerElement;
55 class MediaControlElement;
5660class MediaControlFullscreenVolumeMinButtonElement;
5761class MediaControlFullscreenVolumeSliderElement;
5862class MediaControlFullscreenVolumeMaxButtonElement;
 63class MediaControlPanelElement;
5964class MediaPlayer;
6065
6166class RenderBox;
6267class RenderMedia;
6368
64 class MediaControls {
 69// FIXME: Rename to MediaControlRootElement.
 70class MediaControls : public HTMLDivElement {
6571public:
66  MediaControls(HTMLMediaElement*);
 72 static PassRefPtr<MediaControls> create(HTMLMediaElement*);
 73
 74 void show();
 75 void hide();
 76 void makeOpaque();
 77 void makeTransparent();
6778
6879 void reset();
6980

@@public:
7384
7485 void changedMute();
7586 void changedVolume();
 87
 88 void reportedError();
 89 void changedNetworkState();
 90 void loadedMetadata();
7691 void changedClosedCaptionsVisibility();
7792
78  void destroy();
79  void update();
80  void updateStyle();
81  void forwardEvent(Event*);
 93 void showVolumeSlider();
8294 void updateTimeDisplay();
8395
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();
87 
8896private:
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);
 97 MediaControls(HTMLMediaElement*);
9698
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;
 99 virtual const AtomicString& shadowPseudoId() const;
119100
120101 HTMLMediaElement* m_mediaElement;
121  Timer<MediaControls> m_opacityAnimationTimer;
122 
123  double m_opacityAnimationStartTime;
124  double m_opacityAnimationDuration;
125  float m_opacityAnimationFrom;
126  float m_opacityAnimationTo;
127102
128  bool m_mouseOver;
 103 MediaControlRewindButtonElement* m_rewindButton;
 104 MediaControlPlayButtonElement* m_playButton;
 105 MediaControlReturnToRealtimeButtonElement* m_returnToRealTimeButton;
 106 MediaControlStatusDisplayElement* m_statusDisplay;
 107 MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
 108 MediaControlTimelineElement* m_timeline;
 109 MediaControlTimeRemainingDisplayElement* m_timeRemainingDisplay;
 110 MediaControlTimelineContainerElement* m_timelineContainer;
 111 MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
 112 MediaControlPanelMuteButtonElement* m_panelMuteButton;
 113 MediaControlVolumeSliderElement* m_volumeSlider;
 114 MediaControlVolumeSliderMuteButtonElement* m_volumeSliderMuteButton;
 115 MediaControlVolumeSliderContainerElement* m_volumeSliderContainer;
 116 MediaControlFullscreenButtonElement* m_fullScreenButton;
 117 MediaControlFullscreenVolumeMinButtonElement* m_fullScreenMinVolumeButton;
 118 MediaControlFullscreenVolumeSliderElement* m_fullScreenVolumeSlider;
 119 MediaControlFullscreenVolumeMaxButtonElement* m_fullScreenMaxVolumeButton;
 120 MediaControlPanelElement* m_panel;
 121
 122 bool m_opaque;
129123};
130124
 125inline MediaControls* toMediaControls(Node* node)
 126{
 127 ASSERT(node->isHTMLElement());
 128 return static_cast<MediaControls*>(node);
 129}
131130
132131}
133132

Source/WebCore/rendering/MediaControlElements.cpp

@@static const float cSeekRepeatDelay = 0.1f;
6767static const float cStepTime = 0.07f;
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
10472MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement)
10573 : HTMLDivElement(divTag, mediaElement->document())
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);
11676}
11777
118 void MediaControlElement::update()
 78static const String& displayString()
11979{
120  if (renderer())
121  renderer()->updateFromElement();
122  updateStyle();
 80 DEFINE_STATIC_LOCAL(String, s, ("display"));
 81 return s;
12382}
12483
125 PassRefPtr<RenderStyle> MediaControlElement::styleForElement()
 84void MediaControlElement::show()
12685{
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();
 86 ExceptionCode ec;
 87 // FIXME: Make more efficient.
 88 style()->removeProperty(displayString(), ec);
16989}
17090
171 void MediaControlElement::updateStyle()
 91void MediaControlElement::hide()
17292{
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  }
 93 ExceptionCode ec;
 94 // FIXME: Make more efficient.
 95 DEFINE_STATIC_LOCAL(String, none, ("none"));
 96 style()->setProperty(displayString(), none, ec);
19297}
19398
19499// ----------------------------

@@inline MediaControlTimelineContainerElement::MediaControlTimelineContainerElemen
223128
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
242136MediaControlElementType MediaControlTimelineContainerElement::displayType() const

@@void RenderMediaVolumeSliderContainer::layout()
286180
287181inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement)
288182 : MediaControlElement(mediaElement)
289  , m_isVisible(false)
290183{
291184}
292185
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
298193RenderObject* MediaControlVolumeSliderContainerElement::createRenderer(RenderArena* arena, RenderStyle*)

@@RenderObject* MediaControlVolumeSliderContainerElement::createRenderer(RenderAre
300195 return new (arena) RenderMediaVolumeSliderContainer(this);
301196}
302197
303 PassRefPtr<RenderStyle> MediaControlVolumeSliderContainerElement::styleForElement()
 198void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
304199{
305  RefPtr<RenderStyle> style = MediaControlElement::styleForElement();
306  style->setPosition(AbsolutePosition);
307  style->setDisplay(m_isVisible ? BLOCK : NONE);
308  return style;
309 }
 200 if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
 201 return;
310202
311 void MediaControlVolumeSliderContainerElement::setVisible(bool visible)
312 {
313  if (visible == m_isVisible)
 203 // Poor man's mouseleave event detection.
 204 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
 205 if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
314206 return;
315  m_isVisible = visible;
316 }
317207
318 bool MediaControlVolumeSliderContainerElement::hitTest(const IntPoint& absPoint)
319 {
320  if (renderer() && renderer()->style()->hasAppearance())
321  return renderer()->theme()->hitTestMediaControlPart(renderer(), absPoint);
 208 if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
 209 return;
322210
323  return false;
 211 hide();
324212}
325213
 214
326215MediaControlElementType MediaControlVolumeSliderContainerElement::displayType() const
327216{
328217 return MediaVolumeSliderContainer;

@@inline MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(HTMLMe
344233
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;
356245

@@void MediaControlStatusDisplayElement::update()
359248 else if (mediaElement()->movieLoadType() == MediaPlayer::LiveStream)
360249 newStateToDisplay = LiveBroadcast;
361250
362  // Propagate only if needed.
363251 if (newStateToDisplay == m_stateBeingDisplayed)
364252 return;
365  m_stateBeingDisplayed = newStateToDisplay;
366253
367254 ExceptionCode e;
 255
 256 if (m_stateBeingDisplayed == Nothing)
 257 show();
 258 else if (newStateToDisplay == Nothing)
 259 hide();
 260
 261 m_stateBeingDisplayed = newStateToDisplay;
 262
368263 switch (m_stateBeingDisplayed) {
369264 case Nothing:
370265 setInnerText("", e);

@@void MediaControlStatusDisplayElement::update()
378273 }
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{
391278 return MediaStatusDisplay;

@@MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElemen
406293{
407294}
408295
409 void MediaControlInputElement::attachToParent(Element* parent)
 296void MediaControlInputElement::show()
410297{
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()));
 298 ExceptionCode ec;
 299 style()->removeProperty(displayString(), ec);
435300}
436301
437 void MediaControlInputElement::attach()
 302void MediaControlInputElement::hide()
438303{
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, MeidaControlInput 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, MeidaControlInput 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);
 304 ExceptionCode ec;
 305 style()->setProperty(displayString(), "none", ec);
490306}
491307
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 }
499308
500309void MediaControlInputElement::setDisplayType(MediaControlElementType displayType)
501310{

@@void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
520329 mediaElement()->setMuted(!mediaElement()->muted());
521330 event->setDefaultHandled();
522331 }
 332
523333 HTMLInputElement::defaultEventHandler(event);
524334}
525335
 336void MediaControlMuteButtonElement::changedMute()
 337{
 338 updateDisplayType();
 339}
 340
526341void MediaControlMuteButtonElement::updateDisplayType()
527342{
528343 setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);

@@void MediaControlMuteButtonElement::updateDisplayType()
530345
531346// ----------------------------
532347
533 inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement)
 348inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
534349 : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
 350 , m_controls(controls)
535351{
536352}
537353
538 PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement)
 354PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
539355{
540  RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement));
 356 ASSERT(controls);
 357
 358 RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement, controls));
541359 button->setType("button");
542360 return button.release();
543361}
544362
 363void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
 364{
 365 if (event->type() == eventNames().mouseoverEvent)
 366 m_controls->showVolumeSlider();
 367
 368 MediaControlMuteButtonElement::defaultEventHandler(event);
 369}
 370
545371const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
546372{
547373 DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));

@@const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
551377// ----------------------------
552378
553379inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
554  : MediaControlMuteButtonElement(mediaElement, MediaVolumeSliderMuteButton)
 380 : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
555381{
556382}
557383

@@void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
586412{
587413 if (event->type() == eventNames().clickEvent) {
588414 mediaElement()->togglePlayState();
 415 updateDisplayType();
589416 event->setDefaultHandled();
590417 }
591418 HTMLInputElement::defaultEventHandler(event);

@@PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealti
739566{
740567 RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(mediaElement));
741568 button->setType("button");
 569 button->hide();
742570 return button.release();
743571}
744572

@@PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClos
768596{
769597 RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(mediaElement));
770598 button->setType("button");
 599 button->hide();
771600 return button.release();
772601}
773602

@@void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e
776605 if (event->type() == eventNames().clickEvent) {
777606 mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible());
778607 setChecked(mediaElement()->closedCaptionsVisible());
 608 updateDisplayType();
779609 event->setDefaultHandled();
780610 }
 611
781612 HTMLInputElement::defaultEventHandler(event);
782613}
783614

@@const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoI
794625
795626// ----------------------------
796627
797 MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement)
 628MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement, MediaControls* controls)
798629 : MediaControlInputElement(mediaElement, MediaSlider)
 630 , m_controls(controls)
799631{
 632 setAttribute(precisionAttr, "float");
800633}
801634
802 PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement)
 635PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
803636{
804  RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement));
 637 ASSERT(controls);
 638
 639 RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement, controls));
805640 timeline->setType("range");
806641 timeline->setAttribute(precisionAttr, "float");
807642 return timeline.release();

@@void MediaControlTimelineElement::defaultEventHandler(Event* event)
826661
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.
829665 ExceptionCode ec;
830666 mediaElement()->setCurrentTime(time, ec);
831667 }
832668
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)
838674 mediaElement()->endScrubbing();
839675}
840676
841 void MediaControlTimelineElement::update(bool updateDuration)
 677void MediaControlTimelineElement::setPosition(float currentTime)
842678{
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();
 679 setValue(String::number(currentTime));
 680}
 681
 682void MediaControlTimelineElement::setDuration(float duration)
 683{
 684 setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0));
849685}
850686
 687
851688const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
852689{
853690 DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline"));

@@const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
859696inline MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(HTMLMediaElement* mediaElement)
860697 : MediaControlInputElement(mediaElement, MediaVolumeSlider)
861698{
 699 setAttribute(precisionAttr, "float");
 700 setAttribute(maxAttr, "1");
862701}
863702
864703PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(HTMLMediaElement* mediaElement)

@@void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
893732 }
894733}
895734
896 void MediaControlVolumeSliderElement::update()
 735void MediaControlVolumeSliderElement::setVolume(float volume)
897736{
898  float volume = mediaElement()->volume();
899737 if (value().toFloat() != volume)
900738 setValue(String::number(volume));
901  MediaControlInputElement::update();
902739}
903740
904741const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const

@@PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElem
941778{
942779 RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaElement));
943780 button->setType("button");
 781 button->hide();
944782 return button.release();
945783}
946784

Source/WebCore/rendering/MediaControlElements.h

@@namespace WebCore {
4242
4343class Event;
4444class Frame;
 45class MediaControls;
4546
4647// Must match WebKitSystemInterface.h
4748enum MediaControlElementType {

@@enum MediaControlElementType {
7172
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*);
90  void update();
91  void updateStyle();
 79 // FIXME: These should be part of some InlineStylableElement.
 80 void hide();
 81 void show();
9282
9383 virtual MediaControlElementType displayType() const = 0;
9484

@@public:
9787protected:
9888 MediaControlElement(HTMLMediaElement*);
9989
100  virtual bool rendererIsNeeded(RenderStyle*);
101 
102  virtual PassRefPtr<RenderStyle> styleForElement();
103 
10490private:
10591 virtual bool isMediaControlElement() const { return true; }
10692

@@private:
119105 virtual const AtomicString& shadowPseudoId() const;
120106};
121107
122 
123108// ----------------------------
124109
125110class MediaControlTimelineContainerElement : public MediaControlElement {

@@public:
128113
129114private:
130115 MediaControlTimelineContainerElement(HTMLMediaElement*);
131  virtual MediaControlElementType displayType() const;
132  virtual bool rendererIsNeeded(RenderStyle*);
133116 virtual const AtomicString& shadowPseudoId() const;
 117
 118 virtual MediaControlElementType displayType() const;
134119};
135120
136121// ----------------------------

@@class MediaControlVolumeSliderContainerElement : public MediaControlElement {
139124public:
140125 static PassRefPtr<MediaControlVolumeSliderContainerElement> create(HTMLMediaElement*);
141126
142  virtual PassRefPtr<RenderStyle> styleForElement();
143  void setVisible(bool);
144  bool isVisible() { return m_isVisible; }
145  bool hitTest(const IntPoint& absPoint);
146 
147127private:
148128 MediaControlVolumeSliderContainerElement(HTMLMediaElement*);
149 
150129 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
 130 virtual void defaultEventHandler(Event*);
151131 virtual MediaControlElementType displayType() const;
152132 virtual const AtomicString& shadowPseudoId() const;
153 
154  bool m_isVisible;
155133};
156134
157135// ----------------------------

@@private:
166144 MediaControlStatusDisplayElement(HTMLMediaElement*);
167145
168146 virtual MediaControlElementType displayType() const;
169  virtual bool rendererIsNeeded(RenderStyle*);
170147 virtual const AtomicString& shadowPseudoId() const;
171148
172149 enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast };

@@private:
177154
178155class MediaControlInputElement : public HTMLInputElement {
179156public:
180  void attachToParent(Element*);
181  void update();
182  void updateStyle();
183 
184  bool hitTest(const IntPoint& absPoint);
 157 // FIXME: These should be part of some InlineStylableElement.
 158 void hide();
 159 void show();
185160
186161 MediaControlElementType displayType() const { return m_displayType; }
187162

@@protected:
193168 void setDisplayType(MediaControlElementType);
194169
195170private:
196  virtual void attach();
197  virtual bool rendererIsNeeded(RenderStyle*);
198 
199  virtual PassRefPtr<RenderStyle> styleForElement();
200 
201171 virtual bool isMediaControlElement() const { return true; }
202172
203173 virtual void updateDisplayType() { }

@@private:
210180
211181class MediaControlMuteButtonElement : public MediaControlInputElement {
212182public:
213  virtual void defaultEventHandler(Event*);
 183 void changedMute();
214184
215185protected:
216186 MediaControlMuteButtonElement(HTMLMediaElement*, MediaControlElementType);
 187 virtual void defaultEventHandler(Event*);
 188
217189
218190private:
219191 virtual void updateDisplayType();

@@private:
223195
224196class MediaControlPanelMuteButtonElement : public MediaControlMuteButtonElement {
225197public:
226  static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*);
 198 static PassRefPtr<MediaControlPanelMuteButtonElement> create(HTMLMediaElement*, MediaControls*);
227199
228200private:
229  MediaControlPanelMuteButtonElement(HTMLMediaElement*);
 201 MediaControlPanelMuteButtonElement(HTMLMediaElement*, MediaControls*);
230202
 203 virtual void defaultEventHandler(Event*);
231204 virtual const AtomicString& shadowPseudoId() const;
 205
 206 MediaControls* m_controls;
232207};
233208
234209// ----------------------------

@@public:
251226 static PassRefPtr<MediaControlPlayButtonElement> create(HTMLMediaElement*);
252227
253228 virtual void defaultEventHandler(Event*);
 229 // FIXME: PERHAPS MAKE EXPLICIT PLAY/PAUSE CALLS.
 230 virtual void updateDisplayType();
254231
255232private:
256233 MediaControlPlayButtonElement(HTMLMediaElement*);
257234
258  virtual void updateDisplayType();
259235 virtual const AtomicString& shadowPseudoId() const;
260236};
261237

@@public:
340316 static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(HTMLMediaElement*);
341317
342318 virtual void defaultEventHandler(Event*);
 319 virtual void updateDisplayType();
343320
344321private:
345322 MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement*);
346323
347  virtual void updateDisplayType();
348324 virtual const AtomicString& shadowPseudoId() const;
349325};
350326

@@private:
352328
353329class MediaControlTimelineElement : public MediaControlInputElement {
354330public:
355  static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*);
 331 static PassRefPtr<MediaControlTimelineElement> create(HTMLMediaElement*, MediaControls*);
356332
357333 virtual void defaultEventHandler(Event*);
358  void update(bool updateDuration = true);
 334 void setPosition(float);
 335 void setDuration(float);
359336
360337private:
361  MediaControlTimelineElement(HTMLMediaElement*);
 338 MediaControlTimelineElement(HTMLMediaElement*, MediaControls*);
362339
363340 virtual const AtomicString& shadowPseudoId() const;
 341
 342 MediaControls* m_controls;
364343};
365344
366345// ----------------------------

@@public:
370349 static PassRefPtr<MediaControlVolumeSliderElement> create(HTMLMediaElement*);
371350
372351 virtual void defaultEventHandler(Event*);
373  void update();
 352 void setVolume(float);
374353
375354protected:
376355 MediaControlVolumeSliderElement(HTMLMediaElement*);

@@private:
474453 virtual MediaControlElementType displayType() const;
475454 virtual const AtomicString& shadowPseudoId() const;
476455};
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 
 456
486457// ----------------------------
487458
488459} //namespace WebCore

Source/WebCore/rendering/RenderMedia.cpp

2929#include "RenderMedia.h"
3030
3131#include "HTMLMediaElement.h"
32 #include "MediaControlElements.h"
33 #include "MediaControls.h"
3432#include "RenderView.h"
3533
3634namespace WebCore {
3735
3836RenderMedia::RenderMedia(HTMLMediaElement* video)
3937 : RenderImage(video)
40  , m_controls(new MediaControls(video))
4138{
4239 setImageResource(RenderImageResource::create());
4340}
4441
4542RenderMedia::RenderMedia(HTMLMediaElement* video, const IntSize& intrinsicSize)
4643 : RenderImage(video)
47  , m_controls(new MediaControls(video))
4844{
4945 setImageResource(RenderImageResource::create());
5046 setIntrinsicSize(intrinsicSize);

@@RenderMedia::~RenderMedia()
5450{
5551}
5652
57 void RenderMedia::destroy()
58 {
59  m_controls->destroy();
60  RenderImage::destroy();
61 }
62 
 53// FIXME: Move to RenderVideo
6354HTMLMediaElement* RenderMedia::mediaElement() const
6455{
6556 return static_cast<HTMLMediaElement*>(node());
6657}
6758
68 void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
69 {
70  RenderImage::styleDidChange(diff, oldStyle);
71  m_controls->updateStyle();
72 }
73 
7459void RenderMedia::layout()
7560{
7661 IntSize oldSize = contentBoxRect().size();
7762
7863 RenderImage::layout();
7964
80  RenderBox* controlsRenderer = m_controls->renderBox();
 65 RenderBox* controlsRenderer = toRenderBox(m_children.firstChild());
8166 if (!controlsRenderer)
8267 return;
 68
8369 IntSize newSize = contentBoxRect().size();
8470 if (newSize == oldSize && !controlsRenderer->needsLayout())
8571 return;

@@void RenderMedia::layout()
9985 statePusher.pop();
10086}
10187
102 void RenderMedia::updateFromElement()
 88void RenderMedia::paint(PaintInfo& paintInfo, int tx, int ty)
10389{
104  m_controls->update();
 90 RenderImage::paint(paintInfo, tx, ty);
10591}
10692
10793} // namespace WebCore

Source/WebCore/rendering/RenderMedia.h

3333namespace WebCore {
3434
3535class HTMLMediaElement;
36 class MediaControls;
3736
3837class RenderMedia : public RenderImage {
3938public:

@@public:
4544 RenderObjectChildList* children() { return &m_children; }
4645
4746 HTMLMediaElement* mediaElement() const;
48  MediaControls* controls() const;
49 
50  virtual void updateFromElement();
5147
5248protected:
5349 virtual void layout();
5450
5551private:
 52 virtual void paint(PaintInfo&, int tx, int ty);
5653 virtual RenderObjectChildList* virtualChildren() { return children(); }
5754 virtual const RenderObjectChildList* virtualChildren() const { return children(); }
5855
59  virtual void destroy();
60 
6156 virtual const char* renderName() const { return "RenderMedia"; }
6257 virtual bool isMedia() const { return true; }
6358 virtual bool isImage() const { return false; }
6459
65 
66  virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
67 
6860 virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
6961
70  OwnPtr<MediaControls> m_controls;
7162 RenderObjectChildList m_children;
7263};
7364

@@inline RenderMedia* toRenderMedia(RenderObject* object)
7768 return static_cast<RenderMedia*>(object);
7869}
7970
80 inline MediaControls* RenderMedia::controls() const
81 {
82  return m_controls.get();
83 }
84 
8571// This will catch anyone doing an unnecessary cast.
8672void toRenderMedia(const RenderMedia*);
8773

Source/WebCore/rendering/RenderMediaControlsChromium.cpp

@@static bool paintMediaTimelineContainer(RenderObject* object, const PaintInfo& p
242242 return true;
243243}
244244
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;
265 }
266 
267245bool RenderMediaControlsChromium::paintMediaControlsPart(MediaControlElementType part, RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
268246{
269247 switch (part) {

Source/WebCore/rendering/RenderMediaControlsChromium.h

@@namespace WebCore {
3636class HTMLMediaElement;
3737class RenderMediaControlsChromium {
3838public:
39  static bool shouldRenderMediaControlPart(ControlPart, Element*);
4039 static bool paintMediaControlsPart(MediaControlElementType, RenderObject*, const PaintInfo&, const IntRect&);
4140 static void adjustMediaSliderThumbSize(RenderObject*);
4241};

Source/WebCore/rendering/RenderTheme.cpp

@@bool RenderTheme::paintDecorations(RenderObject* o, const PaintInfo& paintInfo,
481481}
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
513486{

Source/WebCore/rendering/RenderTheme.h

@@public:
181181
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; }
189190 virtual String formatMediaControlsTime(float time) const;

Source/WebCore/rendering/RenderThemeChromiumMac.h

@@protected:
3838 virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
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)
4443 virtual String extraFullScreenStyleSheet();

@@protected:
5049 virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
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
5655 virtual bool usesTestModeFocusRingColor() const;

Source/WebCore/rendering/RenderThemeChromiumMac.mm

@@void RenderThemeChromiumMac::adjustMediaSliderThumbSize(RenderObject* o) const
105105 RenderMediaControlsChromium::adjustMediaSliderThumbSize(o);
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{
115110 return RenderMediaControlsChromium::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);

Source/WebCore/rendering/RenderThemeChromiumSkia.cpp

@@int RenderThemeChromiumSkia::popupInternalPaddingBottom(RenderStyle* style) cons
501501 return menuListInternalPadding(style, BottomPadding);
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)
513506{

Source/WebCore/rendering/RenderThemeChromiumSkia.h

@@class RenderThemeChromiumSkia : public RenderTheme {
123123
124124#if ENABLE(VIDEO)
125125 // Media controls
126  virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
 126 virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
127127#endif
128128
129129 // Provide a way to pass the default font size from the Settings object

Source/WebCore/rendering/RenderThemeMac.h

@@protected:
166166 virtual String extraFullScreenStyleSheet();
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;
173175#endif

Source/WebCore/rendering/RenderThemeMac.mm

@@String RenderThemeMac::extraFullScreenStyleSheet()
19721972}
19731973#endif
19741974
1975 bool RenderThemeMac::shouldRenderMediaControlPart(ControlPart part, Element* element)
 1975bool RenderThemeMac::hasOwnDisabledStateHandlingFor(ControlPart part) const
19761976{
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  }
 1977 if (part == MediaMuteButtonPart)
 1978 return false;
20021979
2003  return RenderTheme::shouldRenderMediaControlPart(part, element);
 1980 return mediaControllerTheme() == MediaControllerThemeClassic;
20041981}
20051982
20061983bool RenderThemeMac::usesMediaControlStatusDisplay()

@@bool RenderThemeMac::usesMediaControlStatusDisplay()
20081985 return mediaControllerTheme() == MediaControllerThemeQuickTime;
20091986}
20101987
 1988bool RenderThemeMac::usesMediaControlVolumeSlider() const
 1989{
 1990 return mediaControllerTheme() == MediaControllerThemeQuickTime;
 1991}
 1992
20111993IntPoint RenderThemeMac::volumeSliderOffsetFromMuteButton(RenderBox* muteButtonBox, const IntSize& size) const
20121994{
20131995 return RenderMediaControls::volumeSliderOffsetFromMuteButton(muteButtonBox, size);

Source/WebCore/rendering/RenderThemeWin.cpp

@@String RenderThemeWin::extraMediaControlsStyleSheet()
10291029 return String(mediaControlsQuickTimeUserAgentStyleSheet, sizeof(mediaControlsQuickTimeUserAgentStyleSheet));
10301030}
10311031
1032 bool RenderThemeWin::shouldRenderMediaControlPart(ControlPart part, Element* element)
 1032bool RenderThemeWin::supportsClosedCaptioning() const
10331033{
1034  if (part == MediaToggleClosedCaptionsButtonPart) {
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);
10451040}
10461041
1047 
10481042bool RenderThemeWin::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
10491043{
10501044 return RenderMediaControls::paintMediaControlsPart(MediaFullscreenButton, o, paintInfo, r);

Source/WebCore/rendering/RenderThemeWin.h

@@public:
124124
125125#if ENABLE(VIDEO)
126126 virtual String extraMediaControlsStyleSheet();
127  virtual bool shouldRenderMediaControlPart(ControlPart, Element*);
 127 virtual bool supportsClosedCaptioning() const { return false; }
128128 virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&);
129129 virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
130130 virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);