OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> |
3 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2008 Apple Inc. All rights reserved. | 4 * Copyright (C) 2008 Apple Inc. All rights reserved. |
5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> | 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> |
6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> | 6 * Copyright (C) 2009 Cameron McCormack <cam@mcc.id.au> |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 PassRefPtr<SVGElement> SVGElement::create(const QualifiedName& tagName, Document
* document) | 81 PassRefPtr<SVGElement> SVGElement::create(const QualifiedName& tagName, Document
* document) |
82 { | 82 { |
83 return adoptRef(new SVGElement(tagName, document)); | 83 return adoptRef(new SVGElement(tagName, document)); |
84 } | 84 } |
85 | 85 |
86 SVGElement::~SVGElement() | 86 SVGElement::~SVGElement() |
87 { | 87 { |
88 if (!hasSVGRareData()) | 88 if (!hasSVGRareData()) |
89 ASSERT(!SVGElementRareData::rareDataMap().contains(this)); | 89 ASSERT(!SVGElementRareData::rareDataMap().contains(this)); |
90 else { | 90 else { |
91 ASSERT(document()); | |
92 SVGElementRareData::SVGElementRareDataMap& rareDataMap = SVGElementRareD
ata::rareDataMap(); | 91 SVGElementRareData::SVGElementRareDataMap& rareDataMap = SVGElementRareD
ata::rareDataMap(); |
93 SVGElementRareData::SVGElementRareDataMap::iterator it = rareDataMap.fin
d(this); | 92 SVGElementRareData::SVGElementRareDataMap::iterator it = rareDataMap.fin
d(this); |
94 ASSERT(it != rareDataMap.end()); | 93 ASSERT(it != rareDataMap.end()); |
95 | 94 |
96 SVGElementRareData* rareData = it->value; | 95 SVGElementRareData* rareData = it->value; |
97 rareData->destroyAnimatedSMILStyleProperties(); | 96 rareData->destroyAnimatedSMILStyleProperties(); |
98 if (SVGCursorElement* cursorElement = rareData->cursorElement()) | 97 if (SVGCursorElement* cursorElement = rareData->cursorElement()) |
99 cursorElement->removeClient(this); | 98 cursorElement->removeClient(this); |
100 if (CSSCursorImageValue* cursorImageValue = rareData->cursorImageValue()
) | 99 if (CSSCursorImageValue* cursorImageValue = rareData->cursorImageValue()
) |
101 cursorImageValue->removeReferencedElement(this); | 100 cursorImageValue->removeReferencedElement(this); |
102 | 101 |
103 delete rareData; | 102 delete rareData; |
104 | 103 |
105 // The rare data cleanup may have caused other SVG nodes to be deleted, | 104 // The rare data cleanup may have caused other SVG nodes to be deleted, |
106 // modifying the rare data map. Do not rely on the existing iterator. | 105 // modifying the rare data map. Do not rely on the existing iterator. |
107 ASSERT(rareDataMap.contains(this)); | 106 ASSERT(rareDataMap.contains(this)); |
108 rareDataMap.remove(this); | 107 rareDataMap.remove(this); |
109 // Clear HasSVGRareData flag now so that we are in a consistent state wh
en | 108 // Clear HasSVGRareData flag now so that we are in a consistent state wh
en |
110 // calling rebuildAllElementReferencesForTarget() and | 109 // calling rebuildAllElementReferencesForTarget() and |
111 // removeAllElementReferencesForTarget() below. | 110 // removeAllElementReferencesForTarget() below. |
112 clearHasSVGRareData(); | 111 clearHasSVGRareData(); |
113 } | 112 } |
114 ASSERT(document()); | 113 document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this)
; |
115 document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(this
); | 114 document().accessSVGExtensions()->removeAllElementReferencesForTarget(this); |
116 document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this)
; | |
117 } | 115 } |
118 | 116 |
119 void SVGElement::willRecalcStyle(StyleChange change) | 117 void SVGElement::willRecalcStyle(StyleChange change) |
120 { | 118 { |
121 // FIXME: This assumes that when shouldNotifyRendererWithIdenticalStyles() i
s true | 119 // FIXME: This assumes that when shouldNotifyRendererWithIdenticalStyles() i
s true |
122 // the change came from a SMIL animation, but what if there were non-SMIL ch
anges | 120 // the change came from a SMIL animation, but what if there were non-SMIL ch
anges |
123 // since then? I think we should remove the shouldNotifyRendererWithIdentica
lStyles | 121 // since then? I think we should remove the shouldNotifyRendererWithIdentica
lStyles |
124 // check. | 122 // check. |
125 if (!hasSVGRareData() || shouldNotifyRendererWithIdenticalStyles()) | 123 if (!hasSVGRareData() || shouldNotifyRendererWithIdenticalStyles()) |
126 return; | 124 return; |
127 // If the style changes because of a regular property change (not induced by
SMIL animations themselves) | 125 // If the style changes because of a regular property change (not induced by
SMIL animations themselves) |
128 // reset the "computed style without SMIL style properties", so the base val
ue change gets reflected. | 126 // reset the "computed style without SMIL style properties", so the base val
ue change gets reflected. |
129 if (change > NoChange || needsStyleRecalc()) | 127 if (change > NoChange || needsStyleRecalc()) |
130 svgRareData()->setNeedsOverrideComputedStyleUpdate(); | 128 svgRareData()->setNeedsOverrideComputedStyleUpdate(); |
131 } | 129 } |
132 | 130 |
133 void SVGElement::buildPendingResourcesIfNeeded() | 131 void SVGElement::buildPendingResourcesIfNeeded() |
134 { | 132 { |
135 Document* document = this->document(); | 133 Document& document = this->document(); |
136 if (!needsPendingResourceHandling() || !document || !inDocument() || isInSha
dowTree()) | 134 if (!needsPendingResourceHandling() || !inDocument() || isInShadowTree()) |
137 return; | 135 return; |
138 | 136 |
139 SVGDocumentExtensions* extensions = document->accessSVGExtensions(); | 137 SVGDocumentExtensions* extensions = document.accessSVGExtensions(); |
140 String resourceId = getIdAttribute(); | 138 String resourceId = getIdAttribute(); |
141 if (!extensions->hasPendingResource(resourceId)) | 139 if (!extensions->hasPendingResource(resourceId)) |
142 return; | 140 return; |
143 | 141 |
144 // Mark pending resources as pending for removal. | 142 // Mark pending resources as pending for removal. |
145 extensions->markPendingResourcesForRemoval(resourceId); | 143 extensions->markPendingResourcesForRemoval(resourceId); |
146 | 144 |
147 // Rebuild pending resources for each client of a pending resource that is b
eing removed. | 145 // Rebuild pending resources for each client of a pending resource that is b
eing removed. |
148 while (Element* clientElement = extensions->removeElementFromPendingResource
sForRemoval(resourceId)) { | 146 while (Element* clientElement = extensions->removeElementFromPendingResource
sForRemoval(resourceId)) { |
149 ASSERT(clientElement->hasPendingResources()); | 147 ASSERT(clientElement->hasPendingResources()); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 // This is true whenever this is the outermost SVG, even if there are HTML e
lements outside it | 205 // This is true whenever this is the outermost SVG, even if there are HTML e
lements outside it |
208 return !parentNode()->isSVGElement(); | 206 return !parentNode()->isSVGElement(); |
209 } | 207 } |
210 | 208 |
211 void SVGElement::reportAttributeParsingError(SVGParsingError error, const Qualif
iedName& name, const AtomicString& value) | 209 void SVGElement::reportAttributeParsingError(SVGParsingError error, const Qualif
iedName& name, const AtomicString& value) |
212 { | 210 { |
213 if (error == NoError) | 211 if (error == NoError) |
214 return; | 212 return; |
215 | 213 |
216 String errorString = "<" + tagName() + "> attribute " + name.toString() + "=
\"" + value + "\""; | 214 String errorString = "<" + tagName() + "> attribute " + name.toString() + "=
\"" + value + "\""; |
217 SVGDocumentExtensions* extensions = document()->accessSVGExtensions(); | 215 SVGDocumentExtensions* extensions = document().accessSVGExtensions(); |
218 | 216 |
219 if (error == NegativeValueForbiddenError) { | 217 if (error == NegativeValueForbiddenError) { |
220 extensions->reportError("Invalid negative value for " + errorString); | 218 extensions->reportError("Invalid negative value for " + errorString); |
221 return; | 219 return; |
222 } | 220 } |
223 | 221 |
224 if (error == ParsingAttributeFailedError) { | 222 if (error == ParsingAttributeFailedError) { |
225 extensions->reportError("Invalid value for " + errorString); | 223 extensions->reportError("Invalid value for " + errorString); |
226 return; | 224 return; |
227 } | 225 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 void SVGElement::removedFrom(ContainerNode* rootParent) | 333 void SVGElement::removedFrom(ContainerNode* rootParent) |
336 { | 334 { |
337 bool wasInDocument = rootParent->inDocument(); | 335 bool wasInDocument = rootParent->inDocument(); |
338 | 336 |
339 if (wasInDocument) | 337 if (wasInDocument) |
340 updateRelativeLengthsInformation(false, this); | 338 updateRelativeLengthsInformation(false, this); |
341 | 339 |
342 Element::removedFrom(rootParent); | 340 Element::removedFrom(rootParent); |
343 | 341 |
344 if (wasInDocument) { | 342 if (wasInDocument) { |
345 document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(
this); | 343 document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(t
his); |
346 document()->accessSVGExtensions()->removeAllElementReferencesForTarget(t
his); | 344 document().accessSVGExtensions()->removeAllElementReferencesForTarget(th
is); |
347 } | 345 } |
348 | 346 |
349 SVGElementInstance::invalidateAllInstancesOfElement(this); | 347 SVGElementInstance::invalidateAllInstancesOfElement(this); |
350 } | 348 } |
351 | 349 |
352 void SVGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node*
afterChange, int childCountDelta) | 350 void SVGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node*
afterChange, int childCountDelta) |
353 { | 351 { |
354 Element::childrenChanged(changedByParser, beforeChange, afterChange, childCo
untDelta); | 352 Element::childrenChanged(changedByParser, beforeChange, afterChange, childCo
untDelta); |
355 | 353 |
356 // Invalidate all SVGElementInstances associated with us. | 354 // Invalidate all SVGElementInstances associated with us. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 n = n->parentOrShadowHostNode(); | 492 n = n->parentOrShadowHostNode(); |
495 } | 493 } |
496 | 494 |
497 return 0; | 495 return 0; |
498 } | 496 } |
499 | 497 |
500 SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() | 498 SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() |
501 { | 499 { |
502 // This function is provided for use by SVGAnimatedProperty to avoid | 500 // This function is provided for use by SVGAnimatedProperty to avoid |
503 // global inclusion of core/dom/Document.h in SVG code. | 501 // global inclusion of core/dom/Document.h in SVG code. |
504 return document() ? document()->accessSVGExtensions() : 0; | 502 return document().accessSVGExtensions(); |
505 } | 503 } |
506 | 504 |
507 void SVGElement::mapInstanceToElement(SVGElementInstance* instance) | 505 void SVGElement::mapInstanceToElement(SVGElementInstance* instance) |
508 { | 506 { |
509 ASSERT(instance); | 507 ASSERT(instance); |
510 | 508 |
511 HashSet<SVGElementInstance*>& instances = ensureSVGRareData()->elementInstan
ces(); | 509 HashSet<SVGElementInstance*>& instances = ensureSVGRareData()->elementInstan
ces(); |
512 ASSERT(!instances.contains(instance)); | 510 ASSERT(!instances.contains(instance)); |
513 | 511 |
514 instances.add(instance); | 512 instances.add(instance); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 continue; | 849 continue; |
852 | 850 |
853 // Consider <svg onload="foo()"><image xlink:href="foo.png" externalReso
urcesRequired="true"/></svg>. | 851 // Consider <svg onload="foo()"><image xlink:href="foo.png" externalReso
urcesRequired="true"/></svg>. |
854 // If foo.png is not yet loaded, the first SVGLoad event will go to the
<svg> element, sent through | 852 // If foo.png is not yet loaded, the first SVGLoad event will go to the
<svg> element, sent through |
855 // Document::implicitClose(). Then the SVGLoad event will fire for <imag
e>, once its loaded. | 853 // Document::implicitClose(). Then the SVGLoad event will fire for <imag
e>, once its loaded. |
856 ASSERT(sendParentLoadEvents); | 854 ASSERT(sendParentLoadEvents); |
857 | 855 |
858 // If the load event was not sent yet by Document::implicitClose(), but
the <image> from the example | 856 // If the load event was not sent yet by Document::implicitClose(), but
the <image> from the example |
859 // above, just appeared, don't send the SVGLoad event to the outermost <
svg>, but wait for the document | 857 // above, just appeared, don't send the SVGLoad event to the outermost <
svg>, but wait for the document |
860 // to be "ready to render", first. | 858 // to be "ready to render", first. |
861 if (!document()->loadEventFinished()) | 859 if (!document().loadEventFinished()) |
862 break; | 860 break; |
863 } | 861 } |
864 } | 862 } |
865 | 863 |
866 void SVGElement::sendSVGLoadEventIfPossibleAsynchronously() | 864 void SVGElement::sendSVGLoadEventIfPossibleAsynchronously() |
867 { | 865 { |
868 svgLoadEventTimer()->startOneShot(0); | 866 svgLoadEventTimer()->startOneShot(0); |
869 } | 867 } |
870 | 868 |
871 void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*) | 869 void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 return svgChild->isValid(); | 910 return svgChild->isValid(); |
913 } | 911 } |
914 return false; | 912 return false; |
915 } | 913 } |
916 | 914 |
917 void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString&
newValue, AttributeModificationReason) | 915 void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString&
newValue, AttributeModificationReason) |
918 { | 916 { |
919 Element::attributeChanged(name, newValue); | 917 Element::attributeChanged(name, newValue); |
920 | 918 |
921 if (isIdAttributeName(name)) | 919 if (isIdAttributeName(name)) |
922 document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(
this); | 920 document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(t
his); |
923 | 921 |
924 // Changes to the style attribute are processed lazily (see Element::getAttr
ibute() and related methods), | 922 // Changes to the style attribute are processed lazily (see Element::getAttr
ibute() and related methods), |
925 // so we don't want changes to the style attribute to result in extra work h
ere. | 923 // so we don't want changes to the style attribute to result in extra work h
ere. |
926 if (name != HTMLNames::styleAttr) | 924 if (name != HTMLNames::styleAttr) |
927 svgAttributeChanged(name); | 925 svgAttributeChanged(name); |
928 } | 926 } |
929 | 927 |
930 void SVGElement::svgAttributeChanged(const QualifiedName& attrName) | 928 void SVGElement::svgAttributeChanged(const QualifiedName& attrName) |
931 { | 929 { |
932 CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName
); | 930 CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName
); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 | 978 |
981 void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement) | 979 void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement) |
982 { | 980 { |
983 ASSERT(contextElement); | 981 ASSERT(contextElement); |
984 contextElement->synchronizeSystemLanguage(); | 982 contextElement->synchronizeSystemLanguage(); |
985 } | 983 } |
986 | 984 |
987 PassRefPtr<RenderStyle> SVGElement::customStyleForRenderer() | 985 PassRefPtr<RenderStyle> SVGElement::customStyleForRenderer() |
988 { | 986 { |
989 if (!correspondingElement()) | 987 if (!correspondingElement()) |
990 return document()->styleResolver()->styleForElement(this); | 988 return document().styleResolver()->styleForElement(this); |
991 | 989 |
992 RenderStyle* style = 0; | 990 RenderStyle* style = 0; |
993 if (Element* parent = parentOrShadowHostElement()) { | 991 if (Element* parent = parentOrShadowHostElement()) { |
994 if (RenderObject* renderer = parent->renderer()) | 992 if (RenderObject* renderer = parent->renderer()) |
995 style = renderer->style(); | 993 style = renderer->style(); |
996 } | 994 } |
997 | 995 |
998 return document()->styleResolver()->styleForElement(correspondingElement(),
style, DisallowStyleSharing); | 996 return document().styleResolver()->styleForElement(correspondingElement(), s
tyle, DisallowStyleSharing); |
999 } | 997 } |
1000 | 998 |
1001 MutableStylePropertySet* SVGElement::animatedSMILStyleProperties() const | 999 MutableStylePropertySet* SVGElement::animatedSMILStyleProperties() const |
1002 { | 1000 { |
1003 if (hasSVGRareData()) | 1001 if (hasSVGRareData()) |
1004 return svgRareData()->animatedSMILStyleProperties(); | 1002 return svgRareData()->animatedSMILStyleProperties(); |
1005 return 0; | 1003 return 0; |
1006 } | 1004 } |
1007 | 1005 |
1008 MutableStylePropertySet* SVGElement::ensureAnimatedSMILStyleProperties() | 1006 MutableStylePropertySet* SVGElement::ensureAnimatedSMILStyleProperties() |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 } | 1142 } |
1145 | 1143 |
1146 if (name == classAttr) | 1144 if (name == classAttr) |
1147 return true; | 1145 return true; |
1148 | 1146 |
1149 return animatableAttributes.contains(name); | 1147 return animatableAttributes.contains(name); |
1150 } | 1148 } |
1151 #endif | 1149 #endif |
1152 | 1150 |
1153 } | 1151 } |
OLD | NEW |