void SVGSMILElement::buildPendingResource() { clearResourceAndEventBaseReferences(); if (!isConnected()) { // Reset the target element if we are no longer in the document. setTargetElement(nullptr); 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); SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : nullptr; if (svgTarget && !svgTarget->isConnected()) svgTarget = nullptr; if (svgTarget != targetElement()) setTargetElement(svgTarget); if (!svgTarget) { // Do not register as pending if we are already pending this resource. if (document().accessSVGExtensions().isElementPendingResource(this, id)) return; if (!id.isEmpty()) { document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else { // 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. addReferenceTo(svgTarget); } connectEventBaseConditions(); }
void SVGSMILElement::connectEventBaseConditions() { disconnectEventBaseConditions(); for (unsigned n = 0; n < m_conditions.size(); ++n) { Condition* condition = m_conditions[n].get(); if (condition->getType() == Condition::EventBase) { ASSERT(!condition->syncBase()); SVGElement* eventBase = eventBaseFor(*condition); if (!eventBase) { if (!condition->baseID().isEmpty() && !document().accessSVGExtensions().isElementPendingResource(this, AtomicString(condition->baseID()))) document().accessSVGExtensions().addPendingResource(AtomicString(condition->baseID()), this); continue; } ASSERT(!condition->eventListener()); condition->setEventListener(ConditionEventListener::create(this, condition)); eventBase->addEventListener(AtomicString(condition->name()), condition->eventListener(), false); addReferenceTo(eventBase); } } }
void SVGAnimateElement::resetAnimatedType() { SVGAnimatedTypeAnimator* animator = ensureAnimator(); SVGElement* targetElement = this->targetElement(); const QualifiedName& attributeName = this->attributeName(); ShouldApplyAnimation shouldApply = shouldApplyAnimation(targetElement, attributeName); if (shouldApply == DontApplyAnimation) return; if (shouldApply == ApplyXMLAnimation) { // SVG DOM animVal animation code-path. WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements = findElementInstances(targetElement); ASSERT(!animatedElements.isEmpty()); WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator end = animatedElements.end(); for (WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator it = animatedElements.begin(); it != end; ++it) addReferenceTo(*it); if (!m_animatedProperty) m_animatedProperty = animator->startAnimValAnimation(animatedElements); else m_animatedProperty = animator->resetAnimValToBaseVal(animatedElements); return; } // CSS properties animation code-path. String baseValue; if (shouldApply == ApplyCSSAnimation) { ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName)); computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue); } m_animatedProperty = animator->constructFromString(baseValue); }
void SVGFEImageElement::buildPendingResource() { clearResourceReferences(); if (!inDocument()) return; AtomicString id; Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id); if (!target) { if (id.isEmpty()) { fetchImageResource(); } else { document().accessSVGExtensions().addPendingResource(id, this); ASSERT(hasPendingResources()); } } else if (target->isSVGElement()) { // 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. addReferenceTo(toSVGElement(target)); } invalidate(); }
bool SVGUseElement::buildShadowTree(SVGElement* target, SVGElement* targetInstance, bool foundUse) { ASSERT(target); ASSERT(targetInstance); // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree. if (isSVGUseElement(*target)) { // We only need to track first degree <use> dependencies. Indirect references are handled // as the invalidation bubbles up the dependency chain. if (!foundUse && !isStructurallyExternal()) { addReferenceTo(target); foundUse = true; } } else if (isDisallowedElement(target)) { return false; } targetInstance->setCorrespondingElement(target); if (EventTargetData* data = target->eventTargetData()) data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(targetInstance); for (RefPtrWillBeRawPtr<Node> child = target->firstChild(); child; child = child->nextSibling()) { // Skip any disallowed element. if (isDisallowedElement(child.get())) continue; RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false); targetInstance->appendChild(newChild.get()); if (newChild->isSVGElement()) { // Enter recursion, appending new instance tree nodes to the "instance" object. if (!buildShadowTree(toSVGElement(child), toSVGElement(newChild), foundUse)) return false; } } return true; }
void SVGAnimateElement::resetAnimatedType() { SVGElement* targetElement = this->targetElement(); const QualifiedName& attributeName = this->attributeName(); m_animator.reset(targetElement); ShouldApplyAnimationType shouldApply = shouldApplyAnimation(targetElement, attributeName); if (shouldApply == DontApplyAnimation) return; if (shouldApply == ApplyXMLAnimation || shouldApply == ApplyXMLandCSSAnimation) { // SVG DOM animVal animation code-path. SVGElementInstances animatedElements = findElementInstances(targetElement); ASSERT(!animatedElements.isEmpty()); for (SVGElement* element : animatedElements) addReferenceTo(element); if (!m_animatedProperty) m_animatedProperty = m_animator.startAnimValAnimation(animatedElements); else m_animatedProperty = m_animator.resetAnimValToBaseVal(animatedElements); return; } // CSS properties animation code-path. String baseValue; if (shouldApply == ApplyCSSAnimation) { ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName)); computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue); } m_animatedProperty = m_animator.constructFromString(baseValue); }