From 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 27 Jun 2017 06:07:23 +0000 Subject: webkitgtk-2.16.5 --- .../WebCore/html/shadow/AutoFillButtonElement.cpp | 69 ++ Source/WebCore/html/shadow/AutoFillButtonElement.h | 52 ++ Source/WebCore/html/shadow/ContentDistributor.cpp | 162 ----- Source/WebCore/html/shadow/ContentDistributor.h | 96 --- .../WebCore/html/shadow/DetailsMarkerControl.cpp | 29 +- Source/WebCore/html/shadow/DetailsMarkerControl.h | 25 +- .../html/shadow/ImageControlsRootElement.cpp | 51 ++ .../WebCore/html/shadow/ImageControlsRootElement.h | 51 ++ Source/WebCore/html/shadow/InsertionPoint.cpp | 162 ----- Source/WebCore/html/shadow/InsertionPoint.h | 130 ---- .../html/shadow/MediaControlElementTypes.cpp | 99 +-- .../WebCore/html/shadow/MediaControlElementTypes.h | 47 +- .../WebCore/html/shadow/MediaControlElements.cpp | 768 ++++++++++----------- Source/WebCore/html/shadow/MediaControlElements.h | 199 +++--- Source/WebCore/html/shadow/MediaControls.cpp | 45 +- Source/WebCore/html/shadow/MediaControls.h | 31 +- Source/WebCore/html/shadow/MediaControlsApple.cpp | 568 +++++++++++++++ Source/WebCore/html/shadow/MediaControlsApple.h | 122 ++++ Source/WebCore/html/shadow/MediaControlsGtk.cpp | 378 ---------- Source/WebCore/html/shadow/MediaControlsGtk.h | 83 --- Source/WebCore/html/shadow/MeterShadowElement.cpp | 115 --- Source/WebCore/html/shadow/MeterShadowElement.h | 111 --- .../WebCore/html/shadow/ProgressShadowElement.cpp | 11 +- Source/WebCore/html/shadow/ProgressShadowElement.h | 32 +- Source/WebCore/html/shadow/SliderThumbElement.cpp | 301 ++++---- Source/WebCore/html/shadow/SliderThumbElement.h | 77 ++- Source/WebCore/html/shadow/SpinButtonElement.cpp | 85 +-- Source/WebCore/html/shadow/SpinButtonElement.h | 46 +- .../html/shadow/TextControlInnerElements.cpp | 385 +++-------- .../WebCore/html/shadow/TextControlInnerElements.h | 127 +--- .../html/shadow/YouTubeEmbedShadowElement.cpp | 49 ++ .../html/shadow/YouTubeEmbedShadowElement.h | 43 ++ Source/WebCore/html/shadow/meterElementShadow.css | 36 + 33 files changed, 1983 insertions(+), 2602 deletions(-) create mode 100644 Source/WebCore/html/shadow/AutoFillButtonElement.cpp create mode 100644 Source/WebCore/html/shadow/AutoFillButtonElement.h delete mode 100644 Source/WebCore/html/shadow/ContentDistributor.cpp delete mode 100644 Source/WebCore/html/shadow/ContentDistributor.h create mode 100644 Source/WebCore/html/shadow/ImageControlsRootElement.cpp create mode 100644 Source/WebCore/html/shadow/ImageControlsRootElement.h delete mode 100644 Source/WebCore/html/shadow/InsertionPoint.cpp delete mode 100644 Source/WebCore/html/shadow/InsertionPoint.h create mode 100644 Source/WebCore/html/shadow/MediaControlsApple.cpp create mode 100644 Source/WebCore/html/shadow/MediaControlsApple.h delete mode 100644 Source/WebCore/html/shadow/MediaControlsGtk.cpp delete mode 100644 Source/WebCore/html/shadow/MediaControlsGtk.h delete mode 100644 Source/WebCore/html/shadow/MeterShadowElement.cpp delete mode 100644 Source/WebCore/html/shadow/MeterShadowElement.h create mode 100644 Source/WebCore/html/shadow/YouTubeEmbedShadowElement.cpp create mode 100644 Source/WebCore/html/shadow/YouTubeEmbedShadowElement.h create mode 100644 Source/WebCore/html/shadow/meterElementShadow.css (limited to 'Source/WebCore/html/shadow') diff --git a/Source/WebCore/html/shadow/AutoFillButtonElement.cpp b/Source/WebCore/html/shadow/AutoFillButtonElement.cpp new file mode 100644 index 000000000..c021daab7 --- /dev/null +++ b/Source/WebCore/html/shadow/AutoFillButtonElement.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "AutoFillButtonElement.h" + +#include "Event.h" +#include "EventNames.h" +#include "HTMLNames.h" +#include "MouseEvent.h" +#include "TextFieldInputType.h" + +namespace WebCore { + +using namespace HTMLNames; + +Ref AutoFillButtonElement::create(Document& document, AutoFillButtonOwner& owner) +{ + return adoptRef(*new AutoFillButtonElement(document, owner)); +} + +AutoFillButtonElement::AutoFillButtonElement(Document& document, AutoFillButtonOwner& owner) + : HTMLDivElement(divTag, document) + , m_owner(owner) +{ +} + +void AutoFillButtonElement::defaultEventHandler(Event& event) +{ + if (!is(event)) { + if (!event.defaultHandled()) + HTMLDivElement::defaultEventHandler(event); + return; + } + + MouseEvent& mouseEvent = downcast(event); + + if (mouseEvent.type() == eventNames().clickEvent) { + m_owner.autoFillButtonElementWasClicked(); + event.setDefaultHandled(); + } + + if (!event.defaultHandled()) + HTMLDivElement::defaultEventHandler(event); +} + +} // namespace WebCore diff --git a/Source/WebCore/html/shadow/AutoFillButtonElement.h b/Source/WebCore/html/shadow/AutoFillButtonElement.h new file mode 100644 index 000000000..58c474eab --- /dev/null +++ b/Source/WebCore/html/shadow/AutoFillButtonElement.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "HTMLDivElement.h" + +namespace WebCore { + +class TextFieldInputType; + +class AutoFillButtonElement final : public HTMLDivElement { +public: + class AutoFillButtonOwner { + public: + virtual ~AutoFillButtonOwner() { } + virtual void autoFillButtonElementWasClicked() = 0; + }; + + static Ref create(Document&, AutoFillButtonOwner&); + +private: + explicit AutoFillButtonElement(Document&, AutoFillButtonOwner&); + + void defaultEventHandler(Event&) override; + + AutoFillButtonOwner& m_owner; +}; + +} // namespace WebCore diff --git a/Source/WebCore/html/shadow/ContentDistributor.cpp b/Source/WebCore/html/shadow/ContentDistributor.cpp deleted file mode 100644 index c4c77a747..000000000 --- a/Source/WebCore/html/shadow/ContentDistributor.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ContentDistributor.h" - -#include "ElementIterator.h" -#include "InsertionPoint.h" - -namespace WebCore { - -ContentDistributor::ContentDistributor() - : m_insertionPointListIsValid(true) - , m_validity(Undetermined) -{ -} - -ContentDistributor::~ContentDistributor() -{ -} - -void ContentDistributor::invalidateInsertionPointList() -{ - m_insertionPointListIsValid = false; - m_insertionPointList.clear(); -} - -const Vector>& ContentDistributor::ensureInsertionPointList(ShadowRoot* shadowRoot) -{ - if (m_insertionPointListIsValid) - return m_insertionPointList; - - m_insertionPointListIsValid = true; - ASSERT(m_insertionPointList.isEmpty()); - - for (auto& element : descendantsOfType(*shadowRoot)) { - if (element.isInsertionPoint()) - m_insertionPointList.append(toInsertionPoint(&element)); - } - - return m_insertionPointList; -} - -InsertionPoint* ContentDistributor::findInsertionPointFor(const Node* key) const -{ - return m_nodeToInsertionPoint.get(key); -} - -void ContentDistributor::distribute(Element* host) -{ - ASSERT(needsDistribution()); - ASSERT(m_nodeToInsertionPoint.isEmpty()); - ASSERT(!host->containingShadowRoot() || host->containingShadowRoot()->distributor().isValid()); - - m_validity = Valid; - - if (ShadowRoot* root = host->shadowRoot()) { - const Vector>& insertionPoints = ensureInsertionPointList(root); - for (size_t i = 0; i < insertionPoints.size(); ++i) { - InsertionPoint* point = insertionPoints[i].get(); - if (!point->isActive()) - continue; - - distributeSelectionsTo(point, host); - } - } -} - -bool ContentDistributor::invalidate(Element* host) -{ - ASSERT(needsInvalidation()); - bool needsReattach = (m_validity == Undetermined) || !m_nodeToInsertionPoint.isEmpty(); - - if (ShadowRoot* root = host->shadowRoot()) { - const Vector>& insertionPoints = ensureInsertionPointList(root); - for (size_t i = 0; i < insertionPoints.size(); ++i) { - needsReattach = true; - insertionPoints[i]->clearDistribution(); - } - } - - m_validity = Invalidating; - m_nodeToInsertionPoint.clear(); - return needsReattach; -} - -void ContentDistributor::distributeSelectionsTo(InsertionPoint* insertionPoint, Element* host) -{ - for (Node* child = host->firstChild(); child; child = child->nextSibling()) { - ASSERT(!child->isInsertionPoint()); - - if (insertionPoint->matchTypeFor(child) != InsertionPoint::AlwaysMatches) - continue; - - m_nodeToInsertionPoint.add(child, insertionPoint); - } - - if (m_nodeToInsertionPoint.isEmpty()) - return; - insertionPoint->setHasDistribution(); -} - -void ContentDistributor::ensureDistribution(ShadowRoot* shadowRoot) -{ - ASSERT(shadowRoot); - - Vector shadowRoots; - for (Element* current = shadowRoot->hostElement(); current; current = current->shadowHost()) { - ShadowRoot* currentRoot = current->shadowRoot(); - if (!currentRoot->distributor().needsDistribution()) - break; - shadowRoots.append(currentRoot); - } - - for (size_t i = shadowRoots.size(); i > 0; --i) - shadowRoots[i - 1]->distributor().distribute(shadowRoots[i - 1]->hostElement()); -} - -void ContentDistributor::invalidateDistribution(Element* host) -{ - bool didNeedInvalidation = needsInvalidation(); - bool needsReattach = didNeedInvalidation ? invalidate(host) : false; - - if (needsReattach) - host->setNeedsStyleRecalc(ReconstructRenderTree); - - if (didNeedInvalidation) { - ASSERT(m_validity == Invalidating); - m_validity = Invalidated; - } -} - -void ContentDistributor::didShadowBoundaryChange(Element* host) -{ - setValidity(Undetermined); - invalidateDistribution(host); -} - -} diff --git a/Source/WebCore/html/shadow/ContentDistributor.h b/Source/WebCore/html/shadow/ContentDistributor.h deleted file mode 100644 index f0ed8af0d..000000000 --- a/Source/WebCore/html/shadow/ContentDistributor.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ContentDistributor_h -#define ContentDistributor_h - -#include -#include -#include -#include - -namespace WebCore { - -class ContainerNode; -class Element; -class InsertionPoint; -class Node; -class ShadowRoot; - -class ContentDistributor { - WTF_MAKE_NONCOPYABLE(ContentDistributor); -public: - enum Validity { - Valid = 0, - Invalidated = 1, - Invalidating = 2, - Undetermined = 3 - }; - - ContentDistributor(); - ~ContentDistributor(); - - void invalidateInsertionPointList(); - - InsertionPoint* findInsertionPointFor(const Node* key) const; - - void distributeSelectionsTo(InsertionPoint*, Element* host); - - void invalidateDistribution(Element* host); - void didShadowBoundaryChange(Element* host); - - static void ensureDistribution(ShadowRoot*); - void distribute(Element* host); - bool needsDistribution() const; - -private: - const Vector>& ensureInsertionPointList(ShadowRoot*); - - bool invalidate(Element* host); - - void setValidity(Validity validity) { m_validity = validity; } - bool isValid() const { return m_validity == Valid; } - bool needsInvalidation() const { return m_validity != Invalidated; } - - Vector> m_insertionPointList; - HashMap> m_nodeToInsertionPoint; - bool m_insertionPointListIsValid; - unsigned m_validity : 2; -}; - -inline bool ContentDistributor::needsDistribution() const -{ - // During the invalidation, re-distribution should be supressed. - return m_validity != Valid && m_validity != Invalidating; -} - -} - -#endif diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp index a48e29f49..6cdf65f1b 100644 --- a/Source/WebCore/html/shadow/DetailsMarkerControl.cpp +++ b/Source/WebCore/html/shadow/DetailsMarkerControl.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,7 +30,6 @@ */ #include "config.h" -#if ENABLE(DETAILS_ELEMENT) #include "DetailsMarkerControl.h" #include "HTMLNames.h" @@ -38,34 +38,25 @@ namespace WebCore { -using namespace HTMLNames; - -DetailsMarkerControl::DetailsMarkerControl(Document& document) - : HTMLDivElement(divTag, document) -{ -} - -RenderPtr DetailsMarkerControl::createElementRenderer(PassRef style) +Ref DetailsMarkerControl::create(Document& document) { - return createRenderer(*this, std::move(style)); + return adoptRef(*new DetailsMarkerControl(document)); } -bool DetailsMarkerControl::rendererIsNeeded(const RenderStyle& style) +DetailsMarkerControl::DetailsMarkerControl(Document& document) + : HTMLDivElement(HTMLNames::divTag, document) { - return summaryElement()->isMainSummary() && HTMLDivElement::rendererIsNeeded(style); + setPseudo(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral)); } -const AtomicString& DetailsMarkerControl::shadowPseudoId() const +RenderPtr DetailsMarkerControl::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - DEFINE_STATIC_LOCAL(AtomicString, pseudId, ("-webkit-details-marker", AtomicString::ConstructFromLiteral)); - return pseudId; + return createRenderer(*this, WTFMove(style)); } -HTMLSummaryElement* DetailsMarkerControl::summaryElement() +bool DetailsMarkerControl::rendererIsNeeded(const RenderStyle& style) { - return toHTMLSummaryElement(shadowHost()); + return downcast(shadowHost())->isActiveSummary() && HTMLDivElement::rendererIsNeeded(style); } } - -#endif diff --git a/Source/WebCore/html/shadow/DetailsMarkerControl.h b/Source/WebCore/html/shadow/DetailsMarkerControl.h index 004dd10e3..fb16c736a 100644 --- a/Source/WebCore/html/shadow/DetailsMarkerControl.h +++ b/Source/WebCore/html/shadow/DetailsMarkerControl.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,35 +29,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DetailsMarkerControl_h -#define DetailsMarkerControl_h +#pragma once #include "HTMLDivElement.h" -#include namespace WebCore { -class HTMLSummaryElement; - class DetailsMarkerControl final : public HTMLDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: DetailsMarkerControl(Document&); - virtual RenderPtr createElementRenderer(PassRef) override; - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual const AtomicString& shadowPseudoId() const override; - - HTMLSummaryElement* summaryElement(); + RenderPtr createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; + bool rendererIsNeeded(const RenderStyle&) override; }; -inline PassRefPtr DetailsMarkerControl::create(Document& document) -{ - return adoptRef(new DetailsMarkerControl(document)); -} - -} - -#endif +} // namespace WebCore diff --git a/Source/WebCore/html/shadow/ImageControlsRootElement.cpp b/Source/WebCore/html/shadow/ImageControlsRootElement.cpp new file mode 100644 index 000000000..f178dfad8 --- /dev/null +++ b/Source/WebCore/html/shadow/ImageControlsRootElement.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ImageControlsRootElement.h" + +#if ENABLE(SERVICE_CONTROLS) + +namespace WebCore { + +#if !PLATFORM(MAC) +Ref ImageControlsRootElement::maybeCreate(Document& document) +{ + return adoptRef(*new ImageControlsRootElement(document)); +} +#endif + +ImageControlsRootElement::ImageControlsRootElement(Document& document) + : HTMLDivElement(HTMLNames::divTag, document) +{ +} + +ImageControlsRootElement::~ImageControlsRootElement() +{ +} + +} // namespace WebCore + +#endif // ENABLE(SERVICE_CONTROLS) diff --git a/Source/WebCore/html/shadow/ImageControlsRootElement.h b/Source/WebCore/html/shadow/ImageControlsRootElement.h new file mode 100644 index 000000000..19986dfe2 --- /dev/null +++ b/Source/WebCore/html/shadow/ImageControlsRootElement.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(SERVICE_CONTROLS) + +#include "HTMLDivElement.h" + +namespace WebCore { + +class Document; + +class ImageControlsRootElement : public HTMLDivElement { +public: + virtual ~ImageControlsRootElement(); + + static RefPtr tryCreate(Document&); + +protected: + explicit ImageControlsRootElement(Document&); + +private: + bool isImageControlsRootElement() const final { return true; } +}; + +} // namespace WebCore + +#endif // ENABLE(SERVICE_CONTROLS) diff --git a/Source/WebCore/html/shadow/InsertionPoint.cpp b/Source/WebCore/html/shadow/InsertionPoint.cpp deleted file mode 100644 index 102c8f218..000000000 --- a/Source/WebCore/html/shadow/InsertionPoint.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "InsertionPoint.h" - -#include "QualifiedName.h" -#include "StaticNodeList.h" -#include "Text.h" - -namespace WebCore { - -using namespace HTMLNames; - -InsertionPoint::InsertionPoint(const QualifiedName& tagName, Document& document) - : HTMLElement(tagName, document, CreateInsertionPoint) - , m_hasDistribution(false) -{ -} - -InsertionPoint::~InsertionPoint() -{ -} - -bool InsertionPoint::shouldUseFallbackElements() const -{ - return isActive() && !hasDistribution(); -} - -bool InsertionPoint::isActive() const -{ - if (!containingShadowRoot()) - return false; - const Node* node = parentNode(); - while (node) { - if (node->isInsertionPoint()) - return false; - - node = node->parentNode(); - } - return true; -} - -bool InsertionPoint::rendererIsNeeded(const RenderStyle& style) -{ - return !isActive() && HTMLElement::rendererIsNeeded(style); -} - -void InsertionPoint::childrenChanged(const ChildChange& change) -{ - HTMLElement::childrenChanged(change); - if (ShadowRoot* root = containingShadowRoot()) - root->invalidateDistribution(); -} - -Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode& insertionPoint) -{ - HTMLElement::insertedInto(insertionPoint); - - if (ShadowRoot* root = containingShadowRoot()) { - root->distributor().didShadowBoundaryChange(root->hostElement()); - root->distributor().invalidateInsertionPointList(); - } - - return InsertionDone; -} - -void InsertionPoint::removedFrom(ContainerNode& insertionPoint) -{ - ShadowRoot* root = containingShadowRoot(); - if (!root) - root = insertionPoint.containingShadowRoot(); - - if (root && root->hostElement()) { - root->invalidateDistribution(); - root->distributor().invalidateInsertionPointList(); - } - - // Since this insertion point is no longer visible from the shadow subtree, it need to clean itself up. - clearDistribution(); - - HTMLElement::removedFrom(insertionPoint); -} - -Node* InsertionPoint::firstDistributed() const -{ - if (!m_hasDistribution) - return 0; - for (Node* current = shadowHost()->firstChild(); current; current = current->nextSibling()) { - if (matchTypeFor(current) == InsertionPoint::AlwaysMatches) - return current; - } - return 0; -} - -Node* InsertionPoint::lastDistributed() const -{ - if (!m_hasDistribution) - return 0; - for (Node* current = shadowHost()->lastChild(); current; current = current->previousSibling()) { - if (matchTypeFor(current) == InsertionPoint::AlwaysMatches) - return current; - } - return 0; -} - -Node* InsertionPoint::nextDistributedTo(const Node* node) const -{ - for (Node* current = node->nextSibling(); current; current = current->nextSibling()) { - if (matchTypeFor(current) == InsertionPoint::AlwaysMatches) - return current; - } - return 0; -} - -Node* InsertionPoint::previousDistributedTo(const Node* node) const -{ - for (Node* current = node->previousSibling(); current; current = current->previousSibling()) { - if (matchTypeFor(current) == InsertionPoint::AlwaysMatches) - return current; - } - return 0; -} - -InsertionPoint* findInsertionPointOf(const Node* projectedNode) -{ - if (ShadowRoot* shadowRoot = shadowRootOfParentForDistribution(projectedNode)) { - if (ShadowRoot* root = projectedNode->containingShadowRoot()) - ContentDistributor::ensureDistribution(root); - return shadowRoot->distributor().findInsertionPointFor(projectedNode); - } - return 0; -} - -} // namespace WebCore diff --git a/Source/WebCore/html/shadow/InsertionPoint.h b/Source/WebCore/html/shadow/InsertionPoint.h deleted file mode 100644 index c7927d273..000000000 --- a/Source/WebCore/html/shadow/InsertionPoint.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef InsertionPoint_h -#define InsertionPoint_h - -#include "ContentDistributor.h" -#include "HTMLElement.h" -#include "HTMLNames.h" -#include "ShadowRoot.h" -#include - -namespace WebCore { - -class InsertionPoint : public HTMLElement { -public: - enum MatchType { - AlwaysMatches, - NeverMatches, - }; - - virtual ~InsertionPoint(); - - bool hasDistribution() const { return m_hasDistribution; } - void setHasDistribution() { m_hasDistribution = true; } - void clearDistribution() { m_hasDistribution = false; } - bool isActive() const; - - virtual MatchType matchTypeFor(Node*) const { return AlwaysMatches; } - - bool shouldUseFallbackElements() const; - - Node* firstDistributed() const; - Node* lastDistributed() const; - Node* nextDistributedTo(const Node*) const; - Node* previousDistributedTo(const Node*) const; - -protected: - InsertionPoint(const QualifiedName&, Document&); - virtual bool rendererIsNeeded(const RenderStyle&) override; - virtual void childrenChanged(const ChildChange&) override; - virtual InsertionNotificationRequest insertedInto(ContainerNode&) override; - virtual void removedFrom(ContainerNode&) override; - virtual bool isInsertionPointNode() const override { return true; } - -private: - - bool m_hasDistribution; -}; - -inline bool isInsertionPoint(const Node& node) { return node.isInsertionPoint(); } - -NODE_TYPE_CASTS(InsertionPoint); - -inline bool isActiveInsertionPoint(const Node* node) -{ - return node && node->isInsertionPoint() && toInsertionPoint(node)->isActive(); -} - -inline Node* parentNodeForDistribution(const Node* node) -{ - ASSERT(node); - - if (Node* parent = node->parentNode()) { - if (parent->isInsertionPoint() && toInsertionPoint(parent)->shouldUseFallbackElements()) - return parent->parentNode(); - return parent; - } - - return 0; -} - -inline Element* parentElementForDistribution(const Node* node) -{ - if (Node* parent = parentNodeForDistribution(node)) { - if (parent->isElementNode()) - return toElement(parent); - } - - return 0; -} - -inline ShadowRoot* shadowRootOfParentForDistribution(const Node* node) -{ - ASSERT(node); - if (Element* parent = parentElementForDistribution(node)) - return parent->shadowRoot(); - - return 0; -} - -InsertionPoint* findInsertionPointOf(const Node*); - -inline bool hasShadowRootOrActiveInsertionPointParent(const Node& node) -{ - return hasShadowRootParent(node) - || isActiveInsertionPoint(findInsertionPointOf(&node)) - || isActiveInsertionPoint(node.parentNode()); -} - -} // namespace WebCore - -#endif // InsertionPoint_h diff --git a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp b/Source/WebCore/html/shadow/MediaControlElementTypes.cpp index d6049a508..a2a62a890 100644 --- a/Source/WebCore/html/shadow/MediaControlElementTypes.cpp +++ b/Source/WebCore/html/shadow/MediaControlElementTypes.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. * @@ -33,7 +33,7 @@ #include "MediaControlElementTypes.h" #include "CSSValueKeywords.h" -#include "ExceptionCodePlaceholder.h" +#include "EventNames.h" #include "HTMLNames.h" #include "MouseEvent.h" #include "RenderMedia.h" @@ -46,12 +46,6 @@ using namespace HTMLNames; class Event; -// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in. -static const double cSkipRepeatDelay = 0.1; -static const double cSkipTime = 0.2; -static const double cScanRepeatDelay = 1.5; -static const double cScanMaximumRate = 8; - HTMLMediaElement* parentMediaElement(Node* node) { if (!node) @@ -59,18 +53,17 @@ HTMLMediaElement* parentMediaElement(Node* node) Node* mediaNode = node->shadowHost(); if (!mediaNode) mediaNode = node; - if (!mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement()) + if (!is(*mediaNode)) return nullptr; - return toHTMLMediaElement(mediaNode); + return downcast(mediaNode); } MediaControlElementType mediaControlElementType(Node* node) { ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement()); - HTMLElement* element = toHTMLElement(node); - if (isHTMLInputElement(element)) - return static_cast(element)->displayType(); - return static_cast(element)->displayType(); + if (is(*node)) + return static_cast(node)->displayType(); + return static_cast(node)->displayType(); } MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element) @@ -144,11 +137,11 @@ MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, { } -void MediaControlMuteButtonElement::defaultEventHandler(Event* event) +void MediaControlMuteButtonElement::defaultEventHandler(Event& event) { - if (event->type() == eventNames().clickEvent) { + if (event.type() == eventNames().clickEvent) { mediaController()->setMuted(!mediaController()->muted()); - event->setDefaultHandled(); + event.setDefaultHandled(); } HTMLInputElement::defaultEventHandler(event); @@ -168,18 +161,15 @@ void MediaControlMuteButtonElement::updateDisplayType() MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document& document, MediaControlElementType displayType) : MediaControlInputElement(document, displayType) - , m_actionOnStop(Nothing) - , m_seekType(Skip) - , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired) { } -void MediaControlSeekButtonElement::defaultEventHandler(Event* event) +void MediaControlSeekButtonElement::defaultEventHandler(Event& event) { // Set the mousedown and mouseup events as defaultHandled so they // do not trigger drag start or end actions in MediaControlPanelElement. - if (event->type() == eventNames().mousedownEvent || event->type() == eventNames().mouseupEvent) - event->setDefaultHandled(); + if (event.type() == eventNames().mousedownEvent || event.type() == eventNames().mouseupEvent) + event.setDefaultHandled(); } void MediaControlSeekButtonElement::setActive(bool flag, bool pause) @@ -188,62 +178,13 @@ void MediaControlSeekButtonElement::setActive(bool flag, bool pause) return; if (flag) - startTimer(); + mediaController()->beginScanning(isForwardButton() ? MediaControllerInterface::Forward : MediaControllerInterface::Backward); else - stopTimer(); + mediaController()->endScanning(); MediaControlInputElement::setActive(flag, pause); } -void MediaControlSeekButtonElement::startTimer() -{ - m_seekType = mediaController()->supportsScanning() ? Scan : Skip; - - if (m_seekType == Skip) { - // Seeking by skipping requires the video to be paused during seeking. - m_actionOnStop = mediaController()->paused() ? Nothing : Play; - mediaController()->pause(); - } else { - // Seeking by scanning requires the video to be playing during seeking. - m_actionOnStop = mediaController()->paused() ? Pause : Nothing; - mediaController()->play(); - mediaController()->setPlaybackRate(nextRate()); - } - - m_seekTimer.start(0, m_seekType == Skip ? cSkipRepeatDelay : cScanRepeatDelay); -} - -void MediaControlSeekButtonElement::stopTimer() -{ - if (m_seekType == Scan) - mediaController()->setPlaybackRate(mediaController()->defaultPlaybackRate()); - - if (m_actionOnStop == Play) - mediaController()->play(); - else if (m_actionOnStop == Pause) - mediaController()->pause(); - - if (m_seekTimer.isActive()) - m_seekTimer.stop(); -} - -double MediaControlSeekButtonElement::nextRate() const -{ - double rate = std::min(cScanMaximumRate, fabs(mediaController()->playbackRate() * 2)); - if (!isForwardButton()) - rate *= -1; - return rate; -} - -void MediaControlSeekButtonElement::seekTimerFired(Timer&) -{ - if (m_seekType == Skip) { - double skipTime = isForwardButton() ? cSkipTime : -cSkipTime; - mediaController()->setCurrentTime(mediaController()->currentTime() + skipTime); - } else - mediaController()->setPlaybackRate(nextRate()); -} - // ---------------------------- MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document) @@ -252,10 +193,10 @@ MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& docum { } -void MediaControlVolumeSliderElement::defaultEventHandler(Event* event) +void MediaControlVolumeSliderElement::defaultEventHandler(Event& event) { // Left button is 0. Rejects mouse events not from left button. - if (event->isMouseEvent() && static_cast(event)->button()) + if (is(event) && downcast(event).button()) return; if (!renderer()) @@ -263,15 +204,15 @@ void MediaControlVolumeSliderElement::defaultEventHandler(Event* event) 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 volume = value().toDouble(); if (volume != mediaController()->volume()) - mediaController()->setVolume(volume, ASSERT_NO_EXCEPTION); + mediaController()->setVolume(volume); if (m_clearMutedOnUserInteraction) mediaController()->setMuted(false); - event->setDefaultHandled(); + event.setDefaultHandled(); } bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents() diff --git a/Source/WebCore/html/shadow/MediaControlElementTypes.h b/Source/WebCore/html/shadow/MediaControlElementTypes.h index d4e4c07aa..ea05eb721 100644 --- a/Source/WebCore/html/shadow/MediaControlElementTypes.h +++ b/Source/WebCore/html/shadow/MediaControlElementTypes.h @@ -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. * @@ -27,8 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MediaControlElementTypes_h -#define MediaControlElementTypes_h +#pragma once #if ENABLE(VIDEO) @@ -36,7 +35,7 @@ #include "HTMLInputElement.h" #include "HTMLMediaElement.h" #include "MediaControllerInterface.h" -#include "RenderBlock.h" +#include "RenderObject.h" namespace WebCore { @@ -75,7 +74,7 @@ enum MediaControlElementType { }; HTMLMediaElement* parentMediaElement(Node*); -inline HTMLMediaElement* parentMediaElement(RenderObject& renderer) { return parentMediaElement(renderer.node()); } +inline HTMLMediaElement* parentMediaElement(const RenderObject& renderer) { return parentMediaElement(renderer.node()); } MediaControlElementType mediaControlElementType(Node*); @@ -88,7 +87,6 @@ public: virtual bool isShowing() const; virtual MediaControlElementType displayType() { return m_displayType; } - virtual const AtomicString& shadowPseudoId() const = 0; virtual void setMediaController(MediaControllerInterface* controller) { m_mediaController = controller; } virtual MediaControllerInterface* mediaController() const { return m_mediaController; } @@ -110,18 +108,20 @@ private: class MediaControlDivElement : public HTMLDivElement, public MediaControlElement { protected: - virtual bool isMediaControlElement() const override { return MediaControlElement::isMediaControlElement(); } explicit MediaControlDivElement(Document&, MediaControlElementType); + +private: + bool isMediaControlElement() const final { return MediaControlElement::isMediaControlElement(); } }; // ---------------------------- class MediaControlInputElement : public HTMLInputElement, public MediaControlElement { protected: - virtual bool isMediaControlElement() const override { return MediaControlElement::isMediaControlElement(); } explicit MediaControlInputElement(Document&, MediaControlElementType); private: + bool isMediaControlElement() const final { return MediaControlElement::isMediaControlElement(); } virtual void updateDisplayType() { } }; @@ -145,57 +145,46 @@ class MediaControlMuteButtonElement : public MediaControlInputElement { public: void changedMute(); - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } protected: explicit MediaControlMuteButtonElement(Document&, MediaControlElementType); - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; private: - virtual void updateDisplayType() override; + void updateDisplayType() override; }; // ---------------------------- class MediaControlSeekButtonElement : public MediaControlInputElement { public: - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } protected: explicit MediaControlSeekButtonElement(Document&, MediaControlElementType); - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; virtual bool isForwardButton() const = 0; private: - virtual void setActive(bool /*flag*/ = true, bool /*pause*/ = false) override final; - - void startTimer(); - void stopTimer(); - double nextRate() const; - void seekTimerFired(Timer&); - - enum ActionType { Nothing, Play, Pause }; - ActionType m_actionOnStop; - enum SeekType { Skip, Scan }; - SeekType m_seekType; - Timer m_seekTimer; + void setActive(bool /*flag*/ = true, bool /*pause*/ = false) final; }; // ---------------------------- class MediaControlVolumeSliderElement : public MediaControlInputElement { public: - virtual bool willRespondToMouseMoveEvents() override; - virtual bool willRespondToMouseClickEvents() override; + bool willRespondToMouseMoveEvents() override; + bool willRespondToMouseClickEvents() override; void setVolume(double); void setClearMutedOnUserInteraction(bool); protected: explicit MediaControlVolumeSliderElement(Document&); - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; private: bool m_clearMutedOnUserInteraction; @@ -204,5 +193,3 @@ private: } // namespace WebCore #endif // ENABLE(VIDEO) - -#endif // MediaControlElementTypes_h 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::create(Document& document) +Ref 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&) +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(event)->absoluteLocation(); - if (event->type() == eventNames().mousedownEvent && event->target() == this) { + if (is(event)) { + LayoutPoint location = downcast(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::create(Document& document) -{ - return adoptRef(new MediaControlPanelEnclosureElement(document)); -} - -const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const +Ref 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::create(Document& document) +Ref 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::create(Document& document) +Ref MediaControlTimelineContainerElement::create(Document& document) { - RefPtr element = adoptRef(new MediaControlTimelineContainerElement(document)); + Ref 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(*this)) { + if (element.shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId() + && element.shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId()) continue; - MediaControlTimeDisplayElement* timeDisplay = static_cast(element); + MediaControlTimeDisplayElement& timeDisplay = static_cast(element); if (hidden) - timeDisplay->hide(); + timeDisplay.hide(); else - timeDisplay->show(); + timeDisplay.show(); } } -RenderPtr MediaControlTimelineContainerElement::createElementRenderer(PassRef style) +RenderPtr MediaControlTimelineContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer(*this, std::move(style)); + return createRenderer(*this, WTFMove(style)); } // ---------------------------- @@ -342,28 +318,29 @@ RenderPtr MediaControlTimelineContainerElement::createElementRend MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document& document) : MediaControlDivElement(document, MediaVolumeSliderContainer) { + setPseudo(AtomicString("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral)); } -PassRefPtr MediaControlVolumeSliderContainerElement::create(Document& document) +Ref MediaControlVolumeSliderContainerElement::create(Document& document) { - RefPtr element = adoptRef(new MediaControlVolumeSliderContainerElement(document)); + Ref element = adoptRef(*new MediaControlVolumeSliderContainerElement(document)); element->hide(); - return element.release(); + return element; } -RenderPtr MediaControlVolumeSliderContainerElement::createElementRenderer(PassRef style) +RenderPtr MediaControlVolumeSliderContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer(*this, std::move(style)); + return createRenderer(*this, WTFMove(style)); } -void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event) +void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event& event) { - if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent) + if (!is(event) || event.type() != eventNames().mouseoutEvent) return; // Poor man's mouseleave event detection. - MouseEvent* mouseEvent = static_cast(event); - EventTarget* relatedTarget = mouseEvent->relatedTarget(); + MouseEvent& mouseEvent = downcast(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::create(Document& document) +Ref MediaControlStatusDisplayElement::create(Document& document) { - RefPtr element = adoptRef(new MediaControlStatusDisplayElement(document)); + Ref 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::create(Document& document, MediaControls* controls) +Ref MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls)); + Ref 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::create(Document& document) +Ref MediaControlVolumeSliderMuteButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlPlayButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlPlayButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlOverlayPlayButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlOverlayPlayButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlSeekForwardButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlSeekForwardButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlSeekBackButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlSeekBackButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlRewindButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlRewindButtonElement(document)); + Ref 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(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::create(Document& document) +Ref MediaControlReturnToRealtimeButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlReturnToRealtimeButtonElement(document)); + Ref 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::create(Document& document, MediaControls* controls) +Ref MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls)); + Ref 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::create(Document& document) +Ref MediaControlClosedCaptionsContainerElement::create(Document& document) { - RefPtr element = adoptRef(new MediaControlClosedCaptionsContainerElement(document)); - element->setAttribute(dirAttr, "auto"); + Ref 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::create(Document& document, MediaControls* controls) +Ref MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr element = adoptRef(new MediaControlClosedCaptionsTrackListElement(document, controls)); - return element.release(); + Ref 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(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; - MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(toElement(target)); + MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(downcast(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 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 offMenuItem; bool trackMenuItemSelected = false; - for (unsigned i = 0, length = m_menuItems.size(); i < length; ++i) { - RefPtr trackItem = m_menuItems[i]; - + for (auto& trackItem : m_menuItems) { RefPtr 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> tracksForMenu = captionPreferences->sortedTrackListForMenu(trackList); + auto& captionPreferences = document().page()->group().captionPreferences(); + Vector> tracksForMenu = captionPreferences.sortedTrackListForMenu(&trackList); - RefPtr captionsHeader = document().createElement(h3Tag, ASSERT_NO_EXCEPTION); + auto captionsHeader = HTMLHeadingElement::create(h3Tag, document()); captionsHeader->appendChild(document().createTextNode(textTrackSubtitlesText())); appendChild(captionsHeader); - RefPtr captionsMenuList = document().createElement(ulTag, ASSERT_NO_EXCEPTION); + auto captionsMenuList = HTMLUListElement::create(document()); - for (unsigned i = 0, length = tracksForMenu.size(); i < length; ++i) { - RefPtr textTrack = tracksForMenu[i]; - RefPtr 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::create(Document& document, MediaControls* controls) +Ref MediaControlTimelineElement::create(Document& document, MediaControls* controls) { ASSERT(controls); - RefPtr timeline = adoptRef(new MediaControlTimelineElement(document, controls)); + Ref 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(event)->button()) + if (is(event) && downcast(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(*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::create(Document& document) +Ref MediaControlPanelVolumeSliderElement::create(Document& document) { - RefPtr slider = adoptRef(new MediaControlPanelVolumeSliderElement(document)); + Ref 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::create(Document& document) +Ref MediaControlFullscreenVolumeSliderElement::create(Document& document) { - RefPtr slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(document)); + Ref 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::create(Document& document) +Ref MediaControlFullscreenButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlFullscreenButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlFullscreenVolumeMinButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(document)); + Ref 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::create(Document& document) +Ref MediaControlFullscreenVolumeMaxButtonElement::create(Document& document) { - RefPtr button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(document)); + Ref 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::create(Document& document) +Ref 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 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::create(Document& document) +Ref 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 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::create(Document& document) +Ref MediaControlTextTrackContainerElement::create(Document& document) { - RefPtr element = adoptRef(new MediaControlTextTrackContainerElement(document)); + auto element = adoptRef(*new MediaControlTextTrackContainerElement(document)); element->hide(); - return element.release(); + return element; } -RenderPtr MediaControlTextTrackContainerElement::createElementRenderer(PassRef style) +RenderPtr MediaControlTextTrackContainerElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer(*this, std::move(style)); + return createRenderer(*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(*mediaElement); // 3. Let output be an empty list of absolutely positioned CSS block boxes. Vector> 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 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 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 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&) +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(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(*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 MediaControlTextTrackContainerElement::createTextTrackRepresentationImage() +RefPtr MediaControlTextTrackContainerElement::createTextTrackRepresentationImage() { if (!hasChildNodes()) return nullptr; @@ -1409,14 +1350,14 @@ PassRefPtr 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(*renderer).layer(); float deviceScaleFactor = 1; if (Page* page = document().page()) @@ -1424,17 +1365,20 @@ PassRefPtr MediaControlTextTrackContainerElement::createTextTrackRepresen IntRect paintingRect = IntRect(IntPoint(), layer->size()); - std::unique_ptr buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB)); + // FIXME (149422): This buffer should not be unconditionally unaccelerated. + std::unique_ptr 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(); } diff --git a/Source/WebCore/html/shadow/MediaControlElements.h b/Source/WebCore/html/shadow/MediaControlElements.h index 6f5205d4b..29642f0ae 100644 --- a/Source/WebCore/html/shadow/MediaControlElements.h +++ b/Source/WebCore/html/shadow/MediaControlElements.h @@ -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. * @@ -27,10 +27,10 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MediaControlElements_h -#define MediaControlElements_h +#pragma once #if ENABLE(VIDEO) + #include "MediaControlElementTypes.h" #include "TextTrackRepresentation.h" @@ -40,7 +40,7 @@ namespace WebCore { class MediaControlPanelElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); void setCanBeDragged(bool); void setIsDisplayed(bool); @@ -50,15 +50,14 @@ public: void makeTransparent(); #if !PLATFORM(IOS) - virtual bool willRespondToMouseMoveEvents() override { return true; } - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseMoveEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: explicit MediaControlPanelElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; void startDrag(const LayoutPoint& eventLocation); void continueDrag(const LayoutPoint& eventLocation); @@ -66,7 +65,7 @@ private: void startTimer(); void stopTimer(); - void transitionTimerFired(Timer&); + void transitionTimerFired(); void setPosition(const LayoutPoint&); @@ -77,76 +76,71 @@ private: LayoutPoint m_lastDragEventLocation; LayoutPoint m_cumulativeDragOffset; - Timer m_transitionTimer; + Timer m_transitionTimer; }; // ---------------------------- class MediaControlPanelEnclosureElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlPanelEnclosureElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- class MediaControlOverlayEnclosureElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlOverlayEnclosureElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- -class MediaControlTimelineContainerElement : public MediaControlDivElement { +class MediaControlTimelineContainerElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); void setTimeDisplaysHidden(bool); private: explicit MediaControlTimelineContainerElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual RenderPtr createElementRenderer(PassRef) override; + RenderPtr createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; }; // ---------------------------- -class MediaControlVolumeSliderContainerElement : public MediaControlDivElement { +class MediaControlVolumeSliderContainerElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseMoveEvents() override { return true; } + bool willRespondToMouseMoveEvents() override { return true; } #endif private: explicit MediaControlVolumeSliderContainerElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; - virtual RenderPtr createElementRenderer(PassRef) override; + RenderPtr createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; }; // ---------------------------- -class MediaControlStatusDisplayElement : public MediaControlDivElement { +class MediaControlStatusDisplayElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); void update(); private: explicit MediaControlStatusDisplayElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; enum StateBeingDisplayed { Nothing, Loading, LiveBroadcast }; StateBeingDisplayed m_stateBeingDisplayed; @@ -156,17 +150,16 @@ private: class MediaControlPanelMuteButtonElement final : public MediaControlMuteButtonElement { public: - static PassRefPtr create(Document&, MediaControls*); + static Ref create(Document&, MediaControls*); #if !PLATFORM(IOS) - virtual bool willRespondToMouseMoveEvents() override { return true; } + bool willRespondToMouseMoveEvents() override { return true; } #endif private: explicit MediaControlPanelMuteButtonElement(Document&, MediaControls*); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; MediaControls* m_controls; }; @@ -175,11 +168,10 @@ private: class MediaControlVolumeSliderMuteButtonElement final : public MediaControlMuteButtonElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlVolumeSliderMuteButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; @@ -187,115 +179,108 @@ private: class MediaControlPlayButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif - virtual void updateDisplayType() override; + void updateDisplayType() override; private: explicit MediaControlPlayButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- class MediaControlOverlayPlayButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); - virtual void updateDisplayType() override; + void updateDisplayType() override; private: explicit MediaControlOverlayPlayButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- -class MediaControlSeekForwardButtonElement : public MediaControlSeekButtonElement { +class MediaControlSeekForwardButtonElement final : public MediaControlSeekButtonElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlSeekForwardButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual bool isForwardButton() const override { return true; } + bool isForwardButton() const override { return true; } }; // ---------------------------- -class MediaControlSeekBackButtonElement : public MediaControlSeekButtonElement { +class MediaControlSeekBackButtonElement final : public MediaControlSeekButtonElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlSeekBackButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual bool isForwardButton() const override { return false; } + bool isForwardButton() const override { return false; } }; // ---------------------------- -class MediaControlRewindButtonElement : public MediaControlInputElement { +class MediaControlRewindButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: explicit MediaControlRewindButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- -class MediaControlReturnToRealtimeButtonElement : public MediaControlInputElement { +class MediaControlReturnToRealtimeButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: explicit MediaControlReturnToRealtimeButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- class MediaControlToggleClosedCaptionsButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&, MediaControls*); + static Ref create(Document&, MediaControls*); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif - virtual void updateDisplayType() override; + void updateDisplayType() override; private: explicit MediaControlToggleClosedCaptionsButtonElement(Document&, MediaControls*); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; -#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) +#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK) MediaControls* m_controls; #endif }; @@ -304,25 +289,24 @@ private: class MediaControlClosedCaptionsContainerElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: MediaControlClosedCaptionsContainerElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- class MediaControlClosedCaptionsTrackListElement final : public MediaControlDivElement { public: - static PassRefPtr create(Document&, MediaControls*); + static Ref create(Document&, MediaControls*); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif void updateDisplay(); @@ -332,8 +316,7 @@ private: void rebuildTrackListMenu(); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; typedef Vector> TrackMenuItems; TrackMenuItems m_menuItems; @@ -348,10 +331,10 @@ private: class MediaControlTimelineElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&, MediaControls*); + static Ref create(Document&, MediaControls*); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override; + bool willRespondToMouseClickEvents() override; #endif void setPosition(double); @@ -360,8 +343,7 @@ public: private: explicit MediaControlTimelineElement(Document&, MediaControls*); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; MediaControls* m_controls; }; @@ -370,73 +352,68 @@ private: class MediaControlFullscreenButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif - virtual void setIsFullscreen(bool); + void setIsFullscreen(bool); private: explicit MediaControlFullscreenButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- class MediaControlPanelVolumeSliderElement final : public MediaControlVolumeSliderElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlPanelVolumeSliderElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- -class MediaControlFullscreenVolumeSliderElement : public MediaControlVolumeSliderElement { +class MediaControlFullscreenVolumeSliderElement final : public MediaControlVolumeSliderElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlFullscreenVolumeSliderElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- -class MediaControlFullscreenVolumeMinButtonElement : public MediaControlInputElement { +class MediaControlFullscreenVolumeMinButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: explicit MediaControlFullscreenVolumeMinButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; // ---------------------------- -class MediaControlFullscreenVolumeMaxButtonElement : public MediaControlInputElement { +class MediaControlFullscreenVolumeMaxButtonElement final : public MediaControlInputElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); #if !PLATFORM(IOS) - virtual bool willRespondToMouseClickEvents() override { return true; } + bool willRespondToMouseClickEvents() override { return true; } #endif private: explicit MediaControlFullscreenVolumeMaxButtonElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; }; @@ -444,22 +421,20 @@ private: class MediaControlTimeRemainingDisplayElement final : public MediaControlTimeDisplayElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlTimeRemainingDisplayElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- class MediaControlCurrentTimeDisplayElement final : public MediaControlTimeDisplayElement { public: - static PassRefPtr create(Document&); + static Ref create(Document&); private: explicit MediaControlCurrentTimeDisplayElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; }; // ---------------------------- @@ -468,31 +443,33 @@ private: class MediaControlTextTrackContainerElement final : public MediaControlDivElement, public TextTrackRepresentationClient { public: - static PassRefPtr create(Document&); + static Ref create(Document&); void updateDisplay(); void updateSizes(bool forceUpdate = false); void enteredFullscreen(); void exitedFullscreen(); - static const AtomicString& textTrackContainerElementShadowPseudoId(); private: - void updateTimerFired(Timer&); + void updateTimerFired(); + void updateActiveCuesFontSize(); explicit MediaControlTextTrackContainerElement(Document&); - virtual const AtomicString& shadowPseudoId() const override; - virtual RenderPtr createElementRenderer(PassRef) override; + RenderPtr createElementRenderer(RenderStyle&&, const RenderTreePosition&) override; - virtual PassRefPtr createTextTrackRepresentationImage() override; - virtual void textTrackRepresentationBoundsChanged(const IntRect&) override; + RefPtr createTextTrackRepresentationImage() override; + void textTrackRepresentationBoundsChanged(const IntRect&) override; + void updateTextTrackRepresentation(); void clearTextTrackRepresentation(); - OwnPtr m_textTrackRepresentation; + void updateStyleForTextTrackRepresentation(); + std::unique_ptr m_textTrackRepresentation; - Timer m_updateTimer; + Timer m_updateTimer; IntRect m_videoDisplaySize; int m_fontSize; bool m_fontSizeIsImportant; + bool m_updateTextTrackRepresentationStyle; }; #endif @@ -500,5 +477,3 @@ private: } // namespace WebCore #endif // ENABLE(VIDEO) - -#endif // MediaControlElements_h diff --git a/Source/WebCore/html/shadow/MediaControls.cpp b/Source/WebCore/html/shadow/MediaControls.cpp index 7bfaf436c..2228f49b5 100644 --- a/Source/WebCore/html/shadow/MediaControls.cpp +++ b/Source/WebCore/html/shadow/MediaControls.cpp @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -29,7 +29,9 @@ #if ENABLE(VIDEO) #include "MediaControls.h" -#include "ExceptionCodePlaceholder.h" +#include "EventNames.h" +#include "Page.h" +#include "RenderElement.h" #include "Settings.h" namespace WebCore { @@ -48,10 +50,11 @@ MediaControls::MediaControls(Document& document) , m_volumeSlider(0) , m_toggleClosedCaptionsButton(0) , m_fullScreenButton(0) - , m_hideFullscreenControlsTimer(this, &MediaControls::hideFullscreenControlsTimerFired) + , m_hideFullscreenControlsTimer(*this, &MediaControls::hideFullscreenControlsTimerFired) , m_isFullscreen(false) , m_isMouseOverControls(false) { + setPseudo(AtomicString("-webkit-media-controls", AtomicString::ConstructFromLiteral)); } void MediaControls::setMediaController(MediaControllerInterface* controller) @@ -115,7 +118,7 @@ void MediaControls::reset() refreshClosedCaptionsButtonVisibility(); if (m_fullScreenButton) { - if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo()) + if (m_mediaController->supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenModeStandard) && m_mediaController->hasVideo()) m_fullScreenButton->show(); else m_fullScreenButton->hide(); @@ -220,7 +223,7 @@ void MediaControls::updateCurrentTimeDisplay() if (!page) return; - m_currentTimeDisplay->setInnerText(page->theme().formatMediaControlsTime(now), IGNORE_EXCEPTION); + m_currentTimeDisplay->setInnerText(page->theme().formatMediaControlsTime(now)); m_currentTimeDisplay->setCurrentValue(now); } @@ -293,11 +296,11 @@ void MediaControls::exitedFullscreen() #endif } -void MediaControls::defaultEventHandler(Event* event) +void MediaControls::defaultEventHandler(Event& event) { HTMLDivElement::defaultEventHandler(event); - if (event->type() == eventNames().mouseoverEvent) { + if (event.type() == eventNames().mouseoverEvent) { if (!containsRelatedTarget(event)) { m_isMouseOverControls = true; if (!m_mediaController->canPlay()) { @@ -309,7 +312,7 @@ void MediaControls::defaultEventHandler(Event* event) return; } - if (event->type() == eventNames().mouseoutEvent) { + if (event.type() == eventNames().mouseoutEvent) { if (!containsRelatedTarget(event)) { m_isMouseOverControls = false; stopHideFullscreenControlsTimer(); @@ -317,7 +320,7 @@ void MediaControls::defaultEventHandler(Event* event) return; } - if (event->type() == eventNames().mousemoveEvent) { + if (event.type() == eventNames().mousemoveEvent) { if (m_isFullscreen) { // When we get a mouse move in fullscreen mode, show the media controls, and start a timer // that will hide the media controls after a 3 seconds without a mouse move. @@ -329,7 +332,7 @@ void MediaControls::defaultEventHandler(Event* event) } } -void MediaControls::hideFullscreenControlsTimerFired(Timer&) +void MediaControls::hideFullscreenControlsTimerFired() { if (m_mediaController->paused()) return; @@ -363,36 +366,31 @@ void MediaControls::stopHideFullscreenControlsTimer() m_hideFullscreenControlsTimer.stop(); } -const AtomicString& MediaControls::shadowPseudoId() const +bool MediaControls::containsRelatedTarget(Event& event) { - DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls")); - return id; -} - -bool MediaControls::containsRelatedTarget(Event* event) -{ - if (!event->isMouseEvent()) + if (!is(event)) return false; - EventTarget* relatedTarget = static_cast(event)->relatedTarget(); + EventTarget* relatedTarget = downcast(event).relatedTarget(); if (!relatedTarget) return false; return contains(relatedTarget->toNode()); } #if ENABLE(VIDEO_TRACK) + void MediaControls::createTextTrackDisplay() { if (m_textDisplayContainer) return; - RefPtr textDisplayContainer = MediaControlTextTrackContainerElement::create(document()); - m_textDisplayContainer = textDisplayContainer.get(); + auto textDisplayContainer = MediaControlTextTrackContainerElement::create(document()); + m_textDisplayContainer = textDisplayContainer.ptr(); if (m_mediaController) m_textDisplayContainer->setMediaController(m_mediaController); // Insert it before the first controller element so it always displays behind the controls. - insertBefore(textDisplayContainer.release(), m_panel, IGNORE_EXCEPTION); + insertBefore(textDisplayContainer, m_panel); } void MediaControls::showTextTrackDisplay() @@ -423,6 +421,7 @@ void MediaControls::textTrackPreferencesChanged() if (m_textDisplayContainer) m_textDisplayContainer->updateSizes(true); } + #endif void MediaControls::setSliderVolume() diff --git a/Source/WebCore/html/shadow/MediaControls.h b/Source/WebCore/html/shadow/MediaControls.h index 47124cfef..72c1ec61d 100644 --- a/Source/WebCore/html/shadow/MediaControls.h +++ b/Source/WebCore/html/shadow/MediaControls.h @@ -11,10 +11,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -24,8 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MediaControls_h -#define MediaControls_h +#pragma once #if ENABLE(VIDEO) @@ -33,7 +32,6 @@ #include "HTMLDivElement.h" #include "MediaControlElements.h" #include "MouseEvent.h" -#include "Page.h" #include "RenderTheme.h" #include "Text.h" #include @@ -46,7 +44,6 @@ namespace WebCore { class Document; class Event; -class Page; class MediaPlayer; class RenderBox; @@ -59,7 +56,7 @@ class MediaControls : public HTMLDivElement { // This function is to be implemented in your port-specific media // controls implementation since it will return a child instance. - static PassRefPtr create(Document&); + static RefPtr tryCreate(Document&); virtual void setMediaController(MediaControllerInterface*); @@ -94,10 +91,10 @@ class MediaControls : public HTMLDivElement { virtual void exitedFullscreen(); #if !PLATFORM(IOS) - virtual bool willRespondToMouseMoveEvents() override { return true; } + bool willRespondToMouseMoveEvents() override { return true; } #endif - virtual void hideFullscreenControlsTimerFired(Timer&); + virtual void hideFullscreenControlsTimerFired(); virtual void startHideFullscreenControlsTimer(); virtual void stopHideFullscreenControlsTimer(); @@ -112,9 +109,9 @@ class MediaControls : public HTMLDivElement { protected: explicit MediaControls(Document&); - virtual void defaultEventHandler(Event*) override; + void defaultEventHandler(Event&) override; - virtual bool containsRelatedTarget(Event*); + virtual bool containsRelatedTarget(Event&); void setSliderVolume(); @@ -137,14 +134,12 @@ protected: MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton; MediaControlFullscreenButtonElement* m_fullScreenButton; - Timer m_hideFullscreenControlsTimer; + Timer m_hideFullscreenControlsTimer; bool m_isFullscreen; bool m_isMouseOverControls; private: - virtual bool isMediaControls() const override { return true; } - - virtual const AtomicString& shadowPseudoId() const override; + bool isMediaControls() const final { return true; } }; inline MediaControls* toMediaControls(Node* node) @@ -156,8 +151,6 @@ inline MediaControls* toMediaControls(Node* node) // This will catch anyone doing an unneccessary cast. void toMediaControls(const MediaControls*); -} +} // namespace WebCore -#endif - -#endif +#endif // ENABLE(VIDEO) diff --git a/Source/WebCore/html/shadow/MediaControlsApple.cpp b/Source/WebCore/html/shadow/MediaControlsApple.cpp new file mode 100644 index 000000000..61092524c --- /dev/null +++ b/Source/WebCore/html/shadow/MediaControlsApple.cpp @@ -0,0 +1,568 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if ENABLE(VIDEO) +#include "MediaControlsApple.h" + +#include "CSSValueKeywords.h" +#include "EventNames.h" +#include "Page.h" +#include "WheelEvent.h" + +namespace WebCore { + +MediaControlsApple::MediaControlsApple(Document& document) + : MediaControls(document) +{ +} + +RefPtr MediaControls::tryCreate(Document& document) +{ + return MediaControlsApple::tryCreateControls(document); +} + +RefPtr MediaControlsApple::tryCreateControls(Document& document) +{ + if (!document.page()) + return nullptr; + + auto controls = adoptRef(*new MediaControlsApple(document)); + + auto panel = MediaControlPanelElement::create(document); + + auto rewindButton = MediaControlRewindButtonElement::create(document); + controls->m_rewindButton = rewindButton.ptr(); + if (panel->appendChild(rewindButton).hasException()) + return nullptr; + + auto playButton = MediaControlPlayButtonElement::create(document); + controls->m_playButton = playButton.ptr(); + if (panel->appendChild(playButton).hasException()) + return nullptr; + + auto returnToRealtimeButton = MediaControlReturnToRealtimeButtonElement::create(document); + controls->m_returnToRealTimeButton = returnToRealtimeButton.ptr(); + if (panel->appendChild(returnToRealtimeButton).hasException()) + return nullptr; + + if (document.page()->theme().usesMediaControlStatusDisplay()) { + auto statusDisplay = MediaControlStatusDisplayElement::create(document); + controls->m_statusDisplay = statusDisplay.ptr(); + if (panel->appendChild(statusDisplay).hasException()) + return nullptr; + } + + auto timelineContainer = MediaControlTimelineContainerElement::create(document); + + auto currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document); + controls->m_currentTimeDisplay = currentTimeDisplay.ptr(); + if (timelineContainer->appendChild(currentTimeDisplay).hasException()) + return nullptr; + + auto timeline = MediaControlTimelineElement::create(document, controls.ptr()); + controls->m_timeline = timeline.ptr(); + if (timelineContainer->appendChild(timeline).hasException()) + return nullptr; + + auto timeRemainingDisplay = MediaControlTimeRemainingDisplayElement::create(document); + controls->m_timeRemainingDisplay = timeRemainingDisplay.ptr(); + if (timelineContainer->appendChild(timeRemainingDisplay).hasException()) + return nullptr; + + controls->m_timelineContainer = timelineContainer.ptr(); + if (panel->appendChild(timelineContainer).hasException()) + return nullptr; + + // FIXME: Only create when needed + auto seekBackButton = MediaControlSeekBackButtonElement::create(document); + controls->m_seekBackButton = seekBackButton.ptr(); + if (panel->appendChild(seekBackButton).hasException()) + return nullptr; + + // FIXME: Only create when needed + auto seekForwardButton = MediaControlSeekForwardButtonElement::create(document); + controls->m_seekForwardButton = seekForwardButton.ptr(); + if (panel->appendChild(seekForwardButton).hasException()) + return nullptr; + + if (document.page()->theme().supportsClosedCaptioning()) { + auto closedCaptionsContainer = MediaControlClosedCaptionsContainerElement::create(document); + + auto closedCaptionsTrackList = MediaControlClosedCaptionsTrackListElement::create(document, controls.ptr()); + controls->m_closedCaptionsTrackList = closedCaptionsTrackList.ptr(); + if (closedCaptionsContainer->appendChild(closedCaptionsTrackList).hasException()) + return nullptr; + + auto toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, controls.ptr()); + controls->m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.ptr(); + if (panel->appendChild(toggleClosedCaptionsButton).hasException()) + return nullptr; + + controls->m_closedCaptionsContainer = closedCaptionsContainer.ptr(); + if (controls->appendChild(closedCaptionsContainer).hasException()) + return nullptr; + } + + // FIXME: Only create when needed + auto fullScreenButton = MediaControlFullscreenButtonElement::create(document); + controls->m_fullScreenButton = fullScreenButton.ptr(); + panel->appendChild(fullScreenButton); + + // The mute button and the slider element should be in the same div. + auto panelVolumeControlContainer = HTMLDivElement::create(document); + + if (document.page()->theme().usesMediaControlVolumeSlider()) { + auto volumeSliderContainer = MediaControlVolumeSliderContainerElement::create(document); + + auto slider = MediaControlPanelVolumeSliderElement::create(document); + controls->m_volumeSlider = slider.ptr(); + if (volumeSliderContainer->appendChild(slider).hasException()) + return nullptr; + + // This is a duplicate mute button, which is visible in some ports at the bottom of the volume bar. + // It's important only when the volume bar is displayed below the controls. + auto volumeSliderMuteButton = MediaControlVolumeSliderMuteButtonElement::create(document); + controls->m_volumeSliderMuteButton = volumeSliderMuteButton.ptr(); + if (volumeSliderContainer->appendChild(volumeSliderMuteButton).hasException()) + return nullptr; + + controls->m_volumeSliderContainer = volumeSliderContainer.ptr(); + if (panelVolumeControlContainer->appendChild(volumeSliderContainer).hasException()) + return nullptr; + } + + auto panelMuteButton = MediaControlPanelMuteButtonElement::create(document, controls.ptr()); + controls->m_panelMuteButton = panelMuteButton.ptr(); + if (panelVolumeControlContainer->appendChild(panelMuteButton).hasException()) + return nullptr; + + if (panel->appendChild(panelVolumeControlContainer).hasException()) + return nullptr; + + // FIXME: Only create when needed + auto fullScreenMinVolumeButton = MediaControlFullscreenVolumeMinButtonElement::create(document); + controls->m_fullScreenMinVolumeButton = fullScreenMinVolumeButton.ptr(); + if (panel->appendChild(fullScreenMinVolumeButton).hasException()) + return nullptr; + + auto fullScreenVolumeSlider = MediaControlFullscreenVolumeSliderElement::create(document); + controls->m_fullScreenVolumeSlider = fullScreenVolumeSlider.ptr(); + if (panel->appendChild(fullScreenVolumeSlider).hasException()) + return nullptr; + + auto fullScreenMaxVolumeButton = MediaControlFullscreenVolumeMaxButtonElement::create(document); + controls->m_fullScreenMaxVolumeButton = fullScreenMaxVolumeButton.ptr(); + if (panel->appendChild(fullScreenMaxVolumeButton).hasException()) + return nullptr; + + controls->m_panel = panel.ptr(); + if (controls->appendChild(panel).hasException()) + return nullptr; + + return WTFMove(controls); +} + +void MediaControlsApple::setMediaController(MediaControllerInterface* controller) +{ + if (m_mediaController == controller) + return; + + MediaControls::setMediaController(controller); + + if (m_rewindButton) + m_rewindButton->setMediaController(controller); + if (m_returnToRealTimeButton) + m_returnToRealTimeButton->setMediaController(controller); + if (m_statusDisplay) + m_statusDisplay->setMediaController(controller); + if (m_timeRemainingDisplay) + m_timeRemainingDisplay->setMediaController(controller); + if (m_timelineContainer) + m_timelineContainer->setMediaController(controller); + if (m_seekBackButton) + m_seekBackButton->setMediaController(controller); + if (m_seekForwardButton) + m_seekForwardButton->setMediaController(controller); + if (m_volumeSliderMuteButton) + m_volumeSliderMuteButton->setMediaController(controller); + if (m_volumeSliderContainer) + m_volumeSliderContainer->setMediaController(controller); + if (m_fullScreenMinVolumeButton) + m_fullScreenMinVolumeButton->setMediaController(controller); + if (m_fullScreenVolumeSlider) + m_fullScreenVolumeSlider->setMediaController(controller); + if (m_fullScreenMaxVolumeButton) + m_fullScreenMaxVolumeButton->setMediaController(controller); + if (m_closedCaptionsTrackList) + m_closedCaptionsTrackList->setMediaController(controller); + if (m_closedCaptionsContainer) + m_closedCaptionsContainer->setMediaController(controller); +} + +void MediaControlsApple::defaultEventHandler(Event& event) +{ + if (event.type() == eventNames().clickEvent) { + if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing()) { + hideClosedCaptionTrackList(); + event.setDefaultHandled(); + } + } + + MediaControls::defaultEventHandler(event); +} + +void MediaControlsApple::hide() +{ + MediaControls::hide(); + m_volumeSliderContainer->hide(); + if (m_closedCaptionsContainer) + hideClosedCaptionTrackList(); +} + +void MediaControlsApple::makeTransparent() +{ + MediaControls::makeTransparent(); + m_volumeSliderContainer->hide(); + if (m_closedCaptionsContainer) + hideClosedCaptionTrackList(); +} + +void MediaControlsApple::changedClosedCaptionsVisibility() +{ + MediaControls::changedClosedCaptionsVisibility(); + if (m_closedCaptionsContainer && m_closedCaptionsContainer->isShowing()) + hideClosedCaptionTrackList(); + +} + +void MediaControlsApple::reset() +{ + Page* page = document().page(); + if (!page) + return; + + updateStatusDisplay(); + + if (m_mediaController->supportsFullscreen(HTMLMediaElementEnums::VideoFullscreenModeStandard)) + m_fullScreenButton->show(); + else + m_fullScreenButton->hide(); + + double duration = m_mediaController->duration(); + if (std::isfinite(duration) || page->theme().hasOwnDisabledStateHandlingFor(MediaSliderPart)) { + m_timeline->setDuration(duration); + m_timelineContainer->show(); + m_timeline->setPosition(m_mediaController->currentTime()); + updateCurrentTimeDisplay(); + } else + m_timelineContainer->hide(); + + if (m_mediaController->hasAudio() || page->theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart)) + m_panelMuteButton->show(); + else + m_panelMuteButton->hide(); + + if (m_volumeSlider) + setSliderVolume(); + + if (m_toggleClosedCaptionsButton) { + if (m_mediaController->hasClosedCaptions()) + m_toggleClosedCaptionsButton->show(); + else + m_toggleClosedCaptionsButton->hide(); + } + + if (m_playButton) + m_playButton->updateDisplayType(); + +#if ENABLE(FULLSCREEN_API) + if (m_fullScreenVolumeSlider) + setFullscreenSliderVolume(); + + if (m_isFullscreen) { + if (m_mediaController->isLiveStream()) { + m_seekBackButton->hide(); + m_seekForwardButton->hide(); + m_rewindButton->show(); + m_returnToRealTimeButton->show(); + } else { + m_seekBackButton->show(); + m_seekForwardButton->show(); + m_rewindButton->hide(); + m_returnToRealTimeButton->hide(); + } + } else +#endif + if (!m_mediaController->isLiveStream()) { + m_returnToRealTimeButton->hide(); + m_rewindButton->show(); + } else { + m_returnToRealTimeButton->show(); + m_rewindButton->hide(); + } + + makeOpaque(); +} + +void MediaControlsApple::updateCurrentTimeDisplay() +{ + double now = m_mediaController->currentTime(); + double duration = m_mediaController->duration(); + + Page* page = document().page(); + if (!page) + return; + + // Allow the theme to format the time. + m_currentTimeDisplay->setInnerText(page->theme().formatMediaControlsCurrentTime(now, duration)); + m_currentTimeDisplay->setCurrentValue(now); + m_timeRemainingDisplay->setInnerText(page->theme().formatMediaControlsRemainingTime(now, duration)); + m_timeRemainingDisplay->setCurrentValue(now - duration); +} + +void MediaControlsApple::reportedError() +{ + Page* page = document().page(); + if (!page) + return; + + if (!page->theme().hasOwnDisabledStateHandlingFor(MediaSliderPart)) + m_timelineContainer->hide(); + + if (!page->theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart)) + m_panelMuteButton->hide(); + + m_fullScreenButton->hide(); + + if (m_volumeSliderContainer) + m_volumeSliderContainer->hide(); + if (m_toggleClosedCaptionsButton && !page->theme().hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart)) + m_toggleClosedCaptionsButton->hide(); + if (m_closedCaptionsContainer) + hideClosedCaptionTrackList(); +} + +void MediaControlsApple::updateStatusDisplay() +{ + if (m_statusDisplay) + m_statusDisplay->update(); +} + +void MediaControlsApple::loadedMetadata() +{ + if (m_statusDisplay && !m_mediaController->isLiveStream()) + m_statusDisplay->hide(); + + MediaControls::loadedMetadata(); +} + +void MediaControlsApple::changedMute() +{ + MediaControls::changedMute(); + + if (m_volumeSliderMuteButton) + m_volumeSliderMuteButton->changedMute(); +} + +void MediaControlsApple::changedVolume() +{ + MediaControls::changedVolume(); + + if (m_fullScreenVolumeSlider) + setFullscreenSliderVolume(); +} + +void MediaControlsApple::enteredFullscreen() +{ + MediaControls::enteredFullscreen(); + m_panel->setCanBeDragged(true); + + if (m_mediaController->isLiveStream()) { + m_seekBackButton->hide(); + m_seekForwardButton->hide(); + m_rewindButton->show(); + m_returnToRealTimeButton->show(); + } else { + m_seekBackButton->show(); + m_seekForwardButton->show(); + m_rewindButton->hide(); + m_returnToRealTimeButton->hide(); + } +} + +void MediaControlsApple::exitedFullscreen() +{ + m_rewindButton->show(); + m_seekBackButton->show(); + m_seekForwardButton->show(); + m_returnToRealTimeButton->show(); + + m_panel->setCanBeDragged(false); + + // We will keep using the panel, but we want it to go back to the standard position. + // This will matter right away because we use the panel even when not fullscreen. + // And if we reenter fullscreen we also want the panel in the standard position. + m_panel->resetPosition(); + + MediaControls::exitedFullscreen(); +} + +void MediaControlsApple::showVolumeSlider() +{ + if (!m_mediaController->hasAudio()) + return; + + if (m_volumeSliderContainer) + m_volumeSliderContainer->show(); +} + +void MediaControlsApple::toggleClosedCaptionTrackList() +{ + if (!m_mediaController->hasClosedCaptions()) + return; + + if (m_closedCaptionsContainer) { + if (m_closedCaptionsContainer->isShowing()) + hideClosedCaptionTrackList(); + else { + if (m_closedCaptionsTrackList) + m_closedCaptionsTrackList->updateDisplay(); + showClosedCaptionTrackList(); + } + } +} + +void MediaControlsApple::showClosedCaptionTrackList() +{ + if (!m_closedCaptionsContainer || m_closedCaptionsContainer->isShowing()) + return; + + m_closedCaptionsContainer->show(); + + // Ensure the controls panel does not receive any events while the captions + // track list is visible as all events now need to be captured by the + // track list. + m_panel->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone); + + EventListener& listener = eventListener(); + m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, listener, true); + + // Track click events in the capture phase at two levels, first at the document level + // such that a click outside of the