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
23#if ENABLE(SVG)
24#include "SVGCursorElement.h"
25
26#include "Attr.h"
27#include "Document.h"
28#include "SVGNames.h"
29
30namespace WebCore {
31
32// Animated property definitions
33DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::xAttr, X, x)
34DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::yAttr, Y, y)
35DEFINE_ANIMATED_STRING(SVGCursorElement, XLinkNames::hrefAttr, Href, href)
36DEFINE_ANIMATED_BOOLEAN(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
37
38inline SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document* document)
39    : SVGElement(tagName, document)
40    , m_x(LengthModeWidth)
41    , m_y(LengthModeHeight)
42{
43}
44
45PassRefPtr<SVGCursorElement> SVGCursorElement::create(const QualifiedName& tagName, Document* document)
46{
47    return adoptRef(new SVGCursorElement(tagName, document));
48}
49
50SVGCursorElement::~SVGCursorElement()
51{
52    HashSet<SVGElement*>::iterator end = m_clients.end();
53    for (HashSet<SVGElement*>::iterator it = m_clients.begin(); it != end; ++it)
54        (*it)->cursorElementRemoved();
55}
56
57void SVGCursorElement::parseMappedAttribute(Attribute* attr)
58{
59    if (attr->name() == SVGNames::xAttr)
60        setXBaseValue(SVGLength(LengthModeWidth, attr->value()));
61    else if (attr->name() == SVGNames::yAttr)
62        setYBaseValue(SVGLength(LengthModeHeight, attr->value()));
63    else {
64        if (SVGTests::parseMappedAttribute(attr))
65            return;
66        if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
67            return;
68        if (SVGURIReference::parseMappedAttribute(attr))
69            return;
70
71        SVGElement::parseMappedAttribute(attr);
72    }
73}
74
75AttributeToPropertyTypeMap& SVGCursorElement::attributeToPropertyTypeMap()
76{
77    DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_attributeToPropertyTypeMap, ());
78    return s_attributeToPropertyTypeMap;
79}
80
81void SVGCursorElement::fillAttributeToPropertyTypeMap()
82{
83    AttributeToPropertyTypeMap& attributeToPropertyTypeMap = this->attributeToPropertyTypeMap();
84    attributeToPropertyTypeMap.set(SVGNames::xAttr, AnimatedNumber);
85    attributeToPropertyTypeMap.set(SVGNames::yAttr, AnimatedNumber);
86    attributeToPropertyTypeMap.set(XLinkNames::hrefAttr, AnimatedString);
87}
88
89void SVGCursorElement::addClient(SVGElement* element)
90{
91    m_clients.add(element);
92    element->setCursorElement(this);
93}
94
95void SVGCursorElement::removeClient(SVGElement* element)
96{
97    HashSet<SVGElement*>::iterator it = m_clients.find(element);
98    if (it != m_clients.end()) {
99        m_clients.remove(it);
100        element->cursorElementRemoved();
101    }
102}
103
104void SVGCursorElement::removeReferencedElement(SVGElement* element)
105{
106    m_clients.remove(element);
107}
108
109void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName)
110{
111    SVGElement::svgAttributeChanged(attrName);
112
113    if (attrName == SVGNames::xAttr
114        || attrName == SVGNames::yAttr
115        || SVGTests::isKnownAttribute(attrName)
116        || SVGExternalResourcesRequired::isKnownAttribute(attrName)
117        || SVGURIReference::isKnownAttribute(attrName)) {
118        HashSet<SVGElement*>::const_iterator it = m_clients.begin();
119        HashSet<SVGElement*>::const_iterator end = m_clients.end();
120
121        for (; it != end; ++it)
122            (*it)->setNeedsStyleRecalc();
123    }
124}
125
126void SVGCursorElement::synchronizeProperty(const QualifiedName& attrName)
127{
128    SVGElement::synchronizeProperty(attrName);
129
130    if (attrName == anyQName()) {
131        synchronizeX();
132        synchronizeY();
133        synchronizeExternalResourcesRequired();
134        synchronizeHref();
135        SVGTests::synchronizeProperties(this, attrName);
136        return;
137    }
138
139    if (attrName == SVGNames::xAttr)
140        synchronizeX();
141    else if (attrName == SVGNames::yAttr)
142        synchronizeY();
143    else if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
144        synchronizeExternalResourcesRequired();
145    else if (SVGURIReference::isKnownAttribute(attrName))
146        synchronizeHref();
147    else if (SVGTests::isKnownAttribute(attrName))
148        SVGTests::synchronizeProperties(this, attrName);
149}
150
151void SVGCursorElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
152{
153    SVGElement::addSubresourceAttributeURLs(urls);
154
155    addSubresourceURL(urls, document()->completeURL(href()));
156}
157
158}
159
160#endif // ENABLE(SVG)
161