| Index: third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
|
| diff --git a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
|
| index 19320b754f5cc0b3889533f5aabd3af4f8bfbd37..4c001e3a876ff040345de6fbc3b04d8213dee8a6 100644
|
| --- a/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
|
| +++ b/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
|
| @@ -25,21 +25,21 @@
|
|
|
| #include "core/svg/animation/SVGSMILElement.h"
|
|
|
| +#include <algorithm>
|
| #include "bindings/core/v8/ScriptEventListener.h"
|
| #include "core/XLinkNames.h"
|
| #include "core/dom/Document.h"
|
| +#include "core/dom/IdTargetObserver.h"
|
| #include "core/dom/TaskRunnerHelper.h"
|
| #include "core/events/Event.h"
|
| #include "core/events/EventListener.h"
|
| #include "core/svg/SVGSVGElement.h"
|
| -#include "core/svg/SVGTreeScopeResources.h"
|
| #include "core/svg/SVGURIReference.h"
|
| #include "core/svg/animation/SMILTimeContainer.h"
|
| #include "platform/heap/Handle.h"
|
| #include "wtf/MathExtras.h"
|
| #include "wtf/StdLibExtras.h"
|
| #include "wtf/Vector.h"
|
| -#include <algorithm>
|
|
|
| namespace blink {
|
|
|
| @@ -145,6 +145,7 @@ SVGSMILElement::Condition::~Condition() = default;
|
|
|
| DEFINE_TRACE(SVGSMILElement::Condition) {
|
| visitor->trace(m_baseElement);
|
| + visitor->trace(m_baseIdObserver);
|
| visitor->trace(m_eventListener);
|
| }
|
|
|
| @@ -169,32 +170,23 @@ void SVGSMILElement::Condition::disconnectSyncBase(
|
| m_baseElement = nullptr;
|
| }
|
|
|
| -SVGElement* SVGSMILElement::Condition::lookupEventBase(
|
| - SVGSMILElement& timedElement) const {
|
| - Element* eventBase = m_baseID.isEmpty()
|
| - ? timedElement.targetElement()
|
| - : timedElement.treeScope().getElementById(m_baseID);
|
| - if (!eventBase || !eventBase->isSVGElement())
|
| - return nullptr;
|
| - return toSVGElement(eventBase);
|
| -}
|
| -
|
| void SVGSMILElement::Condition::connectEventBase(SVGSMILElement& timedElement) {
|
| DCHECK_EQ(m_type, EventBase);
|
| DCHECK(!m_baseElement);
|
| - SVGElement* eventBase = lookupEventBase(timedElement);
|
| - if (!eventBase) {
|
| - if (m_baseID.isEmpty())
|
| - return;
|
| - SVGTreeScopeResources& treeScopeResources =
|
| - timedElement.treeScope().ensureSVGTreeScopedResources();
|
| - if (!treeScopeResources.isElementPendingResource(timedElement, m_baseID))
|
| - treeScopeResources.addPendingResource(m_baseID, timedElement);
|
| - return;
|
| + Element* target;
|
| + if (m_baseID.isEmpty()) {
|
| + target = timedElement.targetElement();
|
| + } else {
|
| + target = SVGURIReference::observeTarget(
|
| + m_baseIdObserver, timedElement.treeScope(), m_baseID,
|
| + WTF::bind(&SVGSMILElement::buildPendingResource,
|
| + wrapWeakPersistent(&timedElement)));
|
| }
|
| + if (!target || !target->isSVGElement())
|
| + return;
|
| DCHECK(!m_eventListener);
|
| m_eventListener = ConditionEventListener::create(&timedElement, this);
|
| - m_baseElement = eventBase;
|
| + m_baseElement = toSVGElement(target);
|
| m_baseElement->addEventListener(m_name, m_eventListener, false);
|
| timedElement.addReferenceTo(m_baseElement);
|
| }
|
| @@ -202,6 +194,7 @@ void SVGSMILElement::Condition::connectEventBase(SVGSMILElement& timedElement) {
|
| void SVGSMILElement::Condition::disconnectEventBase(
|
| SVGSMILElement& timedElement) {
|
| DCHECK_EQ(m_type, EventBase);
|
| + SVGURIReference::unobserveTarget(m_baseIdObserver);
|
| if (!m_eventListener)
|
| return;
|
| m_baseElement->removeEventListener(m_name, m_eventListener, false);
|
| @@ -237,6 +230,7 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
|
| SVGSMILElement::~SVGSMILElement() {}
|
|
|
| void SVGSMILElement::clearResourceAndEventBaseReferences() {
|
| + SVGURIReference::unobserveTarget(m_targetIdObserver);
|
| removeAllOutgoingReferences();
|
| }
|
|
|
| @@ -248,6 +242,7 @@ void SVGSMILElement::clearConditions() {
|
|
|
| void SVGSMILElement::buildPendingResource() {
|
| clearResourceAndEventBaseReferences();
|
| + disconnectEventBaseConditions();
|
|
|
| if (!isConnected()) {
|
| // Reset the target element if we are no longer in the document.
|
| @@ -255,16 +250,13 @@ void SVGSMILElement::buildPendingResource() {
|
| return;
|
| }
|
|
|
| - AtomicString id;
|
| const AtomicString& href = SVGURIReference::legacyHrefString(*this);
|
| Element* target;
|
| - if (href.isEmpty())
|
| - target = parentNode() && parentNode()->isElementNode()
|
| - ? toElement(parentNode())
|
| - : nullptr;
|
| - else
|
| - target =
|
| - SVGURIReference::targetElementFromIRIString(href, treeScope(), &id);
|
| + if (href.isEmpty()) {
|
| + target = parentElement();
|
| + } else {
|
| + target = SVGURIReference::observeTarget(m_targetIdObserver, *this, href);
|
| + }
|
| SVGElement* svgTarget =
|
| target && target->isSVGElement() ? toSVGElement(target) : nullptr;
|
|
|
| @@ -274,16 +266,7 @@ void SVGSMILElement::buildPendingResource() {
|
| if (svgTarget != targetElement())
|
| setTargetElement(svgTarget);
|
|
|
| - if (!svgTarget) {
|
| - // Do not register as pending if we are already pending this resource.
|
| - if (treeScope().ensureSVGTreeScopedResources().isElementPendingResource(
|
| - *this, id))
|
| - return;
|
| - if (!id.isEmpty()) {
|
| - treeScope().ensureSVGTreeScopedResources().addPendingResource(id, *this);
|
| - DCHECK(hasPendingResources());
|
| - }
|
| - } else {
|
| + if (svgTarget) {
|
| // 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.
|
| @@ -1289,6 +1272,7 @@ void SVGSMILElement::unscheduleIfScheduled() {
|
|
|
| DEFINE_TRACE(SVGSMILElement) {
|
| visitor->trace(m_targetElement);
|
| + visitor->trace(m_targetIdObserver);
|
| visitor->trace(m_timeContainer);
|
| visitor->trace(m_conditions);
|
| visitor->trace(m_syncBaseDependents);
|
|
|