| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> | |
| 3 * Copyright (C) 2004, 2005, 2007, 2008 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 #include "core/svg/SVGStyledElement.h" | |
| 24 | |
| 25 #include "HTMLNames.h" | |
| 26 #include "SVGNames.h" | |
| 27 #include "core/css/CSSParser.h" | |
| 28 #include "core/dom/Attr.h" | |
| 29 #include "core/dom/Document.h" | |
| 30 #include "core/dom/EventNames.h" | |
| 31 #include "core/dom/NodeTraversal.h" | |
| 32 #include "core/dom/shadow/ShadowRoot.h" | |
| 33 #include "core/rendering/RenderObject.h" | |
| 34 #include "core/rendering/style/SVGRenderStyle.h" | |
| 35 #include "core/rendering/svg/RenderSVGResource.h" | |
| 36 #include "core/rendering/svg/RenderSVGResourceClipper.h" | |
| 37 #include "core/rendering/svg/RenderSVGResourceFilter.h" | |
| 38 #include "core/rendering/svg/RenderSVGResourceMasker.h" | |
| 39 #include "core/rendering/svg/SVGRenderSupport.h" | |
| 40 #include "core/svg/SVGElement.h" | |
| 41 #include "core/svg/SVGElementInstance.h" | |
| 42 #include "core/svg/SVGElementRareData.h" | |
| 43 #include "core/svg/SVGSVGElement.h" | |
| 44 #include "core/svg/SVGUseElement.h" | |
| 45 #include "wtf/Assertions.h" | |
| 46 #include "wtf/HashMap.h" | |
| 47 #include "wtf/StdLibExtras.h" | |
| 48 #include "wtf/text/WTFString.h" | |
| 49 | |
| 50 namespace WebCore { | |
| 51 | |
| 52 // Animated property definitions | |
| 53 DEFINE_ANIMATED_STRING(SVGStyledElement, HTMLNames::classAttr, ClassName, classN
ame) | |
| 54 | |
| 55 BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGStyledElement) | |
| 56 REGISTER_LOCAL_ANIMATED_PROPERTY(className) | |
| 57 END_REGISTER_ANIMATED_PROPERTIES | |
| 58 | |
| 59 using namespace SVGNames; | |
| 60 | |
| 61 void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyName
ToIdMap, const QualifiedName& attrName) | |
| 62 { | |
| 63 // FIXME: when CSS supports "transform-origin" the special case for transfor
m_originAttr can be removed. | |
| 64 CSSPropertyID propertyId = cssPropertyID(attrName.localName()); | |
| 65 if (!propertyId && attrName == transform_originAttr) | |
| 66 propertyId = CSSPropertyWebkitTransformOrigin; // cssPropertyID("-webkit
-transform-origin") | |
| 67 ASSERT(propertyId > 0); | |
| 68 propertyNameToIdMap->set(attrName.localName().impl(), propertyId); | |
| 69 } | |
| 70 | |
| 71 SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* docum
ent, ConstructionType constructionType) | |
| 72 : SVGElement(tagName, document, constructionType) | |
| 73 { | |
| 74 ScriptWrappable::init(this); | |
| 75 registerAnimatedPropertiesForSVGStyledElement(); | |
| 76 } | |
| 77 | |
| 78 String SVGStyledElement::title() const | |
| 79 { | |
| 80 // According to spec, we should not return titles when hovering over root <s
vg> elements (those | |
| 81 // <title> elements are the title of the document, not a tooltip) so we inst
antly return. | |
| 82 if (isOutermostSVGSVGElement()) | |
| 83 return String(); | |
| 84 | |
| 85 // Walk up the tree, to find out whether we're inside a <use> shadow tree, t
o find the right title. | |
| 86 if (isInShadowTree()) { | |
| 87 Element* shadowHostElement = toShadowRoot(treeScope()->rootNode())->host
(); | |
| 88 // At this time, SVG nodes are not allowed in non-<use> shadow trees, so
any shadow root we do | |
| 89 // have should be a use. The assert and following test is here to catch
future shadow DOM changes | |
| 90 // that do enable SVG in a shadow tree. | |
| 91 ASSERT(!shadowHostElement || shadowHostElement->hasTagName(SVGNames::use
Tag)); | |
| 92 if (shadowHostElement && shadowHostElement->hasTagName(SVGNames::useTag)
) { | |
| 93 SVGUseElement* useElement = toSVGUseElement(shadowHostElement); | |
| 94 | |
| 95 // If the <use> title is not empty we found the title to use. | |
| 96 String useTitle(useElement->title()); | |
| 97 if (!useTitle.isEmpty()) | |
| 98 return useTitle; | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 // If we aren't an instance in a <use> or the <use> title was not found, the
n find the first | |
| 103 // <title> child of this element. | |
| 104 Element* titleElement = ElementTraversal::firstWithin(this); | |
| 105 for (; titleElement; titleElement = ElementTraversal::nextSkippingChildren(t
itleElement, this)) { | |
| 106 if (titleElement->hasTagName(SVGNames::titleTag) && titleElement->isSVGE
lement()) | |
| 107 break; | |
| 108 } | |
| 109 | |
| 110 // If a title child was found, return the text contents. | |
| 111 if (titleElement) | |
| 112 return titleElement->innerText(); | |
| 113 | |
| 114 // Otherwise return a null/empty string. | |
| 115 return String(); | |
| 116 } | |
| 117 | |
| 118 bool SVGStyledElement::rendererIsNeeded(const NodeRenderingContext& context) | |
| 119 { | |
| 120 // http://www.w3.org/TR/SVG/extend.html#PrivateData | |
| 121 // Prevent anything other than SVG renderers from appearing in our render tr
ee | |
| 122 // Spec: SVG allows inclusion of elements from foreign namespaces anywhere | |
| 123 // with the SVG content. In general, the SVG user agent will include the unk
nown | |
| 124 // elements in the DOM but will otherwise ignore unknown elements. | |
| 125 if (!parentOrShadowHostElement() || parentOrShadowHostElement()->isSVGElemen
t()) | |
| 126 return Element::rendererIsNeeded(context); | |
| 127 | |
| 128 return false; | |
| 129 } | |
| 130 | |
| 131 CSSPropertyID SVGStyledElement::cssPropertyIdForSVGAttributeName(const Qualified
Name& attrName) | |
| 132 { | |
| 133 if (!attrName.namespaceURI().isNull()) | |
| 134 return CSSPropertyInvalid; | |
| 135 | |
| 136 static HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap = 0; | |
| 137 if (!propertyNameToIdMap) { | |
| 138 propertyNameToIdMap = new HashMap<StringImpl*, CSSPropertyID>; | |
| 139 // This is a list of all base CSS and SVG CSS properties which are expos
ed as SVG XML attributes | |
| 140 mapAttributeToCSSProperty(propertyNameToIdMap, alignment_baselineAttr); | |
| 141 mapAttributeToCSSProperty(propertyNameToIdMap, baseline_shiftAttr); | |
| 142 mapAttributeToCSSProperty(propertyNameToIdMap, buffered_renderingAttr); | |
| 143 mapAttributeToCSSProperty(propertyNameToIdMap, clipAttr); | |
| 144 mapAttributeToCSSProperty(propertyNameToIdMap, clip_pathAttr); | |
| 145 mapAttributeToCSSProperty(propertyNameToIdMap, clip_ruleAttr); | |
| 146 mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::colorAttr); | |
| 147 mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr); | |
| 148 mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filte
rsAttr); | |
| 149 mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr); | |
| 150 mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr); | |
| 151 mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr); | |
| 152 mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::directionAttr); | |
| 153 mapAttributeToCSSProperty(propertyNameToIdMap, displayAttr); | |
| 154 mapAttributeToCSSProperty(propertyNameToIdMap, dominant_baselineAttr); | |
| 155 mapAttributeToCSSProperty(propertyNameToIdMap, enable_backgroundAttr); | |
| 156 mapAttributeToCSSProperty(propertyNameToIdMap, fillAttr); | |
| 157 mapAttributeToCSSProperty(propertyNameToIdMap, fill_opacityAttr); | |
| 158 mapAttributeToCSSProperty(propertyNameToIdMap, fill_ruleAttr); | |
| 159 mapAttributeToCSSProperty(propertyNameToIdMap, filterAttr); | |
| 160 mapAttributeToCSSProperty(propertyNameToIdMap, flood_colorAttr); | |
| 161 mapAttributeToCSSProperty(propertyNameToIdMap, flood_opacityAttr); | |
| 162 mapAttributeToCSSProperty(propertyNameToIdMap, font_familyAttr); | |
| 163 mapAttributeToCSSProperty(propertyNameToIdMap, font_sizeAttr); | |
| 164 mapAttributeToCSSProperty(propertyNameToIdMap, font_stretchAttr); | |
| 165 mapAttributeToCSSProperty(propertyNameToIdMap, font_styleAttr); | |
| 166 mapAttributeToCSSProperty(propertyNameToIdMap, font_variantAttr); | |
| 167 mapAttributeToCSSProperty(propertyNameToIdMap, font_weightAttr); | |
| 168 mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_horizon
talAttr); | |
| 169 mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_vertica
lAttr); | |
| 170 mapAttributeToCSSProperty(propertyNameToIdMap, image_renderingAttr); | |
| 171 mapAttributeToCSSProperty(propertyNameToIdMap, kerningAttr); | |
| 172 mapAttributeToCSSProperty(propertyNameToIdMap, letter_spacingAttr); | |
| 173 mapAttributeToCSSProperty(propertyNameToIdMap, lighting_colorAttr); | |
| 174 mapAttributeToCSSProperty(propertyNameToIdMap, marker_endAttr); | |
| 175 mapAttributeToCSSProperty(propertyNameToIdMap, marker_midAttr); | |
| 176 mapAttributeToCSSProperty(propertyNameToIdMap, marker_startAttr); | |
| 177 mapAttributeToCSSProperty(propertyNameToIdMap, maskAttr); | |
| 178 mapAttributeToCSSProperty(propertyNameToIdMap, mask_typeAttr); | |
| 179 mapAttributeToCSSProperty(propertyNameToIdMap, opacityAttr); | |
| 180 mapAttributeToCSSProperty(propertyNameToIdMap, overflowAttr); | |
| 181 mapAttributeToCSSProperty(propertyNameToIdMap, pointer_eventsAttr); | |
| 182 mapAttributeToCSSProperty(propertyNameToIdMap, shape_renderingAttr); | |
| 183 mapAttributeToCSSProperty(propertyNameToIdMap, stop_colorAttr); | |
| 184 mapAttributeToCSSProperty(propertyNameToIdMap, stop_opacityAttr); | |
| 185 mapAttributeToCSSProperty(propertyNameToIdMap, strokeAttr); | |
| 186 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dasharrayAttr); | |
| 187 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dashoffsetAttr); | |
| 188 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linecapAttr); | |
| 189 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linejoinAttr); | |
| 190 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_miterlimitAttr); | |
| 191 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_opacityAttr); | |
| 192 mapAttributeToCSSProperty(propertyNameToIdMap, stroke_widthAttr); | |
| 193 mapAttributeToCSSProperty(propertyNameToIdMap, text_anchorAttr); | |
| 194 mapAttributeToCSSProperty(propertyNameToIdMap, text_decorationAttr); | |
| 195 mapAttributeToCSSProperty(propertyNameToIdMap, text_renderingAttr); | |
| 196 mapAttributeToCSSProperty(propertyNameToIdMap, transform_originAttr); | |
| 197 mapAttributeToCSSProperty(propertyNameToIdMap, unicode_bidiAttr); | |
| 198 mapAttributeToCSSProperty(propertyNameToIdMap, vector_effectAttr); | |
| 199 mapAttributeToCSSProperty(propertyNameToIdMap, visibilityAttr); | |
| 200 mapAttributeToCSSProperty(propertyNameToIdMap, word_spacingAttr); | |
| 201 mapAttributeToCSSProperty(propertyNameToIdMap, writing_modeAttr); | |
| 202 } | |
| 203 | |
| 204 return propertyNameToIdMap->get(attrName.localName().impl()); | |
| 205 } | |
| 206 | |
| 207 typedef HashMap<QualifiedName, AnimatedPropertyType> AttributeToPropertyTypeMap; | |
| 208 static inline AttributeToPropertyTypeMap& cssPropertyToTypeMap() | |
| 209 { | |
| 210 DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_cssPropertyMap, ()); | |
| 211 | |
| 212 if (!s_cssPropertyMap.isEmpty()) | |
| 213 return s_cssPropertyMap; | |
| 214 | |
| 215 // Fill the map for the first use. | |
| 216 s_cssPropertyMap.set(alignment_baselineAttr, AnimatedString); | |
| 217 s_cssPropertyMap.set(baseline_shiftAttr, AnimatedString); | |
| 218 s_cssPropertyMap.set(buffered_renderingAttr, AnimatedString); | |
| 219 s_cssPropertyMap.set(clipAttr, AnimatedRect); | |
| 220 s_cssPropertyMap.set(clip_pathAttr, AnimatedString); | |
| 221 s_cssPropertyMap.set(clip_ruleAttr, AnimatedString); | |
| 222 s_cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor); | |
| 223 s_cssPropertyMap.set(color_interpolationAttr, AnimatedString); | |
| 224 s_cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString); | |
| 225 s_cssPropertyMap.set(color_profileAttr, AnimatedString); | |
| 226 s_cssPropertyMap.set(color_renderingAttr, AnimatedString); | |
| 227 s_cssPropertyMap.set(cursorAttr, AnimatedString); | |
| 228 s_cssPropertyMap.set(displayAttr, AnimatedString); | |
| 229 s_cssPropertyMap.set(dominant_baselineAttr, AnimatedString); | |
| 230 s_cssPropertyMap.set(fillAttr, AnimatedColor); | |
| 231 s_cssPropertyMap.set(fill_opacityAttr, AnimatedNumber); | |
| 232 s_cssPropertyMap.set(fill_ruleAttr, AnimatedString); | |
| 233 s_cssPropertyMap.set(filterAttr, AnimatedString); | |
| 234 s_cssPropertyMap.set(flood_colorAttr, AnimatedColor); | |
| 235 s_cssPropertyMap.set(flood_opacityAttr, AnimatedNumber); | |
| 236 s_cssPropertyMap.set(font_familyAttr, AnimatedString); | |
| 237 s_cssPropertyMap.set(font_sizeAttr, AnimatedLength); | |
| 238 s_cssPropertyMap.set(font_stretchAttr, AnimatedString); | |
| 239 s_cssPropertyMap.set(font_styleAttr, AnimatedString); | |
| 240 s_cssPropertyMap.set(font_variantAttr, AnimatedString); | |
| 241 s_cssPropertyMap.set(font_weightAttr, AnimatedString); | |
| 242 s_cssPropertyMap.set(image_renderingAttr, AnimatedString); | |
| 243 s_cssPropertyMap.set(kerningAttr, AnimatedLength); | |
| 244 s_cssPropertyMap.set(letter_spacingAttr, AnimatedLength); | |
| 245 s_cssPropertyMap.set(lighting_colorAttr, AnimatedColor); | |
| 246 s_cssPropertyMap.set(marker_endAttr, AnimatedString); | |
| 247 s_cssPropertyMap.set(marker_midAttr, AnimatedString); | |
| 248 s_cssPropertyMap.set(marker_startAttr, AnimatedString); | |
| 249 s_cssPropertyMap.set(maskAttr, AnimatedString); | |
| 250 s_cssPropertyMap.set(mask_typeAttr, AnimatedString); | |
| 251 s_cssPropertyMap.set(opacityAttr, AnimatedNumber); | |
| 252 s_cssPropertyMap.set(overflowAttr, AnimatedString); | |
| 253 s_cssPropertyMap.set(pointer_eventsAttr, AnimatedString); | |
| 254 s_cssPropertyMap.set(shape_renderingAttr, AnimatedString); | |
| 255 s_cssPropertyMap.set(stop_colorAttr, AnimatedColor); | |
| 256 s_cssPropertyMap.set(stop_opacityAttr, AnimatedNumber); | |
| 257 s_cssPropertyMap.set(strokeAttr, AnimatedColor); | |
| 258 s_cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList); | |
| 259 s_cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength); | |
| 260 s_cssPropertyMap.set(stroke_linecapAttr, AnimatedString); | |
| 261 s_cssPropertyMap.set(stroke_linejoinAttr, AnimatedString); | |
| 262 s_cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber); | |
| 263 s_cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber); | |
| 264 s_cssPropertyMap.set(stroke_widthAttr, AnimatedLength); | |
| 265 s_cssPropertyMap.set(text_anchorAttr, AnimatedString); | |
| 266 s_cssPropertyMap.set(text_decorationAttr, AnimatedString); | |
| 267 s_cssPropertyMap.set(text_renderingAttr, AnimatedString); | |
| 268 s_cssPropertyMap.set(vector_effectAttr, AnimatedString); | |
| 269 s_cssPropertyMap.set(visibilityAttr, AnimatedString); | |
| 270 s_cssPropertyMap.set(word_spacingAttr, AnimatedLength); | |
| 271 return s_cssPropertyMap; | |
| 272 } | |
| 273 | |
| 274 void SVGStyledElement::animatedPropertyTypeForAttribute(const QualifiedName& att
rName, Vector<AnimatedPropertyType>& propertyTypes) | |
| 275 { | |
| 276 SVGElement::animatedPropertyTypeForAttribute(attrName, propertyTypes); | |
| 277 if (!propertyTypes.isEmpty()) | |
| 278 return; | |
| 279 | |
| 280 AttributeToPropertyTypeMap& cssPropertyTypeMap = cssPropertyToTypeMap(); | |
| 281 if (cssPropertyTypeMap.contains(attrName)) | |
| 282 propertyTypes.append(cssPropertyTypeMap.get(attrName)); | |
| 283 } | |
| 284 | |
| 285 bool SVGStyledElement::isAnimatableCSSProperty(const QualifiedName& attrName) | |
| 286 { | |
| 287 return cssPropertyToTypeMap().contains(attrName); | |
| 288 } | |
| 289 | |
| 290 bool SVGStyledElement::isPresentationAttribute(const QualifiedName& name) const | |
| 291 { | |
| 292 if (SVGStyledElement::cssPropertyIdForSVGAttributeName(name) > 0) | |
| 293 return true; | |
| 294 return SVGElement::isPresentationAttribute(name); | |
| 295 } | |
| 296 | |
| 297 void SVGStyledElement::collectStyleForPresentationAttribute(const QualifiedName&
name, const AtomicString& value, MutableStylePropertySet* style) | |
| 298 { | |
| 299 CSSPropertyID propertyID = SVGStyledElement::cssPropertyIdForSVGAttributeNam
e(name); | |
| 300 if (propertyID > 0) | |
| 301 addPropertyToPresentationAttributeStyle(style, propertyID, value); | |
| 302 } | |
| 303 | |
| 304 void SVGStyledElement::parseAttribute(const QualifiedName& name, const AtomicStr
ing& value) | |
| 305 { | |
| 306 // SVG animation has currently requires special storage of values so we set | |
| 307 // the className here. svgAttributeChanged actually causes the resulting | |
| 308 // style updates (instead of Element::parseAttribute). We don't | |
| 309 // tell Element about the change to avoid parsing the class list twice | |
| 310 if (name == HTMLNames::classAttr) { | |
| 311 setClassNameBaseValue(value); | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 // id is handled by Element which SVGElement inherits from | |
| 316 SVGElement::parseAttribute(name, value); | |
| 317 } | |
| 318 | |
| 319 bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName) | |
| 320 { | |
| 321 return isIdAttributeName(attrName); | |
| 322 } | |
| 323 | |
| 324 void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName) | |
| 325 { | |
| 326 CSSPropertyID propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(at
trName); | |
| 327 if (propId > 0) { | |
| 328 SVGElementInstance::invalidateAllInstancesOfElement(this); | |
| 329 return; | |
| 330 } | |
| 331 | |
| 332 if (attrName == HTMLNames::classAttr) { | |
| 333 classAttributeChanged(classNameCurrentValue()); | |
| 334 SVGElementInstance::invalidateAllInstancesOfElement(this); | |
| 335 return; | |
| 336 } | |
| 337 | |
| 338 if (isIdAttributeName(attrName)) { | |
| 339 RenderObject* object = renderer(); | |
| 340 // Notify resources about id changes, this is important as we cache reso
urces by id in SVGDocumentExtensions | |
| 341 if (object && object->isSVGResourceContainer()) | |
| 342 object->toRenderSVGResourceContainer()->idChanged(); | |
| 343 if (inDocument()) | |
| 344 buildPendingResourcesIfNeeded(); | |
| 345 SVGElementInstance::invalidateAllInstancesOfElement(this); | |
| 346 return; | |
| 347 } | |
| 348 } | |
| 349 | |
| 350 Node::InsertionNotificationRequest SVGStyledElement::insertedInto(ContainerNode*
rootParent) | |
| 351 { | |
| 352 SVGElement::insertedInto(rootParent); | |
| 353 updateRelativeLengthsInformation(); | |
| 354 buildPendingResourcesIfNeeded(); | |
| 355 return InsertionDone; | |
| 356 } | |
| 357 | |
| 358 void SVGStyledElement::buildPendingResourcesIfNeeded() | |
| 359 { | |
| 360 Document* document = this->document(); | |
| 361 if (!needsPendingResourceHandling() || !document || !inDocument() || isInSha
dowTree()) | |
| 362 return; | |
| 363 | |
| 364 SVGDocumentExtensions* extensions = document->accessSVGExtensions(); | |
| 365 String resourceId = getIdAttribute(); | |
| 366 if (!extensions->hasPendingResource(resourceId)) | |
| 367 return; | |
| 368 | |
| 369 // Mark pending resources as pending for removal. | |
| 370 extensions->markPendingResourcesForRemoval(resourceId); | |
| 371 | |
| 372 // Rebuild pending resources for each client of a pending resource that is b
eing removed. | |
| 373 while (Element* clientElement = extensions->removeElementFromPendingResource
sForRemoval(resourceId)) { | |
| 374 ASSERT(clientElement->hasPendingResources()); | |
| 375 if (clientElement->hasPendingResources()) { | |
| 376 clientElement->buildPendingResource(); | |
| 377 extensions->clearHasPendingResourcesIfPossible(clientElement); | |
| 378 } | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 void SVGStyledElement::removedFrom(ContainerNode* rootParent) | |
| 383 { | |
| 384 if (rootParent->inDocument()) | |
| 385 updateRelativeLengthsInformation(false, this); | |
| 386 SVGElement::removedFrom(rootParent); | |
| 387 SVGElementInstance::invalidateAllInstancesOfElement(this); | |
| 388 } | |
| 389 | |
| 390 void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange,
Node* afterChange, int childCountDelta) | |
| 391 { | |
| 392 SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, chil
dCountDelta); | |
| 393 | |
| 394 // Invalidate all SVGElementInstances associated with us | |
| 395 if (!changedByParser) | |
| 396 SVGElementInstance::invalidateAllInstancesOfElement(this); | |
| 397 } | |
| 398 | |
| 399 PassRefPtr<CSSValue> SVGStyledElement::getPresentationAttribute(const String& na
me) | |
| 400 { | |
| 401 if (!hasAttributesWithoutUpdate()) | |
| 402 return 0; | |
| 403 | |
| 404 QualifiedName attributeName(nullAtom, name, nullAtom); | |
| 405 const Attribute* attr = getAttributeItem(attributeName); | |
| 406 if (!attr) | |
| 407 return 0; | |
| 408 | |
| 409 RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(SVGA
ttributeMode); | |
| 410 CSSPropertyID propertyID = SVGStyledElement::cssPropertyIdForSVGAttributeNam
e(attr->name()); | |
| 411 style->setProperty(propertyID, attr->value()); | |
| 412 RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID); | |
| 413 return cssValue ? cssValue->cloneForCSSOM() : 0; | |
| 414 } | |
| 415 | |
| 416 bool SVGStyledElement::instanceUpdatesBlocked() const | |
| 417 { | |
| 418 return hasSVGRareData() && svgRareData()->instanceUpdatesBlocked(); | |
| 419 } | |
| 420 | |
| 421 void SVGStyledElement::setInstanceUpdatesBlocked(bool value) | |
| 422 { | |
| 423 if (hasSVGRareData()) | |
| 424 svgRareData()->setInstanceUpdatesBlocked(value); | |
| 425 } | |
| 426 | |
| 427 AffineTransform SVGStyledElement::localCoordinateSpaceTransform(SVGLocatable::CT
MScope) const | |
| 428 { | |
| 429 // To be overriden by SVGStyledLocatableElement/SVGGraphicsElement (or as sp
ecial case SVGTextElement and SVGPatternElement) | |
| 430 return AffineTransform(); | |
| 431 } | |
| 432 | |
| 433 void SVGStyledElement::updateRelativeLengthsInformation(bool hasRelativeLengths,
SVGStyledElement* element) | |
| 434 { | |
| 435 // If we're not yet in a document, this function will be called again from i
nsertedInto(). Do nothing now. | |
| 436 if (!inDocument()) | |
| 437 return; | |
| 438 | |
| 439 // An element wants to notify us that its own relative lengths state changed
. | |
| 440 // Register it in the relative length map, and register us in the parent rel
ative length map. | |
| 441 // Register the parent in the grandparents map, etc. Repeat procedure until
the root of the SVG tree. | |
| 442 | |
| 443 if (hasRelativeLengths) | |
| 444 m_elementsWithRelativeLengths.add(element); | |
| 445 else { | |
| 446 if (!m_elementsWithRelativeLengths.contains(element)) { | |
| 447 // We were never registered. Do nothing. | |
| 448 return; | |
| 449 } | |
| 450 | |
| 451 m_elementsWithRelativeLengths.remove(element); | |
| 452 } | |
| 453 | |
| 454 // Find first styled parent node, and notify it that we've changed our relat
ive length state. | |
| 455 ContainerNode* node = parentNode(); | |
| 456 while (node) { | |
| 457 if (!node->isSVGElement()) | |
| 458 break; | |
| 459 | |
| 460 SVGElement* element = toSVGElement(node); | |
| 461 if (!element->isSVGStyledElement()) { | |
| 462 node = node->parentNode(); | |
| 463 continue; | |
| 464 } | |
| 465 | |
| 466 // Register us in the parent element map. | |
| 467 toSVGStyledElement(element)->updateRelativeLengthsInformation(hasRelativ
eLengths, this); | |
| 468 break; | |
| 469 } | |
| 470 } | |
| 471 | |
| 472 } | |
| OLD | NEW |