2 * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "core/html/HTMLSourceElement.h"
29 #include "core/HTMLNames.h"
30 #include "core/css/MediaList.h"
31 #include "core/css/MediaQueryList.h"
32 #include "core/css/MediaQueryMatcher.h"
33 #include "core/dom/Document.h"
34 #include "core/events/Event.h"
35 #include "core/events/EventSender.h"
36 #include "core/html/HTMLMediaElement.h"
37 #include "core/html/HTMLPictureElement.h"
38 #include "platform/Logging.h"
42 using namespace HTMLNames;
44 static SourceEventSender& sourceErrorEventSender()
46 DEFINE_STATIC_LOCAL(SourceEventSender, sharedErrorEventSender, (EventTypeNames::error));
47 return sharedErrorEventSender;
50 class HTMLSourceElement::Listener final : public MediaQueryListListener {
52 explicit Listener(HTMLSourceElement* element) : m_element(element) { }
53 virtual void notifyMediaQueryChanged() override
56 m_element->notifyMediaQueryChanged();
59 void clearElement() { m_element = nullptr; }
60 virtual void trace(Visitor* visitor) override
62 visitor->trace(m_element);
63 MediaQueryListListener::trace(visitor);
66 RawPtrWillBeMember<HTMLSourceElement> m_element;
69 inline HTMLSourceElement::HTMLSourceElement(Document& document)
70 : HTMLElement(sourceTag, document)
71 , m_listener(adoptRefWillBeNoop(new Listener(this)))
73 WTF_LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
76 DEFINE_NODE_FACTORY(HTMLSourceElement)
78 HTMLSourceElement::~HTMLSourceElement()
80 sourceErrorEventSender().cancelEvent(this);
82 m_listener->clearElement();
86 Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode* insertionPoint)
88 HTMLElement::insertedInto(insertionPoint);
89 Element* parent = parentElement();
90 if (isHTMLMediaElement(parent))
91 toHTMLMediaElement(parent)->sourceWasAdded(this);
92 if (isHTMLPictureElement(parent))
93 toHTMLPictureElement(parent)->sourceOrMediaChanged();
97 void HTMLSourceElement::removedFrom(ContainerNode* removalRoot)
99 Element* parent = parentElement();
100 if (!parent && removalRoot->isElementNode())
101 parent = toElement(removalRoot);
102 if (isHTMLMediaElement(parent))
103 toHTMLMediaElement(parent)->sourceWasRemoved(this);
104 if (isHTMLPictureElement(parent))
105 toHTMLPictureElement(parent)->sourceOrMediaChanged();
106 HTMLElement::removedFrom(removalRoot);
109 void HTMLSourceElement::setSrc(const String& url)
111 setAttribute(srcAttr, AtomicString(url));
114 const AtomicString& HTMLSourceElement::type() const
116 return getAttribute(typeAttr);
119 void HTMLSourceElement::setType(const AtomicString& type)
121 setAttribute(typeAttr, type);
124 void HTMLSourceElement::scheduleErrorEvent()
126 WTF_LOG(Media, "HTMLSourceElement::scheduleErrorEvent - %p", this);
127 sourceErrorEventSender().dispatchEventSoon(this);
130 void HTMLSourceElement::cancelPendingErrorEvent()
132 WTF_LOG(Media, "HTMLSourceElement::cancelPendingErrorEvent - %p", this);
133 sourceErrorEventSender().cancelEvent(this);
136 void HTMLSourceElement::dispatchPendingEvent(SourceEventSender* eventSender)
138 ASSERT_UNUSED(eventSender, eventSender == &sourceErrorEventSender());
139 WTF_LOG(Media, "HTMLSourceElement::dispatchPendingEvent - %p", this);
140 dispatchEvent(Event::createCancelable(EventTypeNames::error));
143 bool HTMLSourceElement::mediaQueryMatches() const
145 if (!m_mediaQueryList)
148 return m_mediaQueryList->matches();
151 bool HTMLSourceElement::isURLAttribute(const Attribute& attribute) const
153 return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
156 void HTMLSourceElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
158 HTMLElement::parseAttribute(name, value);
159 if (name == mediaAttr) {
160 if (m_mediaQueryList)
161 m_mediaQueryList->removeListener(m_listener);
162 RefPtrWillBeRawPtr<MediaQuerySet> set = MediaQuerySet::create(value);
163 m_mediaQueryList = MediaQueryList::create(&document(), &document().mediaQueryMatcher(), set.release());
164 m_mediaQueryList->addListener(m_listener);
166 if (name == srcsetAttr || name == sizesAttr || name == mediaAttr || name == typeAttr) {
167 Element* parent = parentElement();
168 if (isHTMLPictureElement(parent))
169 toHTMLPictureElement(parent)->sourceOrMediaChanged();
173 void HTMLSourceElement::notifyMediaQueryChanged()
175 Element* parent = parentElement();
176 if (isHTMLPictureElement(parent))
177 toHTMLPictureElement(parent)->sourceOrMediaChanged();
180 void HTMLSourceElement::trace(Visitor* visitor)
182 visitor->trace(m_mediaQueryList);
183 visitor->trace(m_listener);
184 HTMLElement::trace(visitor);