Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1838)

Unified Diff: Source/core/svg/SVGElement.cpp

Issue 21042009: [SVG2] Merge SVGStyledElement into SVGElement (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase on master Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/svg/SVGElement.h ('k') | Source/core/svg/SVGElement.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/svg/SVGElement.cpp
diff --git a/Source/core/svg/SVGElement.cpp b/Source/core/svg/SVGElement.cpp
index 70cb07169cb099e0eb4c731836af9e19ad070e85..0d811ffd597e6402f0cfeb8256840aa13174b65b 100644
--- a/Source/core/svg/SVGElement.cpp
+++ b/Source/core/svg/SVGElement.cpp
@@ -31,26 +31,50 @@
#include "XMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
#include "core/css/CSSCursorImageValue.h"
+#include "core/css/CSSParser.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/Document.h"
#include "core/dom/Event.h"
#include "core/dom/NodeRenderingContext.h"
+#include "core/dom/NodeTraversal.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/rendering/RenderObject.h"
+#include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/svg/SVGCursorElement.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGElementRareData.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGSVGElement.h"
+#include "core/svg/SVGUseElement.h"
namespace WebCore {
+// Animated property definitions
+DEFINE_ANIMATED_STRING(SVGElement, HTMLNames::classAttr, ClassName, className)
+
+BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGElement)
+ REGISTER_LOCAL_ANIMATED_PROPERTY(className)
+END_REGISTER_ANIMATED_PROPERTIES
+
using namespace HTMLNames;
+using namespace SVGNames;
+
+void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName)
+{
+ // FIXME: when CSS supports "transform-origin" the special case for transform_originAttr can be removed.
+ CSSPropertyID propertyId = cssPropertyID(attrName.localName());
+ if (!propertyId && attrName == transform_originAttr)
+ propertyId = CSSPropertyWebkitTransformOrigin; // cssPropertyID("-webkit-transform-origin")
+ ASSERT(propertyId > 0);
+ propertyNameToIdMap->set(attrName.localName().impl(), propertyId);
+}
SVGElement::SVGElement(const QualifiedName& tagName, Document* document, ConstructionType constructionType)
: Element(tagName, document, constructionType)
{
ScriptWrappable::init(this);
+ registerAnimatedPropertiesForSVGElement();
setHasCustomStyleCallbacks();
}
@@ -82,6 +106,10 @@ SVGElement::~SVGElement()
// modifying the rare data map. Do not rely on the existing iterator.
ASSERT(rareDataMap.contains(this));
rareDataMap.remove(this);
+ // Clear HasSVGRareData flag now so that we are in a consistent state when
+ // calling rebuildAllElementReferencesForTarget() and
+ // removeAllElementReferencesForTarget() below.
+ clearHasSVGRareData();
}
ASSERT(document());
document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
@@ -102,6 +130,43 @@ void SVGElement::willRecalcStyle(StyleChange change)
svgRareData()->setNeedsOverrideComputedStyleUpdate();
}
+void SVGElement::buildPendingResourcesIfNeeded()
+{
+ Document* document = this->document();
+ if (!needsPendingResourceHandling() || !document || !inDocument() || isInShadowTree())
+ return;
+
+ SVGDocumentExtensions* extensions = document->accessSVGExtensions();
+ String resourceId = getIdAttribute();
+ if (!extensions->hasPendingResource(resourceId))
+ return;
+
+ // Mark pending resources as pending for removal.
+ extensions->markPendingResourcesForRemoval(resourceId);
+
+ // Rebuild pending resources for each client of a pending resource that is being removed.
+ while (Element* clientElement = extensions->removeElementFromPendingResourcesForRemoval(resourceId)) {
+ ASSERT(clientElement->hasPendingResources());
+ if (clientElement->hasPendingResources()) {
+ clientElement->buildPendingResource();
+ extensions->clearHasPendingResourcesIfPossible(clientElement);
+ }
+ }
+}
+
+bool SVGElement::rendererIsNeededInternal(const NodeRenderingContext& context)
+{
+ // http://www.w3.org/TR/SVG/extend.html#PrivateData
+ // Prevent anything other than SVG renderers from appearing in our render tree
+ // Spec: SVG allows inclusion of elements from foreign namespaces anywhere
+ // with the SVG content. In general, the SVG user agent will include the unknown
+ // elements in the DOM but will otherwise ignore unknown elements.
+ if (!parentOrShadowHostElement() || parentOrShadowHostElement()->isSVGElement())
+ return Element::rendererIsNeeded(context);
+
+ return false;
+}
+
SVGElementRareData* SVGElement::svgRareData() const
{
ASSERT(hasSVGRareData());
@@ -170,6 +235,85 @@ bool SVGElement::isSupported(StringImpl* feature, StringImpl* version) const
return DOMImplementation::hasFeature(feature, version);
}
+String SVGElement::title() const
+{
+ // According to spec, we should not return titles when hovering over root <svg> elements (those
+ // <title> elements are the title of the document, not a tooltip) so we instantly return.
+ if (isOutermostSVGSVGElement())
+ return String();
+
+ // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title.
+ if (isInShadowTree()) {
+ Element* shadowHostElement = toShadowRoot(treeScope()->rootNode())->host();
+ // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do
+ // have should be a use. The assert and following test is here to catch future shadow DOM changes
+ // that do enable SVG in a shadow tree.
+ ASSERT(!shadowHostElement || shadowHostElement->hasTagName(SVGNames::useTag));
+ if (shadowHostElement && shadowHostElement->hasTagName(SVGNames::useTag)) {
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(shadowHostElement);
+
+ // If the <use> title is not empty we found the title to use.
+ String useTitle(useElement->title());
+ if (!useTitle.isEmpty())
+ return useTitle;
+ }
+ }
+
+ // If we aren't an instance in a <use> or the <use> title was not found, then find the first
+ // <title> child of this element.
+ Element* titleElement = ElementTraversal::firstWithin(this);
+ for (; titleElement; titleElement = ElementTraversal::nextSkippingChildren(titleElement, this)) {
+ if (titleElement->hasTagName(SVGNames::titleTag) && titleElement->isSVGElement())
+ break;
+ }
+
+ // If a title child was found, return the text contents.
+ if (titleElement)
+ return titleElement->innerText();
+
+ // Otherwise return a null/empty string.
+ return String();
+}
+
+PassRefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name)
+{
+ if (!hasAttributesWithoutUpdate())
+ return 0;
+
+ QualifiedName attributeName(nullAtom, name, nullAtom);
+ const Attribute* attr = getAttributeItem(attributeName);
+ if (!attr)
+ return 0;
+
+ RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(SVGAttributeMode);
+ CSSPropertyID propertyID = SVGElement::cssPropertyIdForSVGAttributeName(attr->name());
+ style->setProperty(propertyID, attr->value());
+ RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID);
+ return cssValue ? cssValue->cloneForCSSOM() : 0;
+}
+
+bool SVGElement::isKnownAttribute(const QualifiedName& attrName)
+{
+ return isIdAttributeName(attrName);
+}
+
+bool SVGElement::instanceUpdatesBlocked() const
+{
+ return hasSVGRareData() && svgRareData()->instanceUpdatesBlocked();
+}
+
+void SVGElement::setInstanceUpdatesBlocked(bool value)
+{
+ if (hasSVGRareData())
+ svgRareData()->setInstanceUpdatesBlocked(value);
+}
+
+AffineTransform SVGElement::localCoordinateSpaceTransform(SVGLocatable::CTMScope) const
+{
+ // To be overriden by SVGGraphicsElement (or as special case SVGTextElement and SVGPatternElement)
+ return AffineTransform();
+}
+
String SVGElement::xmlbase() const
{
return fastGetAttribute(XMLNames::baseAttr);
@@ -180,16 +324,148 @@ void SVGElement::setXmlbase(const String& value)
setAttribute(XMLNames::baseAttr, value);
}
+Node::InsertionNotificationRequest SVGElement::insertedInto(ContainerNode* rootParent)
+{
+ Element::insertedInto(rootParent);
+ updateRelativeLengthsInformation();
+ buildPendingResourcesIfNeeded();
+ return InsertionDone;
+}
+
void SVGElement::removedFrom(ContainerNode* rootParent)
{
bool wasInDocument = rootParent->inDocument();
+ if (wasInDocument)
+ updateRelativeLengthsInformation(false, this);
+
Element::removedFrom(rootParent);
if (wasInDocument) {
document()->accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
}
+
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
+}
+
+void SVGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ Element::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ // Invalidate all SVGElementInstances associated with us.
+ if (!changedByParser)
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
+}
+
+CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attrName)
+{
+ if (!attrName.namespaceURI().isNull())
+ return CSSPropertyInvalid;
+
+ static HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap = 0;
+ if (!propertyNameToIdMap) {
+ propertyNameToIdMap = new HashMap<StringImpl*, CSSPropertyID>;
+ // This is a list of all base CSS and SVG CSS properties which are exposed as SVG XML attributes
+ mapAttributeToCSSProperty(propertyNameToIdMap, alignment_baselineAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, baseline_shiftAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, buffered_renderingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, clipAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, clip_pathAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, clip_ruleAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::colorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filtersAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::directionAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, displayAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, dominant_baselineAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, enable_backgroundAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, fillAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, fill_opacityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, fill_ruleAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, filterAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, flood_colorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, flood_opacityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_familyAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_sizeAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_stretchAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_styleAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_variantAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, font_weightAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_horizontalAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_verticalAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, image_renderingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, kerningAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, letter_spacingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, lighting_colorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, marker_endAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, marker_midAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, marker_startAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, maskAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, mask_typeAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, opacityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, overflowAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, pointer_eventsAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, shape_renderingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stop_colorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stop_opacityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, strokeAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dasharrayAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dashoffsetAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linecapAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linejoinAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_miterlimitAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_opacityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, stroke_widthAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, text_anchorAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, text_decorationAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, text_renderingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, transform_originAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, unicode_bidiAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, vector_effectAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, visibilityAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, word_spacingAttr);
+ mapAttributeToCSSProperty(propertyNameToIdMap, writing_modeAttr);
+ }
+
+ return propertyNameToIdMap->get(attrName.localName().impl());
+}
+
+void SVGElement::updateRelativeLengthsInformation(bool hasRelativeLengths, SVGElement* element)
+{
+ // If we're not yet in a document, this function will be called again from insertedInto(). Do nothing now.
+ if (!inDocument())
+ return;
+
+ // An element wants to notify us that its own relative lengths state changed.
+ // Register it in the relative length map, and register us in the parent relative length map.
+ // Register the parent in the grandparents map, etc. Repeat procedure until the root of the SVG tree.
+ if (hasRelativeLengths) {
+ m_elementsWithRelativeLengths.add(element);
+ } else {
+ if (!m_elementsWithRelativeLengths.contains(element)) {
+ // We were never registered. Do nothing.
+ return;
+ }
+
+ m_elementsWithRelativeLengths.remove(element);
+ }
+
+ // Find first styled parent node, and notify it that we've changed our relative length state.
+ ContainerNode* node = parentNode();
+ while (node) {
+ if (!node->isSVGElement())
+ break;
+
+ SVGElement* element = toSVGElement(node);
+
+ // Register us in the parent element map.
+ element->updateRelativeLengthsInformation(hasRelativeLengths, this);
+ break;
+ }
}
SVGSVGElement* SVGElement::ownerSVGElement() const
@@ -338,14 +614,110 @@ void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& v
setAttributeEventListener(eventNames().focusoutEvent, createAttributeEventListener(this, name, value));
else if (name == SVGNames::onactivateAttr)
setAttributeEventListener(eventNames().DOMActivateEvent, createAttributeEventListener(this, name, value));
- else if (SVGLangSpace::parseAttribute(name, value)) {
+ else if (name == HTMLNames::classAttr) {
+ // SVG animation has currently requires special storage of values so we set
+ // the className here. svgAttributeChanged actually causes the resulting
+ // style updates (instead of Element::parseAttribute). We don't
+ // tell Element about the change to avoid parsing the class list twice
+ setClassNameBaseValue(value);
+ } else if (SVGLangSpace::parseAttribute(name, value)) {
} else
Element::parseAttribute(name, value);
}
+typedef HashMap<QualifiedName, AnimatedPropertyType> AttributeToPropertyTypeMap;
+static inline AttributeToPropertyTypeMap& cssPropertyToTypeMap()
+{
+ DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_cssPropertyMap, ());
+
+ if (!s_cssPropertyMap.isEmpty())
+ return s_cssPropertyMap;
+
+ // Fill the map for the first use.
+ s_cssPropertyMap.set(alignment_baselineAttr, AnimatedString);
+ s_cssPropertyMap.set(baseline_shiftAttr, AnimatedString);
+ s_cssPropertyMap.set(buffered_renderingAttr, AnimatedString);
+ s_cssPropertyMap.set(clipAttr, AnimatedRect);
+ s_cssPropertyMap.set(clip_pathAttr, AnimatedString);
+ s_cssPropertyMap.set(clip_ruleAttr, AnimatedString);
+ s_cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor);
+ s_cssPropertyMap.set(color_interpolationAttr, AnimatedString);
+ s_cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString);
+ s_cssPropertyMap.set(color_profileAttr, AnimatedString);
+ s_cssPropertyMap.set(color_renderingAttr, AnimatedString);
+ s_cssPropertyMap.set(cursorAttr, AnimatedString);
+ s_cssPropertyMap.set(displayAttr, AnimatedString);
+ s_cssPropertyMap.set(dominant_baselineAttr, AnimatedString);
+ s_cssPropertyMap.set(fillAttr, AnimatedColor);
+ s_cssPropertyMap.set(fill_opacityAttr, AnimatedNumber);
+ s_cssPropertyMap.set(fill_ruleAttr, AnimatedString);
+ s_cssPropertyMap.set(filterAttr, AnimatedString);
+ s_cssPropertyMap.set(flood_colorAttr, AnimatedColor);
+ s_cssPropertyMap.set(flood_opacityAttr, AnimatedNumber);
+ s_cssPropertyMap.set(font_familyAttr, AnimatedString);
+ s_cssPropertyMap.set(font_sizeAttr, AnimatedLength);
+ s_cssPropertyMap.set(font_stretchAttr, AnimatedString);
+ s_cssPropertyMap.set(font_styleAttr, AnimatedString);
+ s_cssPropertyMap.set(font_variantAttr, AnimatedString);
+ s_cssPropertyMap.set(font_weightAttr, AnimatedString);
+ s_cssPropertyMap.set(image_renderingAttr, AnimatedString);
+ s_cssPropertyMap.set(kerningAttr, AnimatedLength);
+ s_cssPropertyMap.set(letter_spacingAttr, AnimatedLength);
+ s_cssPropertyMap.set(lighting_colorAttr, AnimatedColor);
+ s_cssPropertyMap.set(marker_endAttr, AnimatedString);
+ s_cssPropertyMap.set(marker_midAttr, AnimatedString);
+ s_cssPropertyMap.set(marker_startAttr, AnimatedString);
+ s_cssPropertyMap.set(maskAttr, AnimatedString);
+ s_cssPropertyMap.set(mask_typeAttr, AnimatedString);
+ s_cssPropertyMap.set(opacityAttr, AnimatedNumber);
+ s_cssPropertyMap.set(overflowAttr, AnimatedString);
+ s_cssPropertyMap.set(pointer_eventsAttr, AnimatedString);
+ s_cssPropertyMap.set(shape_renderingAttr, AnimatedString);
+ s_cssPropertyMap.set(stop_colorAttr, AnimatedColor);
+ s_cssPropertyMap.set(stop_opacityAttr, AnimatedNumber);
+ s_cssPropertyMap.set(strokeAttr, AnimatedColor);
+ s_cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList);
+ s_cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength);
+ s_cssPropertyMap.set(stroke_linecapAttr, AnimatedString);
+ s_cssPropertyMap.set(stroke_linejoinAttr, AnimatedString);
+ s_cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber);
+ s_cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber);
+ s_cssPropertyMap.set(stroke_widthAttr, AnimatedLength);
+ s_cssPropertyMap.set(text_anchorAttr, AnimatedString);
+ s_cssPropertyMap.set(text_decorationAttr, AnimatedString);
+ s_cssPropertyMap.set(text_renderingAttr, AnimatedString);
+ s_cssPropertyMap.set(vector_effectAttr, AnimatedString);
+ s_cssPropertyMap.set(visibilityAttr, AnimatedString);
+ s_cssPropertyMap.set(word_spacingAttr, AnimatedLength);
+ return s_cssPropertyMap;
+}
+
void SVGElement::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
{
localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
+ if (!propertyTypes.isEmpty())
+ return;
+
+ AttributeToPropertyTypeMap& cssPropertyTypeMap = cssPropertyToTypeMap();
+ if (cssPropertyTypeMap.contains(attributeName))
+ propertyTypes.append(cssPropertyTypeMap.get(attributeName));
+}
+
+bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attrName)
+{
+ return cssPropertyToTypeMap().contains(attrName);
+}
+
+bool SVGElement::isPresentationAttribute(const QualifiedName& name) const
+{
+ return cssPropertyIdForSVGAttributeName(name) > 0;
+}
+
+void SVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
+{
+ CSSPropertyID propertyID = cssPropertyIdForSVGAttributeName(name);
+ if (propertyID > 0)
+ addPropertyToPresentationAttributeStyle(style, propertyID, value);
}
bool SVGElement::haveLoadedRequiredResources()
@@ -365,13 +737,9 @@ static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SV
if (element->containingShadowRoot())
return;
- if (!element->isSVGStyledElement())
- return;
-
- SVGStyledElement* styledElement = toSVGStyledElement(element);
- ASSERT(!styledElement->instanceUpdatesBlocked());
+ ASSERT(!element->instanceUpdatesBlocked());
- instances = styledElement->instancesForElement();
+ instances = element->instancesForElement();
}
bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> prpListener, bool useCapture)
@@ -557,6 +925,32 @@ void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString&
svgAttributeChanged(name);
}
+void SVGElement::svgAttributeChanged(const QualifiedName& attrName)
+{
+ CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName);
+ if (propId > 0) {
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
+ return;
+ }
+
+ if (attrName == HTMLNames::classAttr) {
+ classAttributeChanged(classNameCurrentValue());
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
+ return;
+ }
+
+ if (isIdAttributeName(attrName)) {
+ RenderObject* object = renderer();
+ // Notify resources about id changes, this is important as we cache resources by id in SVGDocumentExtensions
+ if (object && object->isSVGResourceContainer())
+ object->toRenderSVGResourceContainer()->idChanged();
+ if (inDocument())
+ buildPendingResourcesIfNeeded();
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
+ return;
+ }
+}
+
void SVGElement::synchronizeAnimatedSVGAttribute(const QualifiedName& name) const
{
if (!elementData() || !elementData()->m_animatedSVGAttributesAreDirty)
@@ -570,12 +964,6 @@ void SVGElement::synchronizeAnimatedSVGAttribute(const QualifiedName& name) cons
nonConstThis->localAttributeToPropertyMap().synchronizeProperty(nonConstThis, name);
}
-SVGAttributeToPropertyMap& SVGElement::localAttributeToPropertyMap() const
-{
- DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, emptyMap, ());
- return emptyMap;
-}
-
void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement)
{
ASSERT(contextElement);
@@ -754,7 +1142,7 @@ bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const
}
if (name == classAttr)
- return isSVGStyledElement();
+ return true;
return animatableAttributes.contains(name);
}
« no previous file with comments | « Source/core/svg/SVGElement.h ('k') | Source/core/svg/SVGElement.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698