1/* 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2007 Rob Buis <buis@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 "HTMLNames.h" 26#include "XLinkNames.h" 27#include "bindings/v8/ScriptEventListener.h" 28#include "core/dom/Attribute.h" 29#include "core/dom/Document.h" 30#include "core/dom/EventNames.h" 31#include "core/dom/ScriptLoader.h" 32#include "core/svg/SVGElementInstance.h" 33#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h" 34 35namespace WebCore { 36 37// Animated property definitions 38DEFINE_ANIMATED_STRING(SVGScriptElement, XLinkNames::hrefAttr, Href, href) 39DEFINE_ANIMATED_BOOLEAN(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 40 41BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGScriptElement) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(href) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 44END_REGISTER_ANIMATED_PROPERTIES 45 46inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool alreadyStarted) 47 : SVGElement(tagName, document) 48 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) 49 , m_loader(ScriptLoader::create(this, wasInsertedByParser, alreadyStarted)) 50{ 51 ASSERT(hasTagName(SVGNames::scriptTag)); 52 ScriptWrappable::init(this); 53 registerAnimatedPropertiesForSVGScriptElement(); 54} 55 56PassRefPtr<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Document* document, bool insertedByParser) 57{ 58 return adoptRef(new SVGScriptElement(tagName, document, insertedByParser, false)); 59} 60 61bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName) 62{ 63 DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); 64 if (supportedAttributes.isEmpty()) { 65 SVGURIReference::addSupportedAttributes(supportedAttributes); 66 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 67 supportedAttributes.add(SVGNames::typeAttr); 68 supportedAttributes.add(HTMLNames::onerrorAttr); 69 } 70 return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); 71} 72 73void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 74{ 75 if (!isSupportedAttribute(name)) { 76 SVGElement::parseAttribute(name, value); 77 return; 78 } 79 80 if (name == SVGNames::typeAttr) { 81 setType(value); 82 return; 83 } 84 85 if (name == HTMLNames::onerrorAttr) { 86 setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, name, value)); 87 return; 88 } 89 90 if (SVGURIReference::parseAttribute(name, value)) 91 return; 92 if (SVGExternalResourcesRequired::parseAttribute(name, value)) 93 return; 94 95 ASSERT_NOT_REACHED(); 96} 97 98void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) 99{ 100 if (!isSupportedAttribute(attrName)) { 101 SVGElement::svgAttributeChanged(attrName); 102 return; 103 } 104 105 SVGElementInstance::InvalidationGuard invalidationGuard(this); 106 107 if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr) 108 return; 109 110 if (SVGURIReference::isKnownAttribute(attrName)) { 111 m_loader->handleSourceAttribute(hrefCurrentValue()); 112 return; 113 } 114 115 if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) 116 return; 117 118 ASSERT_NOT_REACHED(); 119} 120 121Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode* rootParent) 122{ 123 SVGElement::insertedInto(rootParent); 124 m_loader->insertedInto(rootParent); 125 if (rootParent->inDocument()) 126 SVGExternalResourcesRequired::insertedIntoDocument(this); 127 return InsertionDone; 128} 129 130void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) 131{ 132 SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 133 m_loader->childrenChanged(); 134} 135 136bool SVGScriptElement::isURLAttribute(const Attribute& attribute) const 137{ 138 return attribute.name() == sourceAttributeValue(); 139} 140 141void SVGScriptElement::finishParsingChildren() 142{ 143 SVGElement::finishParsingChildren(); 144 SVGExternalResourcesRequired::finishParsingChildren(); 145} 146 147String SVGScriptElement::type() const 148{ 149 return m_type; 150} 151 152void SVGScriptElement::setType(const String& type) 153{ 154 m_type = type; 155} 156 157void SVGScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const 158{ 159 SVGElement::addSubresourceAttributeURLs(urls); 160 161 addSubresourceURL(urls, document()->completeURL(hrefCurrentValue())); 162} 163 164String SVGScriptElement::sourceAttributeValue() const 165{ 166 return hrefCurrentValue(); 167} 168 169String SVGScriptElement::charsetAttributeValue() const 170{ 171 return String(); 172} 173 174String SVGScriptElement::typeAttributeValue() const 175{ 176 return type(); 177} 178 179String SVGScriptElement::languageAttributeValue() const 180{ 181 return String(); 182} 183 184String SVGScriptElement::forAttributeValue() const 185{ 186 return String(); 187} 188 189String SVGScriptElement::eventAttributeValue() const 190{ 191 return String(); 192} 193 194bool SVGScriptElement::asyncAttributeValue() const 195{ 196 return false; 197} 198 199bool SVGScriptElement::deferAttributeValue() const 200{ 201 return false; 202} 203 204bool SVGScriptElement::hasSourceAttribute() const 205{ 206 return hasAttribute(XLinkNames::hrefAttr); 207} 208 209PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() 210{ 211 return adoptRef(new SVGScriptElement(tagQName(), document(), false, m_loader->alreadyStarted())); 212} 213 214void SVGScriptElement::setHaveFiredLoadEvent(bool haveFiredLoadEvent) 215{ 216 m_loader->setHaveFiredLoadEvent(haveFiredLoadEvent); 217} 218 219bool SVGScriptElement::isParserInserted() const 220{ 221 return m_loader->isParserInserted(); 222} 223 224bool SVGScriptElement::haveFiredLoadEvent() const 225{ 226 return m_loader->haveFiredLoadEvent(); 227} 228 229Timer<SVGElement>* SVGScriptElement::svgLoadEventTimer() 230{ 231 return &m_svgLoadEventTimer; 232} 233 234} 235