Home | History | Annotate | Download | only in svg
      1 /*
      2  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3  * Copyright (C) 2004, 2005, 2007 Rob Buis <buis (at) kde.org>
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  */
     20 
     21 #include "config.h"
     22 
     23 #include "core/svg/SVGScriptElement.h"
     24 
     25 #include "bindings/v8/ScriptEventListener.h"
     26 #include "core/HTMLNames.h"
     27 #include "core/XLinkNames.h"
     28 #include "core/dom/Attribute.h"
     29 #include "core/dom/Document.h"
     30 #include "core/dom/ScriptLoader.h"
     31 
     32 namespace WebCore {
     33 
     34 inline SVGScriptElement::SVGScriptElement(Document& document, bool wasInsertedByParser, bool alreadyStarted)
     35     : SVGElement(SVGNames::scriptTag, document)
     36     , SVGURIReference(this)
     37     , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
     38     , m_loader(ScriptLoader::create(this, wasInsertedByParser, alreadyStarted))
     39 {
     40     ScriptWrappable::init(this);
     41 }
     42 
     43 PassRefPtrWillBeRawPtr<SVGScriptElement> SVGScriptElement::create(Document& document, bool insertedByParser)
     44 {
     45     return adoptRefWillBeNoop(new SVGScriptElement(document, insertedByParser, false));
     46 }
     47 
     48 bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName)
     49 {
     50     DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
     51     if (supportedAttributes.isEmpty()) {
     52         SVGURIReference::addSupportedAttributes(supportedAttributes);
     53         supportedAttributes.add(SVGNames::typeAttr);
     54         supportedAttributes.add(HTMLNames::onerrorAttr);
     55     }
     56     return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
     57 }
     58 
     59 void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
     60 {
     61     if (!isSupportedAttribute(name)) {
     62         SVGElement::parseAttribute(name, value);
     63         return;
     64     }
     65 
     66     SVGParsingError parseError = NoError;
     67     if (name == SVGNames::typeAttr)
     68         return;
     69 
     70     if (name == HTMLNames::onerrorAttr) {
     71         setAttributeEventListener(EventTypeNames::error, createAttributeEventListener(this, name, value, eventParameterName()));
     72     } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
     73     } else {
     74         ASSERT_NOT_REACHED();
     75     }
     76 
     77     reportAttributeParsingError(parseError, name, value);
     78 }
     79 
     80 void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
     81 {
     82     if (!isSupportedAttribute(attrName)) {
     83         SVGElement::svgAttributeChanged(attrName);
     84         return;
     85     }
     86 
     87     SVGElement::InvalidationGuard invalidationGuard(this);
     88 
     89     if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr)
     90         return;
     91 
     92     if (SVGURIReference::isKnownAttribute(attrName)) {
     93         m_loader->handleSourceAttribute(hrefString());
     94         return;
     95     }
     96 
     97     ASSERT_NOT_REACHED();
     98 }
     99 
    100 Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode* rootParent)
    101 {
    102     SVGElement::insertedInto(rootParent);
    103     return InsertionShouldCallDidNotifySubtreeInsertions;
    104 }
    105 
    106 void SVGScriptElement::didNotifySubtreeInsertionsToDocument()
    107 {
    108     m_loader->didNotifySubtreeInsertionsToDocument();
    109 
    110     if (!m_loader->isParserInserted()) {
    111         m_loader->setHaveFiredLoadEvent(true);
    112         sendSVGLoadEventIfPossibleAsynchronously();
    113     }
    114 }
    115 
    116 void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
    117 {
    118     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    119     m_loader->childrenChanged();
    120 }
    121 
    122 bool SVGScriptElement::isURLAttribute(const Attribute& attribute) const
    123 {
    124     return attribute.name() == AtomicString(sourceAttributeValue());
    125 }
    126 
    127 void SVGScriptElement::finishParsingChildren()
    128 {
    129     SVGElement::finishParsingChildren();
    130     m_loader->setHaveFiredLoadEvent(true);
    131 }
    132 
    133 bool SVGScriptElement::haveLoadedRequiredResources()
    134 {
    135     return m_loader->haveFiredLoadEvent();
    136 }
    137 
    138 String SVGScriptElement::sourceAttributeValue() const
    139 {
    140     return hrefString();
    141 }
    142 
    143 String SVGScriptElement::charsetAttributeValue() const
    144 {
    145     return String();
    146 }
    147 
    148 String SVGScriptElement::typeAttributeValue() const
    149 {
    150     return getAttribute(SVGNames::typeAttr).string();
    151 }
    152 
    153 String SVGScriptElement::languageAttributeValue() const
    154 {
    155     return String();
    156 }
    157 
    158 String SVGScriptElement::forAttributeValue() const
    159 {
    160     return String();
    161 }
    162 
    163 String SVGScriptElement::eventAttributeValue() const
    164 {
    165     return String();
    166 }
    167 
    168 bool SVGScriptElement::asyncAttributeValue() const
    169 {
    170     return false;
    171 }
    172 
    173 bool SVGScriptElement::deferAttributeValue() const
    174 {
    175     return false;
    176 }
    177 
    178 bool SVGScriptElement::hasSourceAttribute() const
    179 {
    180     return href()->isSpecified();
    181 }
    182 
    183 PassRefPtrWillBeRawPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren()
    184 {
    185     return adoptRefWillBeNoop(new SVGScriptElement(document(), false, m_loader->alreadyStarted()));
    186 }
    187 
    188 void SVGScriptElement::dispatchLoadEvent()
    189 {
    190     dispatchEvent(Event::create(EventTypeNames::load));
    191 }
    192 
    193 #ifndef NDEBUG
    194 bool SVGScriptElement::isAnimatableAttribute(const QualifiedName& name) const
    195 {
    196     if (name == SVGNames::typeAttr)
    197         return false;
    198 
    199     return SVGElement::isAnimatableAttribute(name);
    200 }
    201 #endif
    202 
    203 }
    204