| 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 |