1/* 2 * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 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 "SVGCursorElement.h" 23 24#include "Attr.h" 25#include "Document.h" 26#include "SVGElementInstance.h" 27#include "SVGNames.h" 28#include "XLinkNames.h" 29#include <wtf/NeverDestroyed.h> 30 31namespace WebCore { 32 33// Animated property definitions 34DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::xAttr, X, x) 35DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::yAttr, Y, y) 36DEFINE_ANIMATED_STRING(SVGCursorElement, XLinkNames::hrefAttr, Href, href) 37DEFINE_ANIMATED_BOOLEAN(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired) 38 39BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCursorElement) 40 REGISTER_LOCAL_ANIMATED_PROPERTY(x) 41 REGISTER_LOCAL_ANIMATED_PROPERTY(y) 42 REGISTER_LOCAL_ANIMATED_PROPERTY(href) 43 REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired) 44 REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests) 45END_REGISTER_ANIMATED_PROPERTIES 46 47inline SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document& document) 48 : SVGElement(tagName, document) 49 , m_x(LengthModeWidth) 50 , m_y(LengthModeHeight) 51{ 52 ASSERT(hasTagName(SVGNames::cursorTag)); 53 registerAnimatedPropertiesForSVGCursorElement(); 54} 55 56PassRefPtr<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document& document) 57{ 58 return adoptRef(new SVGCursorElement(tagName, document)); 59} 60 61SVGCursorElement::~SVGCursorElement() 62{ 63 HashSet<SVGElement*>::iterator end = m_clients.end(); 64 for (HashSet<SVGElement*>::iterator it = m_clients.begin(); it != end; ++it) 65 (*it)->cursorElementRemoved(); 66} 67 68bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName) 69{ 70 static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes; 71 if (supportedAttributes.get().isEmpty()) { 72 SVGTests::addSupportedAttributes(supportedAttributes); 73 SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes); 74 SVGURIReference::addSupportedAttributes(supportedAttributes); 75 supportedAttributes.get().add(SVGNames::xAttr); 76 supportedAttributes.get().add(SVGNames::yAttr); 77 } 78 return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName); 79} 80 81void SVGCursorElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 82{ 83 SVGParsingError parseError = NoError; 84 85 if (!isSupportedAttribute(name)) 86 SVGElement::parseAttribute(name, value); 87 else if (name == SVGNames::xAttr) 88 setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError)); 89 else if (name == SVGNames::yAttr) 90 setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError)); 91 else if (SVGTests::parseAttribute(name, value) 92 || SVGExternalResourcesRequired::parseAttribute(name, value) 93 || SVGURIReference::parseAttribute(name, value)) { 94 } else 95 ASSERT_NOT_REACHED(); 96 97 reportAttributeParsingError(parseError, name, value); 98} 99 100void SVGCursorElement::addClient(SVGElement* element) 101{ 102 m_clients.add(element); 103 element->setCursorElement(this); 104} 105 106void SVGCursorElement::removeClient(SVGElement* element) 107{ 108 if (m_clients.remove(element)) 109 element->cursorElementRemoved(); 110} 111 112void SVGCursorElement::removeReferencedElement(SVGElement* element) 113{ 114 m_clients.remove(element); 115} 116 117void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName) 118{ 119 if (!isSupportedAttribute(attrName)) { 120 SVGElement::svgAttributeChanged(attrName); 121 return; 122 } 123 124 SVGElementInstance::InvalidationGuard invalidationGuard(this); 125 126 // Any change of a cursor specific attribute triggers this recalc. 127 HashSet<SVGElement*>::const_iterator it = m_clients.begin(); 128 HashSet<SVGElement*>::const_iterator end = m_clients.end(); 129 130 for (; it != end; ++it) 131 (*it)->setNeedsStyleRecalc(); 132} 133 134void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const 135{ 136 SVGElement::addSubresourceAttributeURLs(urls); 137 138 addSubresourceURL(urls, document().completeURL(href())); 139} 140 141} 142