summaryrefslogtreecommitdiffstats
path: root/WebCore/svg/SVGStyledElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/svg/SVGStyledElement.cpp')
-rw-r--r--WebCore/svg/SVGStyledElement.cpp106
1 files changed, 66 insertions, 40 deletions
diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp
index 22c2008..9a3f950 100644
--- a/WebCore/svg/SVGStyledElement.cpp
+++ b/WebCore/svg/SVGStyledElement.cpp
@@ -41,8 +41,8 @@
#include "SVGNames.h"
#include "SVGRenderStyle.h"
#include "SVGRenderSupport.h"
-#include "SVGResource.h"
#include "SVGSVGElement.h"
+#include "SVGUseElement.h"
#include <wtf/Assertions.h>
namespace WebCore {
@@ -63,7 +63,50 @@ SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc)
SVGStyledElement::~SVGStyledElement()
{
- SVGResource::removeClient(this);
+}
+
+String SVGStyledElement::title() const
+{
+ // According to spec, we should not return titles when hovering over <svg> elements (those
+ // <title> elements are the title of the document, not a tooltip) so we instantly return.
+ if (hasTagName(SVGNames::svgTag))
+ return String();
+
+ // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title.
+ Node* parent = const_cast<SVGStyledElement*>(this);
+ while (parent) {
+ if (!parent->isShadowNode()) {
+ parent = parent->parentNode();
+ continue;
+ }
+
+ // Get the <use> element.
+ Node* shadowParent = parent->shadowParentNode();
+ if (shadowParent && shadowParent->isSVGElement() && shadowParent->hasTagName(SVGNames::useTag)) {
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(shadowParent);
+ // If the <use> title is not empty we found the title to use.
+ String useTitle(useElement->title());
+ if (useTitle.isEmpty())
+ break;
+ return useTitle;
+ }
+ parent = parent->parentNode();
+ }
+
+ // 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 = firstElementChild();
+ for (; titleElement; titleElement = titleElement->nextElementSibling()) {
+ 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();
}
bool SVGStyledElement::rendererIsNeeded(RenderStyle* style)
@@ -200,19 +243,21 @@ void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName)
if (attrName.matches(HTMLNames::classAttr))
classAttributeChanged(className());
+ RenderObject* object = renderer();
+
if (attrName == idAttributeName()) {
// Notify resources about id changes, this is important as we cache resources by id in SVGDocumentExtensions
- if (renderer() && renderer()->isSVGResource()) {
- RenderSVGResource* resource = renderer()->toRenderSVGResource();
- resource->idChanged();
- }
+ if (object && object->isSVGResourceContainer())
+ object->toRenderSVGResourceContainer()->idChanged();
}
- // If we're the child of a resource element, be sure to invalidate it.
- invalidateResourcesInAncestorChain();
+ if (!document()->parsing() && object) {
+ // If we're the child of a resource element, tell the resource (and eventually its resources) that we've changed.
+ invalidateResourcesInAncestorChain();
- // If the element is using resources, invalidate them.
- invalidateResources();
+ // If we're referencing resources, tell them we've changed.
+ deregisterFromResources(object);
+ }
// Invalidate all SVGElementInstances associated with us
SVGElementInstance::invalidateAllInstancesOfElement(this);
@@ -226,20 +271,6 @@ void SVGStyledElement::synchronizeProperty(const QualifiedName& attrName)
synchronizeClassName();
}
-void SVGStyledElement::invalidateResources()
-{
- RenderObject* object = renderer();
- if (!object)
- return;
-
- Document* document = this->document();
-
- if (document->parsing())
- return;
-
- deregisterFromResources(object);
-}
-
void SVGStyledElement::invalidateResourcesInAncestorChain() const
{
Node* node = parentNode();
@@ -248,25 +279,25 @@ void SVGStyledElement::invalidateResourcesInAncestorChain() const
break;
SVGElement* element = static_cast<SVGElement*>(node);
- if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0))
- styledElement->invalidateCanvasResources();
+ if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0)) {
+ styledElement->invalidateResourceClients();
+
+ // If we found the first resource in the ancestor chain, immediately stop.
+ break;
+ }
node = node->parentNode();
}
}
-void SVGStyledElement::invalidateCanvasResources()
+void SVGStyledElement::invalidateResourceClients()
{
RenderObject* object = renderer();
if (!object)
return;
- if (object->isSVGResource())
- object->toRenderSVGResource()->invalidateClients();
-
- // The following lines will be removed soon, once all resources are handled by renderers.
- if (SVGResource* resource = canvasResource(object))
- resource->invalidate();
+ if (object->isSVGResourceContainer())
+ object->toRenderSVGResourceContainer()->invalidateClients();
}
void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -274,7 +305,8 @@ void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange,
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
// Invalidate all SVGElementInstances associated with us
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ if (!changedByParser)
+ SVGElementInstance::invalidateAllInstancesOfElement(this);
}
PassRefPtr<RenderStyle> SVGStyledElement::resolveStyle(RenderStyle* parentStyle)
@@ -309,12 +341,6 @@ PassRefPtr<CSSValue> SVGStyledElement::getPresentationAttribute(const String& na
return cssSVGAttr->style()->getPropertyCSSValue(name);
}
-void SVGStyledElement::detach()
-{
- SVGResource::removeClient(this);
- SVGElement::detach();
-}
-
bool SVGStyledElement::instanceUpdatesBlocked() const
{
return hasRareSVGData() && rareSVGData()->instanceUpdatesBlocked();