Exemple #1
0
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);
}