Home | History | Annotate | Download | only in html
      1 /*
      2  * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      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.
     12  *
     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.
     24  */
     25 
     26 #include "config.h"
     27 #include "core/html/HTMLSourceElement.h"
     28 
     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"
     39 
     40 namespace blink {
     41 
     42 using namespace HTMLNames;
     43 
     44 static SourceEventSender& sourceErrorEventSender()
     45 {
     46     DEFINE_STATIC_LOCAL(SourceEventSender, sharedErrorEventSender, (EventTypeNames::error));
     47     return sharedErrorEventSender;
     48 }
     49 
     50 class HTMLSourceElement::Listener FINAL : public MediaQueryListListener {
     51 public:
     52     explicit Listener(HTMLSourceElement* element) : m_element(element) { }
     53     virtual void notifyMediaQueryChanged() OVERRIDE
     54     {
     55         if (m_element)
     56             m_element->notifyMediaQueryChanged();
     57     }
     58 
     59     void clearElement() { m_element = nullptr; }
     60     virtual void trace(Visitor* visitor) OVERRIDE
     61     {
     62         visitor->trace(m_element);
     63         MediaQueryListListener::trace(visitor);
     64     }
     65 private:
     66     RawPtrWillBeMember<HTMLSourceElement> m_element;
     67 };
     68 
     69 inline HTMLSourceElement::HTMLSourceElement(Document& document)
     70     : HTMLElement(sourceTag, document)
     71     , m_listener(adoptRefWillBeNoop(new Listener(this)))
     72 {
     73     WTF_LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
     74 }
     75 
     76 DEFINE_NODE_FACTORY(HTMLSourceElement)
     77 
     78 HTMLSourceElement::~HTMLSourceElement()
     79 {
     80     sourceErrorEventSender().cancelEvent(this);
     81 #if !ENABLE(OILPAN)
     82     m_listener->clearElement();
     83 #endif
     84 }
     85 
     86 Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode* insertionPoint)
     87 {
     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();
     94     return InsertionDone;
     95 }
     96 
     97 void HTMLSourceElement::removedFrom(ContainerNode* removalRoot)
     98 {
     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);
    107 }
    108 
    109 void HTMLSourceElement::setSrc(const String& url)
    110 {
    111     setAttribute(srcAttr, AtomicString(url));
    112 }
    113 
    114 const AtomicString& HTMLSourceElement::type() const
    115 {
    116     return getAttribute(typeAttr);
    117 }
    118 
    119 void HTMLSourceElement::setType(const AtomicString& type)
    120 {
    121     setAttribute(typeAttr, type);
    122 }
    123 
    124 void HTMLSourceElement::scheduleErrorEvent()
    125 {
    126     WTF_LOG(Media, "HTMLSourceElement::scheduleErrorEvent - %p", this);
    127     sourceErrorEventSender().dispatchEventSoon(this);
    128 }
    129 
    130 void HTMLSourceElement::cancelPendingErrorEvent()
    131 {
    132     WTF_LOG(Media, "HTMLSourceElement::cancelPendingErrorEvent - %p", this);
    133     sourceErrorEventSender().cancelEvent(this);
    134 }
    135 
    136 void HTMLSourceElement::dispatchPendingEvent(SourceEventSender* eventSender)
    137 {
    138     ASSERT_UNUSED(eventSender, eventSender == &sourceErrorEventSender());
    139     WTF_LOG(Media, "HTMLSourceElement::dispatchPendingEvent - %p", this);
    140     dispatchEvent(Event::createCancelable(EventTypeNames::error));
    141 }
    142 
    143 bool HTMLSourceElement::mediaQueryMatches() const
    144 {
    145     if (!m_mediaQueryList)
    146         return true;
    147 
    148     return m_mediaQueryList->matches();
    149 }
    150 
    151 bool HTMLSourceElement::isURLAttribute(const Attribute& attribute) const
    152 {
    153     return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
    154 }
    155 
    156 void HTMLSourceElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
    157 {
    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);
    165     }
    166     if (name == srcsetAttr || name == sizesAttr || name == mediaAttr || name == typeAttr) {
    167         Element* parent = parentElement();
    168         if (isHTMLPictureElement(parent))
    169             toHTMLPictureElement(parent)->sourceOrMediaChanged();
    170     }
    171 }
    172 
    173 void HTMLSourceElement::notifyMediaQueryChanged()
    174 {
    175     Element* parent = parentElement();
    176     if (isHTMLPictureElement(parent))
    177         toHTMLPictureElement(parent)->sourceOrMediaChanged();
    178 }
    179 
    180 void HTMLSourceElement::trace(Visitor* visitor)
    181 {
    182     visitor->trace(m_mediaQueryList);
    183     visitor->trace(m_listener);
    184     HTMLElement::trace(visitor);
    185 }
    186 
    187 }
    188