diff options
Diffstat (limited to 'Source/WebCore/html/shadow/MediaControlElements.cpp')
-rw-r--r-- | Source/WebCore/html/shadow/MediaControlElements.cpp | 768 |
1 files changed, 356 insertions, 412 deletions
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp index 91df2d97b..87da17e58 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.cpp +++ b/Source/WebCore/html/shadow/MediaControlElements.cpp @@ -11,7 +11,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * 3. Neither the name of Apple Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -28,21 +28,26 @@ */ #include "config.h" +#include "MediaControlElements.h" #if ENABLE(VIDEO) -#include "MediaControlElements.h" #include "DOMTokenList.h" +#include "ElementChildIterator.h" #include "EventHandler.h" #include "EventNames.h" -#include "ExceptionCodePlaceholder.h" #include "Frame.h" #include "GraphicsContext.h" +#include "HTMLHeadingElement.h" +#include "HTMLLIElement.h" +#include "HTMLUListElement.h" #include "HTMLVideoElement.h" #include "ImageBuffer.h" #include "Language.h" #include "LocalizedStrings.h" +#include "Logging.h" #include "MediaControls.h" +#include "Page.h" #include "PageGroup.h" #include "RenderLayer.h" #include "RenderMediaControlElements.h" @@ -51,13 +56,8 @@ #include "RenderView.h" #include "Settings.h" #include "ShadowRoot.h" -#if ENABLE(VIDEO_TRACK) #include "TextTrackList.h" -#endif - -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) -#include "RenderWidget.h" -#endif +#include "VTTRegionList.h" namespace WebCore { @@ -72,19 +72,14 @@ MediaControlPanelElement::MediaControlPanelElement(Document& document) , m_isBeingDragged(false) , m_isDisplayed(false) , m_opaque(true) - , m_transitionTimer(this, &MediaControlPanelElement::transitionTimerFired) + , m_transitionTimer(*this, &MediaControlPanelElement::transitionTimerFired) { + setPseudo(AtomicString("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(Document& document) +Ref<MediaControlPanelElement> MediaControlPanelElement::create(Document& document) { - return adoptRef(new MediaControlPanelElement(document)); -} - -const AtomicString& MediaControlPanelElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral)); - return id; + return adoptRef(*new MediaControlPanelElement(document)); } void MediaControlPanelElement::startDrag(const LayoutPoint& eventLocation) @@ -152,7 +147,7 @@ void MediaControlPanelElement::stopTimer() m_transitionTimer.stop(); } -void MediaControlPanelElement::transitionTimerFired(Timer<MediaControlPanelElement>&) +void MediaControlPanelElement::transitionTimerFired() { if (!m_opaque) hide(); @@ -172,7 +167,7 @@ void MediaControlPanelElement::setPosition(const LayoutPoint& position) setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX); setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX); - classList()->add("dragged", IGNORE_EXCEPTION); + classList().add("dragged"); } void MediaControlPanelElement::resetPosition() @@ -182,7 +177,7 @@ void MediaControlPanelElement::resetPosition() removeInlineStyleProperty(CSSPropertyMarginLeft); removeInlineStyleProperty(CSSPropertyMarginTop); - classList()->remove("dragged", IGNORE_EXCEPTION); + classList().remove("dragged"); m_cumulativeDragOffset.setX(0); m_cumulativeDragOffset.setY(0); @@ -195,8 +190,8 @@ void MediaControlPanelElement::makeOpaque() double duration = document().page() ? document().page()->theme().mediaControlsFadeInDuration() : 0; - setInlineStyleProperty(CSSPropertyWebkitTransitionProperty, CSSPropertyOpacity); - setInlineStyleProperty(CSSPropertyWebkitTransitionDuration, duration, CSSPrimitiveValue::CSS_S); + setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity); + setInlineStyleProperty(CSSPropertyTransitionDuration, duration, CSSPrimitiveValue::CSS_S); setInlineStyleProperty(CSSPropertyOpacity, 1.0, CSSPrimitiveValue::CSS_NUMBER); m_opaque = true; @@ -212,29 +207,29 @@ void MediaControlPanelElement::makeTransparent() double duration = document().page() ? document().page()->theme().mediaControlsFadeOutDuration() : 0; - setInlineStyleProperty(CSSPropertyWebkitTransitionProperty, CSSPropertyOpacity); - setInlineStyleProperty(CSSPropertyWebkitTransitionDuration, duration, CSSPrimitiveValue::CSS_S); + setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity); + setInlineStyleProperty(CSSPropertyTransitionDuration, duration, CSSPrimitiveValue::CSS_S); setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER); m_opaque = false; startTimer(); } -void MediaControlPanelElement::defaultEventHandler(Event* event) +void MediaControlPanelElement::defaultEventHandler(Event& event) { MediaControlDivElement::defaultEventHandler(event); - if (event->isMouseEvent()) { - LayoutPoint location = static_cast<MouseEvent*>(event)->absoluteLocation(); - if (event->type() == eventNames().mousedownEvent && event->target() == this) { + if (is<MouseEvent>(event)) { + LayoutPoint location = downcast<MouseEvent>(event).absoluteLocation(); + if (event.type() == eventNames().mousedownEvent && event.target() == this) { startDrag(location); - event->setDefaultHandled(); - } else if (event->type() == eventNames().mousemoveEvent && m_isBeingDragged) + event.setDefaultHandled(); + } else if (event.type() == eventNames().mousemoveEvent && m_isBeingDragged) continueDrag(location); - else if (event->type() == eventNames().mouseupEvent && m_isBeingDragged) { + else if (event.type() == eventNames().mouseupEvent && m_isBeingDragged) { continueDrag(location); endDrag(); - event->setDefaultHandled(); + event.setDefaultHandled(); } } } @@ -261,17 +256,12 @@ MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& d // Mapping onto same MediaControlElementType as panel element, since it has similar properties. : MediaControlDivElement(document, MediaControlsPanel) { + setPseudo(AtomicString("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document) -{ - return adoptRef(new MediaControlPanelEnclosureElement(document)); -} - -const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const +Ref<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document) { - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral)); - return id; + return adoptRef(*new MediaControlPanelEnclosureElement(document)); } // ---------------------------- @@ -280,17 +270,12 @@ MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Documen // Mapping onto same MediaControlElementType as panel element, since it has similar properties. : MediaControlDivElement(document, MediaControlsPanel) { + setPseudo(AtomicString("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document) +Ref<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document) { - return adoptRef(new MediaControlOverlayEnclosureElement(document)); -} - -const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral)); - return id; + return adoptRef(*new MediaControlOverlayEnclosureElement(document)); } // ---------------------------- @@ -298,43 +283,34 @@ const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document& document) : MediaControlDivElement(document, MediaTimelineContainer) { + setPseudo(AtomicString("-webkit-media-controls-timeline-container", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(Document& document) +Ref<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(Document& document) { - RefPtr<MediaControlTimelineContainerElement> element = adoptRef(new MediaControlTimelineContainerElement(document)); + Ref<MediaControlTimelineContainerElement> element = adoptRef(*new MediaControlTimelineContainerElement(document)); element->hide(); - return element.release(); -} - -const AtomicString& MediaControlTimelineContainerElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline-container", AtomicString::ConstructFromLiteral)); - return id; + return element; } void MediaControlTimelineContainerElement::setTimeDisplaysHidden(bool hidden) { - for (unsigned i = 0; i < childNodeCount(); ++i) { - Node* child = childNode(i); - if (!child || !child->isElementNode()) - continue; - Element* element = toElement(child); - if (element->shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId() - && element->shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId()) + for (auto& element : childrenOfType<Element>(*this)) { + if (element.shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId() + && element.shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId()) continue; - MediaControlTimeDisplayElement* timeDisplay = static_cast<MediaControlTimeDisplayElement*>(element); + MediaControlTimeDisplayElement& timeDisplay = static_cast<MediaControlTimeDisplayElement&>(element); if (hidden) - timeDisplay->hide(); + timeDisplay.hide(); else - timeDisplay->show(); + timeDisplay.show(); } } -RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderMediaControlTimelineContainer>(*this, std::move(style)); + return createRenderer<RenderMediaControlTimelineContainer>(*this, WTFMove(style)); } // ---------------------------- @@ -342,28 +318,29 @@ RenderPtr<RenderElement> MediaControlTimelineContainerElement::createElementRend MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document& document) : MediaControlDivElement(document, MediaVolumeSliderContainer) { + setPseudo(AtomicString("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(Document& document) +Ref<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(Document& document) { - RefPtr<MediaControlVolumeSliderContainerElement> element = adoptRef(new MediaControlVolumeSliderContainerElement(document)); + Ref<MediaControlVolumeSliderContainerElement> element = adoptRef(*new MediaControlVolumeSliderContainerElement(document)); element->hide(); - return element.release(); + return element; } -RenderPtr<RenderElement> MediaControlVolumeSliderContainerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> MediaControlVolumeSliderContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderMediaVolumeSliderContainer>(*this, std::move(style)); + return createRenderer<RenderMediaVolumeSliderContainer>(*this, WTFMove(style)); } -void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event) +void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event& event) { - if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent) + if (!is<MouseEvent>(event) || event.type() != eventNames().mouseoutEvent) return; // Poor man's mouseleave event detection. - MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); - EventTarget* relatedTarget = mouseEvent->relatedTarget(); + MouseEvent& mouseEvent = downcast<MouseEvent>(event); + EventTarget* relatedTarget = mouseEvent.relatedTarget(); if (!relatedTarget || !relatedTarget->toNode()) return; @@ -373,25 +350,20 @@ void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event) hide(); } -const AtomicString& MediaControlVolumeSliderContainerElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document& document) : MediaControlDivElement(document, MediaStatusDisplay) , m_stateBeingDisplayed(Nothing) { + setPseudo(AtomicString("-webkit-media-controls-status-display", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(Document& document) +Ref<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(Document& document) { - RefPtr<MediaControlStatusDisplayElement> element = adoptRef(new MediaControlStatusDisplayElement(document)); + Ref<MediaControlStatusDisplayElement> element = adoptRef(*new MediaControlStatusDisplayElement(document)); element->hide(); - return element.release(); + return element; } void MediaControlStatusDisplayElement::update() @@ -416,75 +388,58 @@ void MediaControlStatusDisplayElement::update() switch (m_stateBeingDisplayed) { case Nothing: - setInnerText("", IGNORE_EXCEPTION); + setInnerText(emptyString()); break; case Loading: - setInnerText(mediaElementLoadingStateText(), IGNORE_EXCEPTION); + setInnerText(mediaElementLoadingStateText()); break; case LiveBroadcast: - setInnerText(mediaElementLiveBroadcastStateText(), IGNORE_EXCEPTION); + setInnerText(mediaElementLiveBroadcastStateText()); break; } } -const AtomicString& MediaControlStatusDisplayElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-status-display", AtomicString::ConstructFromLiteral)); - return id; -} - - // ---------------------------- MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls) : MediaControlMuteButtonElement(document, MediaMuteButton) , m_controls(controls) { + setPseudo(AtomicString("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls) +Ref<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls)); + Ref<MediaControlPanelMuteButtonElement> button = adoptRef(*new MediaControlPanelMuteButtonElement(document, controls)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event) +void MediaControlPanelMuteButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().mouseoverEvent) + if (event.type() == eventNames().mouseoverEvent) m_controls->showVolumeSlider(); MediaControlMuteButtonElement::defaultEventHandler(event); } -const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(Document& document) : MediaControlMuteButtonElement(document, MediaMuteButton) { + setPseudo(AtomicString("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document) +Ref<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document) { - RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document)); + Ref<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(*new MediaControlVolumeSliderMuteButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); -} - -const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral)); - return id; + return button; } // ---------------------------- @@ -492,25 +447,26 @@ const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document) : MediaControlInputElement(document, MediaPlayButton) { + setPseudo(AtomicString("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document) +Ref<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document) { - RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document)); + Ref<MediaControlPlayButtonElement> button = adoptRef(*new MediaControlPlayButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlPlayButtonElement::defaultEventHandler(Event* event) +void MediaControlPlayButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { if (mediaController()->canPlay()) mediaController()->play(); else mediaController()->pause(); updateDisplayType(); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } @@ -520,33 +476,28 @@ void MediaControlPlayButtonElement::updateDisplayType() setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton); } -const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document) : MediaControlInputElement(document, MediaOverlayPlayButton) { + setPseudo(AtomicString("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document) +Ref<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document) { - RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document)); + Ref<MediaControlOverlayPlayButtonElement> button = adoptRef(*new MediaControlOverlayPlayButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event* event) +void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent && mediaController()->canPlay()) { + if (event.type() == eventNames().clickEvent && mediaController()->canPlay()) { mediaController()->play(); updateDisplayType(); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } @@ -559,32 +510,20 @@ void MediaControlOverlayPlayButtonElement::updateDisplayType() hide(); } -const AtomicString& MediaControlOverlayPlayButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral)); - return id; -} - - // ---------------------------- MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(Document& document) : MediaControlSeekButtonElement(document, MediaSeekForwardButton) { + setPseudo(AtomicString("-webkit-media-controls-seek-forward-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document& document) +Ref<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document& document) { - RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(document)); + Ref<MediaControlSeekForwardButtonElement> button = adoptRef(*new MediaControlSeekForwardButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); -} - -const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-forward-button", AtomicString::ConstructFromLiteral)); - return id; + return button; } // ---------------------------- @@ -592,20 +531,15 @@ const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(Document& document) : MediaControlSeekButtonElement(document, MediaSeekBackButton) { + setPseudo(AtomicString("-webkit-media-controls-seek-back-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document& document) +Ref<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document& document) { - RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(document)); + Ref<MediaControlSeekBackButtonElement> button = adoptRef(*new MediaControlSeekBackButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); -} - -const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-back-button", AtomicString::ConstructFromLiteral)); - return id; + return button; } // ---------------------------- @@ -613,84 +547,75 @@ const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document& document) : MediaControlInputElement(document, MediaRewindButton) { + setPseudo(AtomicString("-webkit-media-controls-rewind-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document& document) +Ref<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document& document) { - RefPtr<MediaControlRewindButtonElement> button = adoptRef(new MediaControlRewindButtonElement(document)); + Ref<MediaControlRewindButtonElement> button = adoptRef(*new MediaControlRewindButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlRewindButtonElement::defaultEventHandler(Event* event) +void MediaControlRewindButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { mediaController()->setCurrentTime(std::max<double>(0, mediaController()->currentTime() - 30)); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-rewind-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document& document) : MediaControlInputElement(document, MediaReturnToRealtimeButton) { + setPseudo(AtomicString("-webkit-media-controls-return-to-realtime-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document& document) +Ref<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document& document) { - RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(document)); + Ref<MediaControlReturnToRealtimeButtonElement> button = adoptRef(*new MediaControlReturnToRealtimeButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); button->hide(); - return button.release(); + return button; } -void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event) +void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { mediaController()->returnToRealtime(); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-return-to-realtime-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls* controls) : MediaControlInputElement(document, MediaShowClosedCaptionsButton) -#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) +#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK) , m_controls(controls) #endif { -#if !PLATFORM(MAC) && !PLATFORM(WIN) || !PLATFORM(GTK) +#if !PLATFORM(COCOA) && !PLATFORM(WIN) || !PLATFORM(GTK) UNUSED_PARAM(controls); #endif + setPseudo(AtomicString("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls) +Ref<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls)); + Ref<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(*new MediaControlToggleClosedCaptionsButtonElement(document, controls)); button->ensureUserAgentShadowRoot(); button->setType("button"); button->hide(); - return button.release(); + return button; } void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() @@ -700,51 +625,40 @@ void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType() setChecked(captionsVisible); } -void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event) +void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { // FIXME: It's not great that the shared code is dictating behavior of platform-specific // UI. Not all ports may want the closed captions button to toggle a list of tracks, so // we have to use #if. // https://bugs.webkit.org/show_bug.cgi?id=101877 -#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(GTK) +#if !PLATFORM(COCOA) && !PLATFORM(WIN) && !PLATFORM(GTK) mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible()); setChecked(mediaController()->closedCaptionsVisible()); updateDisplayType(); #else m_controls->toggleClosedCaptionTrackList(); #endif - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement(Document& document) : MediaControlDivElement(document, MediaClosedCaptionsContainer) { + setPseudo(AtomicString("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document& document) +Ref<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document& document) { - RefPtr<MediaControlClosedCaptionsContainerElement> element = adoptRef(new MediaControlClosedCaptionsContainerElement(document)); - element->setAttribute(dirAttr, "auto"); + Ref<MediaControlClosedCaptionsContainerElement> element = adoptRef(*new MediaControlClosedCaptionsContainerElement(document)); + element->setAttributeWithoutSynchronization(dirAttr, AtomicString("auto", AtomicString::ConstructFromLiteral)); element->hide(); - return element.release(); -} - -const AtomicString& MediaControlClosedCaptionsContainerElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral)); - return id; + return element; } // ---------------------------- @@ -758,21 +672,22 @@ MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListE #if !ENABLE(VIDEO_TRACK) UNUSED_PARAM(controls); #endif + setPseudo(AtomicString("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls) +Ref<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr<MediaControlClosedCaptionsTrackListElement> element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document, controls)); - return element.release(); + Ref<MediaControlClosedCaptionsTrackListElement> element = adoptRef(*new MediaControlClosedCaptionsTrackListElement(document, controls)); + return element; } -void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* event) +void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event& event) { #if ENABLE(VIDEO_TRACK) - if (event->type() == eventNames().clickEvent) { - Node* target = event->target()->toNode(); - if (!target || !target->isElementNode()) + if (event.type() == eventNames().clickEvent) { + Node* target = event.target()->toNode(); + if (!is<Element>(target)) return; // When we created the elements in the track list, we gave them a custom @@ -781,7 +696,7 @@ void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even // tell the HTMLMediaElement to enable that track. RefPtr<TextTrack> textTrack; - MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(toElement(target)); + MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(downcast<Element>(target)); if (iter != m_menuToTrackMap.end()) textTrack = iter->value; m_menuToTrackMap.clear(); @@ -804,30 +719,23 @@ void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event* even #endif } -const AtomicString& MediaControlClosedCaptionsTrackListElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral)); - return id; -} - void MediaControlClosedCaptionsTrackListElement::updateDisplay() { #if ENABLE(VIDEO_TRACK) - DEFINE_STATIC_LOCAL(AtomicString, selectedClassValue, ("selected", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> selectedClassValue("selected", AtomicString::ConstructFromLiteral); if (!mediaController()->hasClosedCaptions()) return; if (!document().page()) return; - CaptionUserPreferences::CaptionDisplayMode displayMode = document().page()->group().captionPreferences()->captionDisplayMode(); + CaptionUserPreferences::CaptionDisplayMode displayMode = document().page()->group().captionPreferences().captionDisplayMode(); HTMLMediaElement* mediaElement = parentMediaElement(this); if (!mediaElement) return; - TextTrackList* trackList = mediaElement->textTracks(); - if (!trackList || !trackList->length()) + if (!mediaElement->textTracks().length()) return; rebuildTrackListMenu(); @@ -835,9 +743,7 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() RefPtr<Element> offMenuItem; bool trackMenuItemSelected = false; - for (unsigned i = 0, length = m_menuItems.size(); i < length; ++i) { - RefPtr<Element> trackItem = m_menuItems[i]; - + for (auto& trackItem : m_menuItems) { RefPtr<TextTrack> textTrack; MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(trackItem.get()); if (iter == m_menuToTrackMap.end()) @@ -853,24 +759,24 @@ void MediaControlClosedCaptionsTrackListElement::updateDisplay() if (textTrack == TextTrack::captionMenuAutomaticItem()) { if (displayMode == CaptionUserPreferences::Automatic) - trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION); + trackItem->classList().add(selectedClassValue); else - trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION); + trackItem->classList().remove(selectedClassValue); continue; } - if (displayMode != CaptionUserPreferences::Automatic && textTrack->mode() == TextTrack::showingKeyword()) { + if (displayMode != CaptionUserPreferences::Automatic && textTrack->mode() == TextTrack::Mode::Showing) { trackMenuItemSelected = true; - trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION); + trackItem->classList().add(selectedClassValue); } else - trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION); + trackItem->classList().remove(selectedClassValue); } if (offMenuItem) { if (displayMode == CaptionUserPreferences::ForcedOnly && !trackMenuItemSelected) - offMenuItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION); + offMenuItem->classList().add(selectedClassValue); else - offMenuItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION); + offMenuItem->classList().remove(selectedClassValue); } #endif } @@ -890,27 +796,26 @@ void MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu() if (!mediaElement) return; - TextTrackList* trackList = mediaElement->textTracks(); - if (!trackList || !trackList->length()) + TextTrackList& trackList = mediaElement->textTracks(); + if (!trackList.length()) return; if (!document().page()) return; - CaptionUserPreferences* captionPreferences = document().page()->group().captionPreferences(); - Vector<RefPtr<TextTrack>> tracksForMenu = captionPreferences->sortedTrackListForMenu(trackList); + auto& captionPreferences = document().page()->group().captionPreferences(); + Vector<RefPtr<TextTrack>> tracksForMenu = captionPreferences.sortedTrackListForMenu(&trackList); - RefPtr<Element> captionsHeader = document().createElement(h3Tag, ASSERT_NO_EXCEPTION); + auto captionsHeader = HTMLHeadingElement::create(h3Tag, document()); captionsHeader->appendChild(document().createTextNode(textTrackSubtitlesText())); appendChild(captionsHeader); - RefPtr<Element> captionsMenuList = document().createElement(ulTag, ASSERT_NO_EXCEPTION); + auto captionsMenuList = HTMLUListElement::create(document()); - for (unsigned i = 0, length = tracksForMenu.size(); i < length; ++i) { - RefPtr<TextTrack> textTrack = tracksForMenu[i]; - RefPtr<Element> menuItem = document().createElement(liTag, ASSERT_NO_EXCEPTION); - menuItem->appendChild(document().createTextNode(captionPreferences->displayNameForTrack(textTrack.get()))); + for (auto& textTrack : tracksForMenu) { + auto menuItem = HTMLLIElement::create(document()); + menuItem->appendChild(document().createTextNode(captionPreferences.displayNameForTrack(textTrack.get()))); captionsMenuList->appendChild(menuItem); - m_menuItems.append(menuItem); - m_menuToTrackMap.add(menuItem, textTrack); + m_menuItems.append(menuItem.ptr()); + m_menuToTrackMap.add(menuItem.ptr(), textTrack); } appendChild(captionsMenuList); @@ -923,45 +828,46 @@ MediaControlTimelineElement::MediaControlTimelineElement(Document& document, Med : MediaControlInputElement(document, MediaSlider) , m_controls(controls) { + setPseudo(AtomicString("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls) +Ref<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls)); + Ref<MediaControlTimelineElement> timeline = adoptRef(*new MediaControlTimelineElement(document, controls)); timeline->ensureUserAgentShadowRoot(); timeline->setType("range"); - timeline->setAttribute(precisionAttr, "float"); - return timeline.release(); + timeline->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral)); + return timeline; } -void MediaControlTimelineElement::defaultEventHandler(Event* event) +void MediaControlTimelineElement::defaultEventHandler(Event& event) { // Left button is 0. Rejects mouse events not from left button. - if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button()) + if (is<MouseEvent>(event) && downcast<MouseEvent>(event).button()) return; if (!renderer()) return; - if (event->type() == eventNames().mousedownEvent) + if (event.type() == eventNames().mousedownEvent) mediaController()->beginScrubbing(); - if (event->type() == eventNames().mouseupEvent) + if (event.type() == eventNames().mouseupEvent) mediaController()->endScrubbing(); MediaControlInputElement::defaultEventHandler(event); - if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent) + if (event.type() == eventNames().mouseoverEvent || event.type() == eventNames().mouseoutEvent || event.type() == eventNames().mousemoveEvent) return; double time = value().toDouble(); - if (event->type() == eventNames().inputEvent && time != mediaController()->currentTime()) + if ((event.isInputEvent() || event.type() == eventNames().inputEvent) && time != mediaController()->currentTime()) mediaController()->setCurrentTime(time); - RenderSlider* slider = toRenderSlider(renderer()); - if (slider && slider->inDragMode()) + RenderSlider& slider = downcast<RenderSlider>(*renderer()); + if (slider.inDragMode()) m_controls->updateCurrentTimeDisplay(); } @@ -985,34 +891,22 @@ void MediaControlTimelineElement::setDuration(double duration) setAttribute(maxAttr, AtomicString::number(std::isfinite(duration) ? duration : 0)); } - -const AtomicString& MediaControlTimelineElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document) : MediaControlVolumeSliderElement(document) { + setPseudo(AtomicString("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document) +Ref<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document) { - RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document)); + Ref<MediaControlPanelVolumeSliderElement> slider = adoptRef(*new MediaControlPanelVolumeSliderElement(document)); slider->ensureUserAgentShadowRoot(); slider->setType("range"); - slider->setAttribute(precisionAttr, "float"); - slider->setAttribute(maxAttr, "1"); - return slider.release(); -} - -const AtomicString& MediaControlPanelVolumeSliderElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral)); - return id; + slider->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral)); + slider->setAttributeWithoutSynchronization(maxAttr, AtomicString("1", AtomicString::ConstructFromLiteral)); + return slider; } // ---------------------------- @@ -1020,22 +914,17 @@ const AtomicString& MediaControlPanelVolumeSliderElement::shadowPseudoId() const MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(Document& document) : MediaControlVolumeSliderElement(document) { + setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-slider", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document& document) +Ref<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document& document) { - RefPtr<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(document)); + Ref<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(*new MediaControlFullscreenVolumeSliderElement(document)); slider->ensureUserAgentShadowRoot(); slider->setType("range"); - slider->setAttribute(precisionAttr, "float"); - slider->setAttribute(maxAttr, "1"); - return slider.release(); -} - -const AtomicString& MediaControlFullscreenVolumeSliderElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-slider", AtomicString::ConstructFromLiteral)); - return id; + slider->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral)); + slider->setAttributeWithoutSynchronization(maxAttr, AtomicString("1", AtomicString::ConstructFromLiteral)); + return slider; } // ---------------------------- @@ -1043,45 +932,40 @@ const AtomicString& MediaControlFullscreenVolumeSliderElement::shadowPseudoId() MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document) : MediaControlInputElement(document, MediaEnterFullscreenButton) { + setPseudo(AtomicString("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document) +Ref<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document) { - RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document)); + Ref<MediaControlFullscreenButtonElement> button = adoptRef(*new MediaControlFullscreenButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); button->hide(); - return button.release(); + return button; } -void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) +void MediaControlFullscreenButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { #if ENABLE(FULLSCREEN_API) // Only use the new full screen API if the fullScreenEnabled setting has // been explicitly enabled. Otherwise, use the old fullscreen API. This // allows apps which embed a WebView to retain the existing full screen // video implementation without requiring them to implement their own full // screen behavior. - if (document().settings() && document().settings()->fullScreenEnabled()) { + if (document().settings().fullScreenEnabled()) { if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == parentMediaElement(this)) document().webkitCancelFullScreen(); else - document().requestFullScreenForElement(parentMediaElement(this), 0, Document::ExemptIFrameAllowFullScreenRequirement); + document().requestFullScreenForElement(parentMediaElement(this), Document::ExemptIFrameAllowFullScreenRequirement); } else #endif mediaController()->enterFullscreen(); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral)); - return id; -} - void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen) { setDisplayType(isFullscreen ? MediaExitFullscreenButton : MediaEnterFullscreenButton); @@ -1092,143 +976,119 @@ void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen) MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(Document& document) : MediaControlInputElement(document, MediaUnMuteButton) { + setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-min-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document& document) +Ref<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document& document) { - RefPtr<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(document)); + Ref<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMinButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event) +void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { - ExceptionCode code = 0; - mediaController()->setVolume(0, code); - event->setDefaultHandled(); + if (event.type() == eventNames().clickEvent) { + mediaController()->setVolume(0); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlFullscreenVolumeMinButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-min-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlFullscreenVolumeMaxButtonElement::MediaControlFullscreenVolumeMaxButtonElement(Document& document) : MediaControlInputElement(document, MediaMuteButton) { + setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-max-button", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document& document) +Ref<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document& document) { - RefPtr<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(document)); + Ref<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMaxButtonElement(document)); button->ensureUserAgentShadowRoot(); button->setType("button"); - return button.release(); + return button; } -void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event) +void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { - ExceptionCode code = 0; - mediaController()->setVolume(1, code); - event->setDefaultHandled(); + if (event.type() == eventNames().clickEvent) { + mediaController()->setVolume(1); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); } -const AtomicString& MediaControlFullscreenVolumeMaxButtonElement::shadowPseudoId() const -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-max-button", AtomicString::ConstructFromLiteral)); - return id; -} - // ---------------------------- MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document) : MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay) { + setPseudo(getMediaControlTimeRemainingDisplayElementShadowPseudoId()); } -PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document) +Ref<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document) { - return adoptRef(new MediaControlTimeRemainingDisplayElement(document)); + return adoptRef(*new MediaControlTimeRemainingDisplayElement(document)); } static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId() { - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> id("-webkit-media-controls-time-remaining-display", AtomicString::ConstructFromLiteral); return id; } -const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const -{ - return getMediaControlTimeRemainingDisplayElementShadowPseudoId(); -} - // ---------------------------- MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document) : MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay) { + setPseudo(getMediaControlCurrentTimeDisplayElementShadowPseudoId()); } -PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document) +Ref<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document) { - return adoptRef(new MediaControlCurrentTimeDisplayElement(document)); + return adoptRef(*new MediaControlCurrentTimeDisplayElement(document)); } static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId() { - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display", AtomicString::ConstructFromLiteral)); + static NeverDestroyed<AtomicString> id("-webkit-media-controls-current-time-display", AtomicString::ConstructFromLiteral); return id; } -const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const -{ - return getMediaControlCurrentTimeDisplayElementShadowPseudoId(); -} - // ---------------------------- #if ENABLE(VIDEO_TRACK) MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document) : MediaControlDivElement(document, MediaTextTrackDisplayContainer) - , m_updateTimer(this, &MediaControlTextTrackContainerElement::updateTimerFired) + , m_updateTimer(*this, &MediaControlTextTrackContainerElement::updateTimerFired) , m_fontSize(0) , m_fontSizeIsImportant(false) + , m_updateTextTrackRepresentationStyle(false) { + setPseudo(AtomicString("-webkit-media-text-track-container", AtomicString::ConstructFromLiteral)); } -PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document) +Ref<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document) { - RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(document)); + auto element = adoptRef(*new MediaControlTextTrackContainerElement(document)); element->hide(); - return element.release(); + return element; } -RenderPtr<RenderElement> MediaControlTextTrackContainerElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> MediaControlTextTrackContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderTextTrackContainerElement>(*this, std::move(style)); + return createRenderer<RenderTextTrackContainerElement>(*this, WTFMove(style)); } -const AtomicString& MediaControlTextTrackContainerElement::textTrackContainerElementShadowPseudoId() -{ - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-text-track-container", AtomicString::ConstructFromLiteral)); - return id; -} - -const AtomicString& MediaControlTextTrackContainerElement::shadowPseudoId() const +static bool compareCueIntervalForDisplay(const CueInterval& one, const CueInterval& two) { - return textTrackContainerElementShadowPseudoId(); -} + return one.data()->isPositionedAbove(two.data()); +}; void MediaControlTextTrackContainerElement::updateDisplay() { @@ -1243,7 +1103,7 @@ void MediaControlTextTrackContainerElement::updateDisplay() return; // 2. Let video be the media element or other playback mechanism. - HTMLVideoElement* video = toHTMLVideoElement(mediaElement); + HTMLVideoElement& video = downcast<HTMLVideoElement>(*mediaElement); // 3. Let output be an empty list of absolutely positioned CSS block boxes. Vector<RefPtr<HTMLDivElement>> output; @@ -1267,7 +1127,7 @@ void MediaControlTextTrackContainerElement::updateDisplay() // 7. Let cues be an empty list of text track cues. // 8. For each track track in tracks, append to cues all the cues from // track's list of cues that have their text track cue active flag set. - CueList activeCues = video->currentlyActiveCues(); + CueList activeCues = video.currentlyActiveCues(); // 9. If reset is false, then, for each text track cue cue in cues: if cue's // text track cue display state has a set of CSS boxes, then add those boxes @@ -1277,76 +1137,158 @@ void MediaControlTextTrackContainerElement::updateDisplay() // within the TextTrackCue instance itself. If parameters of the cue change, // the display tree is cleared. + // If the number of CSS boxes in the output is less than the number of cues + // we wish to render (e.g., we are adding another cue in a set of roll-up + // cues), remove all the existing CSS boxes representing the cues and re-add + // them so that the new cue is at the bottom. + // FIXME: Calling countChildNodes() here is inefficient. We don't need to + // traverse all children just to check if there are less children than cues. + if (countChildNodes() < activeCues.size()) + removeChildren(); + + // Sort the active cues for the appropriate display order. For example, for roll-up + // or paint-on captions, we need to add the cues in reverse chronological order, + // so that the newest captions appear at the bottom. + std::sort(activeCues.begin(), activeCues.end(), &compareCueIntervalForDisplay); + // 10. For each text track cue cue in cues that has not yet had // corresponding CSS boxes added to output, in text track cue order, run the // following substeps: for (size_t i = 0; i < activeCues.size(); ++i) { - TextTrackCue* cue = activeCues[i].data(); + if (!mediaController()->closedCaptionsVisible()) + continue; + + TextTrackCue* textTrackCue = activeCues[i].data(); + if (!textTrackCue->isRenderable()) + continue; + + VTTCue* cue = toVTTCue(textTrackCue); ASSERT(cue->isActive()); if (!cue->track() || !cue->track()->isRendered() || !cue->isActive() || cue->text().isEmpty()) continue; - RefPtr<TextTrackCueBox> displayBox = cue->getDisplayTree(m_videoDisplaySize.size()); - if (displayBox->hasChildNodes() && !contains(displayBox.get())) { - // Note: the display tree of a cue is removed when the active flag of the cue is unset. - appendChild(displayBox, ASSERT_NO_EXCEPTION); - cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant); + LOG(Media, "MediaControlTextTrackContainerElement::updateDisplay(%p) - adding and positioning cue #%zu: \"%s\", start=%.2f, end=%.2f, line=%.2f", this, i, cue->text().utf8().data(), cue->startTime(), cue->endTime(), cue->line()); + + Ref<VTTCueBox> displayBox = cue->getDisplayTree(m_videoDisplaySize.size(), m_fontSize); + if (cue->track()->mode() == TextTrack::Mode::Disabled) + continue; + + VTTRegion* region = cue->track()->regions()->getRegionById(cue->regionId()); + if (!region) { + // If cue has an empty text track cue region identifier or there is no + // WebVTT region whose region identifier is identical to cue's text + // track cue region identifier, run the following substeps: + if (displayBox->hasChildNodes() && !contains(displayBox.ptr())) { + // Note: the display tree of a cue is removed when the active flag of the cue is unset. + appendChild(displayBox); + cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant); + } + } else { + // Let region be the WebVTT region whose region identifier + // matches the text track cue region identifier of cue. + Ref<HTMLDivElement> regionNode = region->getDisplayTree(); + + // Append the region to the viewport, if it was not already. + if (!contains(regionNode.ptr())) + appendChild(region->getDisplayTree()); + + region->appendTextTrackCueBox(WTFMove(displayBox)); } } // 11. Return output. if (hasChildNodes()) { show(); - if (mediaElement->requiresTextTrackRepresentation()) { - if (!m_textTrackRepresentation) - m_textTrackRepresentation = TextTrackRepresentation::create(this); - mediaElement->setTextTrackRepresentation(m_textTrackRepresentation.get()); - - if (Page* page = document().page()) - m_textTrackRepresentation->setContentScale(page->deviceScaleFactor()); - - m_textTrackRepresentation->update(); - setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX); - setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX); - } + updateTextTrackRepresentation(); } else { hide(); clearTextTrackRepresentation(); } } -void MediaControlTextTrackContainerElement::updateTimerFired(Timer<MediaControlTextTrackContainerElement>&) +void MediaControlTextTrackContainerElement::updateActiveCuesFontSize() { if (!document().page()) return; - if (m_textTrackRepresentation) { - setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX); - setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX); - } - HTMLMediaElement* mediaElement = parentMediaElement(this); if (!mediaElement) return; float smallestDimension = std::min(m_videoDisplaySize.size().height(), m_videoDisplaySize.size().width()); - float fontScale = document().page()->group().captionPreferences()->captionFontSizeScaleAndImportance(m_fontSizeIsImportant); + float fontScale = document().page()->group().captionPreferences().captionFontSizeScaleAndImportance(m_fontSizeIsImportant); m_fontSize = lroundf(smallestDimension * fontScale); - - CueList activeCues = mediaElement->currentlyActiveCues(); - for (size_t i = 0; i < activeCues.size(); ++i) { - TextTrackCue* cue = activeCues[i].data(); - cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant); + + for (auto& activeCue : mediaElement->currentlyActiveCues()) { + TextTrackCue* cue = activeCue.data(); + if (!cue->isRenderable()) + continue; + + toVTTCue(cue)->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant); } + +} + +void MediaControlTextTrackContainerElement::updateTimerFired() +{ + if (!document().page()) + return; + + if (m_textTrackRepresentation) + updateStyleForTextTrackRepresentation(); + + updateActiveCuesFontSize(); updateDisplay(); } +void MediaControlTextTrackContainerElement::updateTextTrackRepresentation() +{ + HTMLMediaElement* mediaElement = parentMediaElement(this); + if (!mediaElement) + return; + + if (!mediaElement->requiresTextTrackRepresentation()) + return; + + if (!m_textTrackRepresentation) { + m_textTrackRepresentation = TextTrackRepresentation::create(*this); + m_updateTextTrackRepresentationStyle = true; + mediaElement->setTextTrackRepresentation(m_textTrackRepresentation.get()); + } + + m_textTrackRepresentation->update(); + updateStyleForTextTrackRepresentation(); +} + void MediaControlTextTrackContainerElement::clearTextTrackRepresentation() { + if (!m_textTrackRepresentation) + return; + + m_textTrackRepresentation = nullptr; + m_updateTextTrackRepresentationStyle = true; if (HTMLMediaElement* mediaElement = parentMediaElement(this)) mediaElement->setTextTrackRepresentation(nullptr); - m_textTrackRepresentation = nullptr; + updateStyleForTextTrackRepresentation(); + updateActiveCuesFontSize(); +} + +void MediaControlTextTrackContainerElement::updateStyleForTextTrackRepresentation() +{ + if (!m_updateTextTrackRepresentationStyle) + return; + m_updateTextTrackRepresentationStyle = false; + + if (m_textTrackRepresentation) { + setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX); + setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX); + setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute); + setInlineStyleProperty(CSSPropertyLeft, 0, CSSPrimitiveValue::CSS_PX); + setInlineStyleProperty(CSSPropertyTop, 0, CSSPrimitiveValue::CSS_PX); + return; + } + removeInlineStyleProperty(CSSPropertyPosition); removeInlineStyleProperty(CSSPropertyWidth); removeInlineStyleProperty(CSSPropertyHeight); @@ -1356,6 +1298,8 @@ void MediaControlTextTrackContainerElement::clearTextTrackRepresentation() void MediaControlTextTrackContainerElement::enteredFullscreen() { + if (hasChildNodes()) + updateTextTrackRepresentation(); updateSizes(true); } @@ -1374,31 +1318,28 @@ void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate) if (!document().page()) return; - IntRect videoBox; + mediaElement->syncTextTrackBounds(); + IntRect videoBox; if (m_textTrackRepresentation) videoBox = m_textTrackRepresentation->bounds(); else { -#if ENABLE(PLUGIN_PROXY_FOR_VIDEO) - if (!mediaElement->renderer() || !mediaElement->renderer()->isWidget()) + if (!is<RenderVideo>(mediaElement->renderer())) return; - videoBox = pixelSnappedIntRect(toRenderWidget(mediaElement->renderer())->contentBoxRect()); -#else - if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo()) - return; - videoBox = toRenderVideo(*mediaElement->renderer()).videoBox(); -#endif + videoBox = downcast<RenderVideo>(*mediaElement->renderer()).videoBox(); } if (!forceUpdate && m_videoDisplaySize == videoBox) return; + m_videoDisplaySize = videoBox; + m_updateTextTrackRepresentationStyle = true; // FIXME (121170): This function is called during layout, and should lay out the text tracks immediately. m_updateTimer.startOneShot(0); } -PassRefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentationImage() +RefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentationImage() { if (!hasChildNodes()) return nullptr; @@ -1409,14 +1350,14 @@ PassRefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresen document().updateLayout(); - auto renderer = this->renderer(); + auto* renderer = this->renderer(); if (!renderer) return nullptr; if (!renderer->hasLayer()) return nullptr; - RenderLayer* layer = toRenderLayerModelObject(renderer)->layer(); + RenderLayer* layer = downcast<RenderLayerModelObject>(*renderer).layer(); float deviceScaleFactor = 1; if (Page* page = document().page()) @@ -1424,17 +1365,20 @@ PassRefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresen IntRect paintingRect = IntRect(IntPoint(), layer->size()); - std::unique_ptr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB)); + // FIXME (149422): This buffer should not be unconditionally unaccelerated. + std::unique_ptr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), Unaccelerated, deviceScaleFactor)); if (!buffer) return nullptr; - layer->paint(buffer->context(), paintingRect, PaintBehaviorFlattenCompositingLayers, nullptr, nullptr, RenderLayer::PaintLayerPaintingCompositingAllPhases); + layer->paint(buffer->context(), paintingRect, LayoutSize(), PaintBehaviorFlattenCompositingLayers, nullptr, RenderLayer::PaintLayerPaintingCompositingAllPhases); - return buffer->copyImage(); + return ImageBuffer::sinkIntoImage(WTFMove(buffer)); } void MediaControlTextTrackContainerElement::textTrackRepresentationBoundsChanged(const IntRect&) { + if (hasChildNodes()) + updateTextTrackRepresentation(); updateSizes(); } |