diff options
Diffstat (limited to 'Source/WebCore/svg/SVGTRefElement.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGTRefElement.cpp | 129 |
1 files changed, 55 insertions, 74 deletions
diff --git a/Source/WebCore/svg/SVGTRefElement.cpp b/Source/WebCore/svg/SVGTRefElement.cpp index 012974bfc..a4ff46ab0 100644 --- a/Source/WebCore/svg/SVGTRefElement.cpp +++ b/Source/WebCore/svg/SVGTRefElement.cpp @@ -20,20 +20,16 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTRefElement.h" #include "EventListener.h" #include "EventNames.h" -#include "ExceptionCodePlaceholder.h" #include "MutationEvent.h" #include "RenderSVGInline.h" #include "RenderSVGInlineText.h" #include "RenderSVGResource.h" #include "ShadowRoot.h" #include "SVGDocument.h" -#include "SVGElementInstance.h" #include "SVGNames.h" #include "StyleInheritedData.h" #include "Text.h" @@ -49,57 +45,55 @@ BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTRefElement) REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextPositioningElement) END_REGISTER_ANIMATED_PROPERTIES -PassRefPtr<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document& document) +Ref<SVGTRefElement> SVGTRefElement::create(const QualifiedName& tagName, Document& document) { - RefPtr<SVGTRefElement> element = adoptRef(new SVGTRefElement(tagName, document)); + Ref<SVGTRefElement> element = adoptRef(*new SVGTRefElement(tagName, document)); element->ensureUserAgentShadowRoot(); - return element.release(); + return element; } -class SVGTRefTargetEventListener : public EventListener { +class SVGTRefTargetEventListener final : public EventListener { public: - static PassRefPtr<SVGTRefTargetEventListener> create(SVGTRefElement* trefElement) + static Ref<SVGTRefTargetEventListener> create(SVGTRefElement& trefElement) { - return adoptRef(new SVGTRefTargetEventListener(trefElement)); + return adoptRef(*new SVGTRefTargetEventListener(trefElement)); } static const SVGTRefTargetEventListener* cast(const EventListener* listener) { - return listener->type() == SVGTRefTargetEventListenerType - ? static_cast<const SVGTRefTargetEventListener*>(listener) : 0; + return listener->type() == SVGTRefTargetEventListenerType ? static_cast<const SVGTRefTargetEventListener*>(listener) : nullptr; } - void attach(PassRefPtr<Element> target); + void attach(RefPtr<Element>&& target); void detach(); bool isAttached() const { return m_target.get(); } private: - SVGTRefTargetEventListener(SVGTRefElement* trefElement); + explicit SVGTRefTargetEventListener(SVGTRefElement& trefElement); - virtual void handleEvent(ScriptExecutionContext*, Event*) override; - virtual bool operator==(const EventListener&) override; + void handleEvent(ScriptExecutionContext*, Event*) final; + bool operator==(const EventListener&) const final; - SVGTRefElement* m_trefElement; + SVGTRefElement& m_trefElement; RefPtr<Element> m_target; }; -SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement* trefElement) +SVGTRefTargetEventListener::SVGTRefTargetEventListener(SVGTRefElement& trefElement) : EventListener(SVGTRefTargetEventListenerType) , m_trefElement(trefElement) - , m_target(0) + , m_target(nullptr) { - ASSERT(m_trefElement); } -void SVGTRefTargetEventListener::attach(PassRefPtr<Element> target) +void SVGTRefTargetEventListener::attach(RefPtr<Element>&& target) { ASSERT(!isAttached()); ASSERT(target.get()); - ASSERT(target->inDocument()); + ASSERT(target->isConnected()); - target->addEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); - target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false); - m_target = target; + target->addEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false); + target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false); + m_target = WTFMove(target); } void SVGTRefTargetEventListener::detach() @@ -107,15 +101,15 @@ void SVGTRefTargetEventListener::detach() if (!isAttached()) return; - m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false); - m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false); - m_target.clear(); + m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false); + m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false); + m_target = nullptr; } -bool SVGTRefTargetEventListener::operator==(const EventListener& listener) +bool SVGTRefTargetEventListener::operator==(const EventListener& listener) const { if (const SVGTRefTargetEventListener* targetListener = SVGTRefTargetEventListener::cast(&listener)) - return m_trefElement == targetListener->m_trefElement; + return &m_trefElement == &targetListener->m_trefElement; return false; } @@ -123,15 +117,15 @@ void SVGTRefTargetEventListener::handleEvent(ScriptExecutionContext*, Event* eve { ASSERT(isAttached()); - if (event->type() == eventNames().DOMSubtreeModifiedEvent && m_trefElement != event->target()) - m_trefElement->updateReferencedText(m_target.get()); + if (event->type() == eventNames().DOMSubtreeModifiedEvent && &m_trefElement != event->target()) + m_trefElement.updateReferencedText(m_target.get()); else if (event->type() == eventNames().DOMNodeRemovedFromDocumentEvent) - m_trefElement->detachTarget(); + m_trefElement.detachTarget(); } inline SVGTRefElement::SVGTRefElement(const QualifiedName& tagName, Document& document) : SVGTextPositioningElement(tagName, document) - , m_targetListener(SVGTRefTargetEventListener::create(this)) + , m_targetListener(SVGTRefTargetEventListener::create(*this)) { ASSERT(hasTagName(SVGNames::trefTag)); registerAnimatedPropertiesForSVGTRefElement(); @@ -151,10 +145,10 @@ void SVGTRefElement::updateReferencedText(Element* target) ASSERT(shadowRoot()); ShadowRoot* root = shadowRoot(); if (!root->firstChild()) - root->appendChild(Text::create(document(), textContent), ASSERT_NO_EXCEPTION); + root->appendChild(Text::create(document(), textContent)); else { ASSERT(root->firstChild()->isTextNode()); - root->firstChild()->setTextContent(textContent, ASSERT_NO_EXCEPTION); + root->firstChild()->setTextContent(textContent); } } @@ -168,61 +162,40 @@ void SVGTRefElement::detachTarget() ASSERT(shadowRoot()); Node* container = shadowRoot()->firstChild(); if (container) - container->setTextContent(emptyContent, IGNORE_EXCEPTION); + container->setTextContent(emptyContent); - if (!inDocument()) + if (!isConnected()) return; // Mark the referenced ID as pending. String id; SVGURIReference::targetElementFromIRIString(href(), document(), &id); if (!id.isEmpty()) - document().accessSVGExtensions()->addPendingResource(id, this); -} - -bool SVGTRefElement::isSupportedAttribute(const QualifiedName& attrName) -{ - DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ()); - if (supportedAttributes.isEmpty()) - SVGURIReference::addSupportedAttributes(supportedAttributes); - return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName); + document().accessSVGExtensions().addPendingResource(id, this); } void SVGTRefElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { - if (!isSupportedAttribute(name)) { - SVGTextPositioningElement::parseAttribute(name, value); - return; - } - - if (SVGURIReference::parseAttribute(name, value)) - return; - - ASSERT_NOT_REACHED(); + SVGTextPositioningElement::parseAttribute(name, value); + SVGURIReference::parseAttribute(name, value); } void SVGTRefElement::svgAttributeChanged(const QualifiedName& attrName) { - if (!isSupportedAttribute(attrName)) { - SVGTextPositioningElement::svgAttributeChanged(attrName); - return; - } - - SVGElementInstance::InvalidationGuard invalidationGuard(this); - if (SVGURIReference::isKnownAttribute(attrName)) { + InstanceInvalidationGuard guard(*this); buildPendingResource(); if (auto renderer = this->renderer()) RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer); return; } - ASSERT_NOT_REACHED(); + SVGTextPositioningElement::svgAttributeChanged(attrName); } -RenderPtr<RenderElement> SVGTRefElement::createElementRenderer(PassRef<RenderStyle> style) +RenderPtr<RenderElement> SVGTRefElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&) { - return createRenderer<RenderSVGInline>(*this, std::move(style)); + return createRenderer<RenderSVGInline>(*this, WTFMove(style)); } bool SVGTRefElement::childShouldCreateRenderer(const Node& child) const @@ -245,13 +218,18 @@ bool SVGTRefElement::rendererIsNeeded(const RenderStyle& style) return false; } +void SVGTRefElement::clearTarget() +{ + m_targetListener->detach(); +} + void SVGTRefElement::buildPendingResource() { // Remove any existing event listener. m_targetListener->detach(); // If we're not yet in a document, this function will be called again from insertedInto(). - if (!inDocument()) + if (!isConnected()) return; String id; @@ -260,7 +238,7 @@ void SVGTRefElement::buildPendingResource() if (id.isEmpty()) return; - document().accessSVGExtensions()->addPendingResource(id, this); + document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); return; } @@ -270,7 +248,7 @@ void SVGTRefElement::buildPendingResource() // expects every element instance to have an associated shadow tree element - which is not the // case when we land here from SVGUseElement::buildShadowTree(). if (!isInShadowTree()) - m_targetListener->attach(target); + m_targetListener->attach(target.copyRef()); updateReferencedText(target.get()); } @@ -278,18 +256,21 @@ void SVGTRefElement::buildPendingResource() Node::InsertionNotificationRequest SVGTRefElement::insertedInto(ContainerNode& rootParent) { SVGElement::insertedInto(rootParent); - if (rootParent.inDocument()) - buildPendingResource(); + if (rootParent.isConnected()) + return InsertionShouldCallFinishedInsertingSubtree; return InsertionDone; } +void SVGTRefElement::finishedInsertingSubtree() +{ + buildPendingResource(); +} + void SVGTRefElement::removedFrom(ContainerNode& rootParent) { SVGElement::removedFrom(rootParent); - if (rootParent.inDocument()) + if (rootParent.isConnected()) m_targetListener->detach(); } } - -#endif // ENABLE(SVG) |