2 Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005, 2007 Rob Buis <buis@kde.org>
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.
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.
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.
22 #include "wtf/Platform.h"
25 #include "SVGStyledElement.h"
28 #include "CSSParser.h"
29 #include "CSSStyleSelector.h"
30 #include "CString.h"*/
31 #include "cssstyleselector.h"
33 /*#include "HTMLNames.h"*/
34 #include "PlatformString.h"
35 #include "SVGElement.h"
36 /*#include "SVGElementInstance.h"*/
38 #include "RenderObject.h"
39 #include "SVGRenderStyle.h"
40 /*#include "SVGResource.h"*/
41 #include "SVGSVGElement.h"
42 #include <wtf/Assertions.h>
49 using namespace SVGNames
;
51 static HashSet
<const SVGStyledElement
*>* gElementsWithInstanceUpdatesBlocked
= 0;
53 SVGStyledElement::SVGStyledElement(const QualifiedName
& tagName
, Document
* doc
)
54 : SVGElement(tagName
, doc
)
58 SVGStyledElement::~SVGStyledElement()
60 // SVGResource::removeClient(this);
63 ANIMATED_PROPERTY_DEFINITIONS(SVGStyledElement
, String
, String
, string
, ClassName
, className
, HTMLNames::classAttr
, m_className
)
65 bool SVGStyledElement::rendererIsNeeded(RenderStyle
* style
)
67 // http://www.w3.org/TR/SVG/extend.html#PrivateData
68 // Prevent anything other than SVG renderers from appearing in our render tree
69 // Spec: SVG allows inclusion of elements from foreign namespaces anywhere
70 // with the SVG content. In general, the SVG user agent will include the unknown
71 // elements in the DOM but will otherwise ignore unknown elements.
72 if (!parentNode() || parentNode()->isSVGElement())
73 return StyledElement::rendererIsNeeded(style
);
78 static void mapAttributeToCSSProperty(HashMap
<DOMStringImpl
*, int>* propertyNameToIdMap
, const QualifiedName
& attrName
)
80 /*int propertyId = cssPropertyID(attrName.localName());*/
81 QString propName
= attrName
.localName().string();
82 int propertyId
= getPropertyID(propName
.toLatin1(), propName
.length());
83 ASSERT(propertyId
> 0);
84 propertyNameToIdMap
->set(attrName
.localName().implementation(), propertyId
);
87 int SVGStyledElement::cssPropertyIdForSVGAttributeName(const QualifiedName
& attrName
)
89 if (!attrName
.namespaceURI().isEmpty()/*khtml fix, was isNull()*/)
92 static HashMap
<DOMStringImpl
*, int>* propertyNameToIdMap
= 0;
93 if (!propertyNameToIdMap
) {
94 propertyNameToIdMap
= new HashMap
<DOMStringImpl
*, int>;
95 // This is a list of all base CSS and SVG CSS properties which are exposed as SVG XML attributes
96 /*mapAttributeToCSSProperty(propertyNameToIdMap, alignment_baselineAttr);
97 mapAttributeToCSSProperty(propertyNameToIdMap, baseline_shiftAttr);*/
98 mapAttributeToCSSProperty(propertyNameToIdMap
, clipAttr
);
99 mapAttributeToCSSProperty(propertyNameToIdMap
, clip_pathAttr
);
100 mapAttributeToCSSProperty(propertyNameToIdMap
, clip_ruleAttr
);
101 /*mapAttributeToCSSProperty(propertyNameToIdMap, colorAttr);
102 mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr);
103 mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filtersAttr);
104 mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr);
105 mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr);
106 mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr);
107 mapAttributeToCSSProperty(propertyNameToIdMap, directionAttr);
108 mapAttributeToCSSProperty(propertyNameToIdMap, displayAttr);
109 mapAttributeToCSSProperty(propertyNameToIdMap, dominant_baselineAttr);
110 mapAttributeToCSSProperty(propertyNameToIdMap, enable_backgroundAttr);*/
111 mapAttributeToCSSProperty(propertyNameToIdMap
, fillAttr
);
112 mapAttributeToCSSProperty(propertyNameToIdMap
, fill_opacityAttr
);
113 mapAttributeToCSSProperty(propertyNameToIdMap
, fill_ruleAttr
);
114 /*mapAttributeToCSSProperty(propertyNameToIdMap, filterAttr);
115 mapAttributeToCSSProperty(propertyNameToIdMap, flood_colorAttr);
116 mapAttributeToCSSProperty(propertyNameToIdMap, flood_opacityAttr);*/
117 mapAttributeToCSSProperty(propertyNameToIdMap
, font_familyAttr
);
118 mapAttributeToCSSProperty(propertyNameToIdMap
, font_sizeAttr
);
119 //mapAttributeToCSSProperty(propertyNameToIdMap, font_stretchAttr);
120 mapAttributeToCSSProperty(propertyNameToIdMap
, font_styleAttr
);
121 mapAttributeToCSSProperty(propertyNameToIdMap
, font_variantAttr
);
122 mapAttributeToCSSProperty(propertyNameToIdMap
, font_weightAttr
);
123 /*mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_horizontalAttr);
124 mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_verticalAttr);
125 mapAttributeToCSSProperty(propertyNameToIdMap, image_renderingAttr);
126 mapAttributeToCSSProperty(propertyNameToIdMap, kerningAttr);
127 mapAttributeToCSSProperty(propertyNameToIdMap, letter_spacingAttr);
128 mapAttributeToCSSProperty(propertyNameToIdMap, lighting_colorAttr);
129 mapAttributeToCSSProperty(propertyNameToIdMap, marker_endAttr);
130 mapAttributeToCSSProperty(propertyNameToIdMap, marker_midAttr);
131 mapAttributeToCSSProperty(propertyNameToIdMap, marker_startAttr);
132 mapAttributeToCSSProperty(propertyNameToIdMap, maskAttr);
133 mapAttributeToCSSProperty(propertyNameToIdMap, opacityAttr);
134 mapAttributeToCSSProperty(propertyNameToIdMap, overflowAttr);
135 mapAttributeToCSSProperty(propertyNameToIdMap, pointer_eventsAttr);
136 mapAttributeToCSSProperty(propertyNameToIdMap, shape_renderingAttr);*/
137 mapAttributeToCSSProperty(propertyNameToIdMap
, stop_colorAttr
);
138 mapAttributeToCSSProperty(propertyNameToIdMap
, stop_opacityAttr
);
139 mapAttributeToCSSProperty(propertyNameToIdMap
, strokeAttr
);
140 /*mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dasharrayAttr);
141 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dashoffsetAttr);
142 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linecapAttr);
143 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linejoinAttr);
144 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_miterlimitAttr);*/
145 mapAttributeToCSSProperty(propertyNameToIdMap
, stroke_opacityAttr
);
146 mapAttributeToCSSProperty(propertyNameToIdMap
, stroke_widthAttr
);
147 /*mapAttributeToCSSProperty(propertyNameToIdMap, text_anchorAttr);
148 mapAttributeToCSSProperty(propertyNameToIdMap, text_decorationAttr);
149 mapAttributeToCSSProperty(propertyNameToIdMap, text_renderingAttr);
150 mapAttributeToCSSProperty(propertyNameToIdMap, unicode_bidiAttr);
151 mapAttributeToCSSProperty(propertyNameToIdMap, visibilityAttr);
152 mapAttributeToCSSProperty(propertyNameToIdMap, word_spacingAttr);
153 mapAttributeToCSSProperty(propertyNameToIdMap, writing_modeAttr);*/
155 return propertyNameToIdMap
->get(attrName
.localName().implementation());
158 /*bool SVGStyledElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
160 if (SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName) > 0) {
164 return SVGElement::mapToEntry(attrName, result);
167 void SVGStyledElement::parseMappedAttribute(MappedAttribute
* attr
)
169 // NOTE: Any subclass which overrides parseMappedAttribute for a property handled by
170 // cssPropertyIdForSVGAttributeName will also have to override mapToEntry to disable the default eSVG mapping
171 kDebug() << "parse:" << attr
->localName() << attr
->value() << "id=" << attr
->id() << endl
;
173 if (id
== ATTR_STYLE
) {
174 kDebug() << "handle style" << endl
;
175 if (inlineStyleDecls()) {
176 inlineStyleDecls()->clear();
180 inlineStyleDecls()->setProperty(attr
->value());
184 int propId
= SVGStyledElement::cssPropertyIdForSVGAttributeName(attr
->name());
185 kDebug() << "propId" << propId
<< endl
;
187 addCSSProperty(attr
, propId
, attr
->value());
192 // id and class are handled by StyledElement
193 SVGElement::parseMappedAttribute(attr
);
196 bool SVGStyledElement::isKnownAttribute(const QualifiedName
& attrName
)
198 // Recognize all style related SVG CSS properties
199 int propId
= SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName
);
202 return (attrName
.id() == ATTR_ID
|| attrName
.id() == ATTR_STYLE
);
203 /*return (attrName == HTMLNames::idAttr || attrName == HTMLNames::styleAttr); */
206 void SVGStyledElement::svgAttributeChanged(const QualifiedName
& attrName
)
208 SVGElement::svgAttributeChanged(attrName
);
210 // If we're the child of a resource element, be sure to invalidate it.
211 invalidateResourcesInAncestorChain();
213 SVGDocumentExtensions
* extensions
= document()->accessSVGExtensions();
217 // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily)
219 // In case we're referenced by a <use> element, we have element instances registered
220 // to us in the SVGDocumentExtensions. If notifyAttributeChange() is called, we need
221 // to recursively update all children including ourselves.
222 updateElementInstance(extensions
);
225 void SVGStyledElement::invalidateResourcesInAncestorChain() const
227 Node
* node
= parentNode();
229 if (!node
->isSVGElement())
232 SVGElement
* element
= static_cast<SVGElement
*>(node
);
233 if (SVGStyledElement
* styledElement
= static_cast<SVGStyledElement
*>(element
->isStyled() ? element
: 0)) {
234 /*if (SVGResource* resource = styledElement->canvasResource())
235 resource->invalidate();*/
238 node
= node
->parentNode();
242 void SVGStyledElement::childrenChanged(bool changedByParser
, Node
* beforeChange
, Node
* afterChange
, int childCountDelta
)
244 SVGElement::childrenChanged();
245 /*SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
246 if (document()->parsing())
249 SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
253 // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily)
255 // In case we're referenced by a <use> element, we have element instances registered
256 // to us in the SVGDocumentExtensions. If childrenChanged() is called, we need
257 // to recursively update all children including ourselves.
258 updateElementInstance(extensions);*/
261 void SVGStyledElement::updateElementInstance(SVGDocumentExtensions
* extensions
) const
263 /*if (gElementsWithInstanceUpdatesBlocked && gElementsWithInstanceUpdatesBlocked->contains(this))
266 SVGStyledElement* nonConstThis = const_cast<SVGStyledElement*>(this);
267 HashSet<SVGElementInstance*>* set = extensions->instancesForElement(nonConstThis);
268 if (!set || set->isEmpty())
271 // We need to be careful here, as the instancesForElement
272 // hash set may be modified after we call updateInstance!
273 HashSet<SVGElementInstance*> localCopy;
275 // First create a local copy of the hashset
276 HashSet<SVGElementInstance*>::const_iterator it1 = set->begin();
277 const HashSet<SVGElementInstance*>::const_iterator end1 = set->end();
279 for (; it1 != end1; ++it1)
282 // Actually nofify instances to update
283 HashSet<SVGElementInstance*>::const_iterator it2 = localCopy.begin();
284 const HashSet<SVGElementInstance*>::const_iterator end2 = localCopy.end();
286 for (; it2 != end2; ++it2)
287 (*it2)->updateInstance(nonConstThis);*/
290 RenderStyle
* SVGStyledElement::resolveStyle(RenderStyle
* parentStyle
)
293 RenderStyle
* renderStyle
= renderer()->style();
298 return document()->styleSelector()->styleForElement(this/*, parentStyle*/);
301 PassRefPtr
<CSSValue
> SVGStyledElement::getPresentationAttribute(const String
& name
)
303 /*MappedAttribute* cssSVGAttr = mappedAttributes()->getAttributeItem(name);
304 if (!cssSVGAttr || !cssSVGAttr->style())
306 return cssSVGAttr->style()->getPropertyCSSValue(name);*/
308 return new CSSPrimitiveValueImpl(0);
311 void SVGStyledElement::detach()
313 /*SVGResource::removeClient(this);*/
314 SVGElement::detach();
317 void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates
)
320 if (!gElementsWithInstanceUpdatesBlocked
)
321 gElementsWithInstanceUpdatesBlocked
= new HashSet
<const SVGStyledElement
*>;
322 gElementsWithInstanceUpdatesBlocked
->add(this);
324 ASSERT(gElementsWithInstanceUpdatesBlocked
);
325 ASSERT(gElementsWithInstanceUpdatesBlocked
->contains(this));
326 gElementsWithInstanceUpdatesBlocked
->remove(this);
332 #endif // ENABLE(SVG)