Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / svg / SVGTextPathElement.cpp
index 01817d5..9c3cd10 100644 (file)
  */
 
 #include "config.h"
-
-#if ENABLE(SVG)
 #include "SVGTextPathElement.h"
 
-#include "Attribute.h"
 #include "RenderSVGResource.h"
 #include "RenderSVGTextPath.h"
-#include "SVGElementInstance.h"
 #include "SVGNames.h"
+#include "XLinkNames.h"
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -45,7 +43,7 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPathElement)
     REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
 END_REGISTER_ANIMATED_PROPERTIES
 
-inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Document* document)
+inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Document& document)
     : SVGTextContentElement(tagName, document)
     , m_startOffset(LengthModeOther)
     , m_method(SVGTextPathMethodAlign)
@@ -55,45 +53,53 @@ inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Docu
     registerAnimatedPropertiesForSVGTextPathElement();
 }
 
-PassRefPtr<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document* document)
+Ref<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document& document)
+{
+    return adoptRef(*new SVGTextPathElement(tagName, document));
+}
+
+SVGTextPathElement::~SVGTextPathElement()
+{
+    clearResourceReferences();
+}
+
+void SVGTextPathElement::clearResourceReferences()
 {
-    return adoptRef(new SVGTextPathElement(tagName, document));
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 bool SVGTextPathElement::isSupportedAttribute(const QualifiedName& attrName)
 {
-    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
-    if (supportedAttributes.isEmpty()) {
+    static NeverDestroyed<HashSet<QualifiedName>> supportedAttributes;
+    if (supportedAttributes.get().isEmpty()) {
         SVGURIReference::addSupportedAttributes(supportedAttributes);
-        supportedAttributes.add(SVGNames::startOffsetAttr);
-        supportedAttributes.add(SVGNames::methodAttr);
-        supportedAttributes.add(SVGNames::spacingAttr);
+        supportedAttributes.get().add(SVGNames::startOffsetAttr);
+        supportedAttributes.get().add(SVGNames::methodAttr);
+        supportedAttributes.get().add(SVGNames::spacingAttr);
     }
-    return supportedAttributes.contains<QualifiedName, SVGAttributeHashTranslator>(attrName);
+    return supportedAttributes.get().contains<SVGAttributeHashTranslator>(attrName);
 }
 
-void SVGTextPathElement::parseMappedAttribute(Attribute* attr)
+void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
     SVGParsingError parseError = NoError;
-    const AtomicString& value = attr->value();
 
-    if (!isSupportedAttribute(attr->name()))
-        SVGTextContentElement::parseMappedAttribute(attr);
-    else if (attr->name() == SVGNames::startOffsetAttr)
+    if (name == SVGNames::startOffsetAttr)
         setStartOffsetBaseValue(SVGLength::construct(LengthModeOther, value, parseError));
-    else if (attr->name() == SVGNames::methodAttr) {
+    else if (name == SVGNames::methodAttr) {
         SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
         if (propertyValue > 0)
             setMethodBaseValue(propertyValue);
-    } else if (attr->name() == SVGNames::spacingAttr) {
+    } else if (name == SVGNames::spacingAttr) {
         SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
         if (propertyValue > 0)
             setSpacingBaseValue(propertyValue);
-    } else if (SVGURIReference::parseMappedAttribute(attr)) {
-    } else
-        ASSERT_NOT_REACHED();
+    }
+
+    reportAttributeParsingError(parseError, name, value);
 
-    reportAttributeParsingError(parseError, attr);
+    SVGTextContentElement::parseAttribute(name, value);
+    SVGURIReference::parseAttribute(name, value);
 }
 
 void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -103,58 +109,88 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
         return;
     }
 
-    SVGElementInstance::InvalidationGuard invalidationGuard(this);
+    InstanceInvalidationGuard guard(*this);
+
+    if (SVGURIReference::isKnownAttribute(attrName)) {
+        buildPendingResource();
+        return;
+    }
 
     if (attrName == SVGNames::startOffsetAttr)
         updateRelativeLengthsInformation();
 
-    if (RenderObject* object = renderer())
-        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
+    if (auto renderer = this->renderer())
+        RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
 }
 
-RenderObject* SVGTextPathElement::createRenderer(RenderArena* arena, RenderStyle*)
+RenderPtr<RenderElement> SVGTextPathElement::createElementRenderer(Ref<RenderStyle>&& style, const RenderTreePosition&)
 {
-    return new (arena) RenderSVGTextPath(this);
+    return createRenderer<RenderSVGTextPath>(*this, WTFMove(style));
 }
 
-bool SVGTextPathElement::childShouldCreateRenderer(Node* child) const
+bool SVGTextPathElement::childShouldCreateRenderer(const Node& child) const
 {
-    if (child->isTextNode()
-        || child->hasTagName(SVGNames::aTag)
-        || child->hasTagName(SVGNames::trefTag)
-        || child->hasTagName(SVGNames::tspanTag))
+    if (child.isTextNode()
+        || child.hasTagName(SVGNames::aTag)
+        || child.hasTagName(SVGNames::trefTag)
+        || child.hasTagName(SVGNames::tspanTag))
         return true;
 
     return false;
 }
 
-bool SVGTextPathElement::rendererIsNeeded(const NodeRenderingContext& context)
+bool SVGTextPathElement::rendererIsNeeded(const RenderStyle& style)
 {
     if (parentNode()
         && (parentNode()->hasTagName(SVGNames::aTag)
             || parentNode()->hasTagName(SVGNames::textTag)))
-        return StyledElement::rendererIsNeeded(context);
+        return StyledElement::rendererIsNeeded(style);
 
     return false;
 }
 
-void SVGTextPathElement::insertedIntoDocument()
+void SVGTextPathElement::buildPendingResource()
 {
-    SVGTextContentElement::insertedIntoDocument();
+    clearResourceReferences();
+    if (!inDocument())
+        return;
 
     String id;
-    Element* targetElement = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
-    if (!targetElement) {
-        if (hasPendingResources() || id.isEmpty())
+    Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
+    if (!target) {
+        // Do not register as pending if we are already pending this resource.
+        if (document().accessSVGExtensions().isPendingResource(this, id))
             return;
 
-        ASSERT(!hasPendingResources());
-        document()->accessSVGExtensions()->addPendingResource(id, this);
-        ASSERT(hasPendingResources());
-        return;
+        if (!id.isEmpty()) {
+            document().accessSVGExtensions().addPendingResource(id, this);
+            ASSERT(hasPendingResources());
+        }
+    } else if (target->hasTagName(SVGNames::pathTag)) {
+        // Register us with the target in the dependencies map. Any change of hrefElement
+        // that leads to relayout/repainting now informs us, so we can react to it.
+        document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target));
     }
 }
 
+Node::InsertionNotificationRequest SVGTextPathElement::insertedInto(ContainerNode& rootParent)
+{
+    SVGTextContentElement::insertedInto(rootParent);
+    return InsertionShouldCallFinishedInsertingSubtree;
+}
+
+void SVGTextPathElement::finishedInsertingSubtree()
+{
+    buildPendingResource();
+}
+
+void SVGTextPathElement::removedFrom(ContainerNode& rootParent)
+{
+    SVGTextContentElement::removedFrom(rootParent);
+    if (rootParent.inDocument())
+        clearResourceReferences();
+}
+
 bool SVGTextPathElement::selfHasRelativeLengths() const
 {
     return startOffset().isRelative()
@@ -162,5 +198,3 @@ bool SVGTextPathElement::selfHasRelativeLengths() const
 }
 
 }
-
-#endif // ENABLE(SVG)