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#include "SVGScriptElement.h" 23 24#include "Attribute.h" 25#include "Document.h" 26#include "Event.h" 27#include "EventNames.h" 28#include "HTMLNames.h" 29#include "SVGAnimatedStaticPropertyTearOff.h" 30#include "SVGElementInstance.h" 31#include "XLinkNames.h" 32#include <wtf/NeverDestroyed.h> 33 34namespace WebCore { 35 36// Animated property definitions 37DEFINE_ANIMATED_STRING(SVGScriptElement, XLinkNames::hrefAttr, Href, href) 38DEFINE_ANIMATED_BOOLEAN(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 39 40BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGScriptElement) 41 REGISTER_LOCAL_ANIMATED_PROPERTY(href) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 43END_REGISTER_ANIMATED_PROPERTIES 44 45inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted) 46 : SVGElement(tagName, document) 47 , ScriptElement(*this, wasInsertedByParser, alreadyStarted) 48 , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired) 49{ 50 ASSERT(hasTagName(SVGNames::scriptTag)); 51 registerAnimatedPropertiesForSVGScriptElement(); 52} 53 54PassRefPtr<SVGScriptElement> SVGScriptElement::create(const QualifiedName& tagName, Document& document, bool insertedByParser) 55{ 56 return adoptRef(new SVGScriptElement(tagName, document, insertedByParser, false)); 57} 58 59bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName) 60{ 61 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; 62 if (supportedAttributes.get().isEmpty()) { 63 SVGURIReference::addSupportedAttributes(supportedAttributes); 64 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 65 supportedAttributes.get().add(SVGNames::typeAttr); 66 supportedAttributes.get().add(HTMLNames::onerrorAttr); 67 } 68 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); 69} 70 71void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 72{ 73 if (!isSupportedAttribute(name)) { 74 SVGElement::parseAttribute(name, value); 75 return; 76 } 77 78 if (name == SVGNames::typeAttr) 79 return; 80 81 if (name == HTMLNames::onerrorAttr) { 82 setAttributeEventListener(eventNames().errorEvent, name, value); 83 return; 84 } 85 86 if (SVGURIReference::parseAttribute(name, value)) 87 return; 88 if (SVGExternalResourcesRequired::parseAttribute(name, value)) 89 return; 90 91 ASSERT_NOT_REACHED(); 92} 93 94void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) 95{ 96 if (!isSupportedAttribute(attrName)) { 97 SVGElement::svgAttributeChanged(attrName); 98 return; 99 } 100 101 SVGElementInstance::InvalidationGuard invalidationGuard(this); 102 103 if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr) 104 return; 105 106 if (SVGURIReference::isKnownAttribute(attrName)) { 107 handleSourceAttribute(href()); 108 return; 109 } 110 111 if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName)) 112 return; 113 114 ASSERT_NOT_REACHED(); 115} 116 117Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode& rootParent) 118{ 119 SVGElement::insertedInto(rootParent); 120 ScriptElement::insertedInto(rootParent); 121 if (rootParent.inDocument()) 122 SVGExternalResourcesRequired::insertedIntoDocument(this); 123 return InsertionDone; 124} 125 126void SVGScriptElement::childrenChanged(const ChildChange& change) 127{ 128 SVGElement::childrenChanged(change); 129 ScriptElement::childrenChanged(); 130} 131 132bool SVGScriptElement::isURLAttribute(const Attribute& attribute) const 133{ 134 return attribute.name() == sourceAttributeValue(); 135} 136 137void SVGScriptElement::finishParsingChildren() 138{ 139 SVGElement::finishParsingChildren(); 140 SVGExternalResourcesRequired::finishParsingChildren(); 141} 142 143void SVGScriptElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const 144{ 145 SVGElement::addSubresourceAttributeURLs(urls); 146 147 addSubresourceURL(urls, document().completeURL(href())); 148} 149 150String SVGScriptElement::sourceAttributeValue() const 151{ 152 return href(); 153} 154 155String SVGScriptElement::charsetAttributeValue() const 156{ 157 return String(); 158} 159 160String SVGScriptElement::typeAttributeValue() const 161{ 162 return getAttribute(SVGNames::typeAttr).string(); 163} 164 165String SVGScriptElement::languageAttributeValue() const 166{ 167 return String(); 168} 169 170String SVGScriptElement::forAttributeValue() const 171{ 172 return String(); 173} 174 175String SVGScriptElement::eventAttributeValue() const 176{ 177 return String(); 178} 179 180bool SVGScriptElement::asyncAttributeValue() const 181{ 182 return false; 183} 184 185bool SVGScriptElement::deferAttributeValue() const 186{ 187 return false; 188} 189 190bool SVGScriptElement::hasSourceAttribute() const 191{ 192 return hasAttribute(XLinkNames::hrefAttr); 193} 194 195PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren() 196{ 197 return adoptRef(new SVGScriptElement(tagQName(), document(), false, alreadyStarted())); 198} 199 200#ifndef NDEBUG 201bool SVGScriptElement::filterOutAnimatableAttribute(const QualifiedName& name) const 202{ 203 return name == SVGNames::typeAttr; 204} 205#endif 206 207} 208