don't discard iframe children.
[kdelibs.git] / khtml / svg / SVGStyledElement.cpp
blob20475cf7e6a26dce6918eaacf586aa051346fb20
1 /*
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.
21 #include "config.h"
22 #include "wtf/Platform.h"
24 #if ENABLE(SVG)
25 #include "SVGStyledElement.h"
27 /*#include "Attr.h"
28 #include "CSSParser.h"
29 #include "CSSStyleSelector.h"
30 #include "CString.h"*/
31 #include "cssstyleselector.h"
32 #include "Document.h"
33 /*#include "HTMLNames.h"*/
34 #include "PlatformString.h"
35 #include "SVGElement.h"
36 /*#include "SVGElementInstance.h"*/
37 #include "SVGNames.h"
38 #include "RenderObject.h"
39 #include "SVGRenderStyle.h"
40 /*#include "SVGResource.h"*/
41 #include "SVGSVGElement.h"
42 #include <wtf/Assertions.h>
44 // khtml
45 #include "css_base.h"
47 namespace WebCore {
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);
75 return false;
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()*/)
90 return 0;
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) {
161 result = eSVG;
162 return false;
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;
172 int id = attr->id();
173 if (id == ATTR_STYLE) {
174 kDebug() << "handle style" << endl;
175 if (inlineStyleDecls()) {
176 inlineStyleDecls()->clear();
177 } else {
178 createInlineDecl();
180 inlineStyleDecls()->setProperty(attr->value());
181 setChanged();
182 return;
184 int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name());
185 kDebug() << "propId" << propId << endl;
186 if (propId > 0) {
187 addCSSProperty(attr, propId, attr->value());
188 setChanged();
189 return;
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);
200 if (propId > 0)
201 return true;
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();
214 if (!extensions)
215 return;
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();
228 while (node) {
229 if (!node->isSVGElement())
230 break;
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())
247 return;
249 SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
250 if (!extensions)
251 return;
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))
264 return;
266 SVGStyledElement* nonConstThis = const_cast<SVGStyledElement*>(this);
267 HashSet<SVGElementInstance*>* set = extensions->instancesForElement(nonConstThis);
268 if (!set || set->isEmpty())
269 return;
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)
280 localCopy.add(*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)
292 if (renderer()) {
293 RenderStyle* renderStyle = renderer()->style();
294 renderStyle->ref();
295 return renderStyle;
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())
305 return 0;
306 return cssSVGAttr->style()->getPropertyCSSValue(name);*/
307 Q_ASSERT(false);
308 return new CSSPrimitiveValueImpl(0);
311 void SVGStyledElement::detach()
313 /*SVGResource::removeClient(this);*/
314 SVGElement::detach();
317 void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates)
319 if (blockUpdates) {
320 if (!gElementsWithInstanceUpdatesBlocked)
321 gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>;
322 gElementsWithInstanceUpdatesBlocked->add(this);
323 } else {
324 ASSERT(gElementsWithInstanceUpdatesBlocked);
325 ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this));
326 gElementsWithInstanceUpdatesBlocked->remove(this);
332 #endif // ENABLE(SVG)