Exemple #1
0
String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(
    const String& propertyName) {
  CSSPropertyID propertyID = cssPropertyID(propertyName);

  // Custom properties don't have shorthands, so we can ignore them here.
  if (!propertyID || propertyID == CSSPropertyVariable)
    return String();
  if (isShorthandProperty(propertyID))
    return String();
  CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
  if (!shorthandID)
    return String();
  return getPropertyNameString(shorthandID);
}
Exemple #2
0
bool AnimationControllerPrivate::pauseTransitionAtTime(RenderElement* renderer, const String& property, double t)
{
    if (!renderer)
        return false;

    CompositeAnimation& compositeAnimation = ensureCompositeAnimation(*renderer);
    if (compositeAnimation.pauseTransitionAtTime(cssPropertyID(property), t)) {
        renderer->element()->invalidateStyleAndLayerComposition();
        startUpdateStyleIfNeededDispatcher();
        return true;
    }

    return false;
}
bool UseCounter::isCounted(Document& document, const String& string)
{
    Frame* frame = document.frame();
    if (!frame)
        return false;
    FrameHost* host = frame->host();
    if (!host)
        return false;

    CSSPropertyID propertyID = cssPropertyID(string);
    if (propertyID == CSSPropertyInvalid)
        return false;
    return host->useCounter().isCounted(propertyID);
}
CSSStyleValueVector FilteredComputedStylePropertyMap::getAll(
    const String& propertyName,
    ExceptionState& exceptionState) {
  CSSPropertyID propertyID = cssPropertyID(propertyName);
  if (propertyID >= firstCSSProperty && m_nativeProperties.contains(propertyID))
    return getAllInternal(propertyID);

  if (propertyID == CSSPropertyVariable &&
      m_customProperties.contains(AtomicString(propertyName)))
    return getAllInternal(AtomicString(propertyName));

  exceptionState.throwTypeError("Invalid propertyName: " + propertyName);
  return CSSStyleValueVector();
}
Exemple #5
0
bool SVGAnimationElement::attributeIsCSS(const String &attributeName)
{
    // FIXME: We should have a map of all SVG properties and their attribute types so we
    // could validate animations better. The spec is very vague about this.
    unsigned id = cssPropertyID(attributeName);
    // SVG range
    if (id >= CSSPropertyClipPath && id <= CSSPropertyWritingMode) {
        return true;
    }
    // Regular CSS properties also in SVG
    return id == CSSPropertyColor || id == CSSPropertyDisplay || id == CSSPropertyOpacity
           || (id >= CSSPropertyFont && id <= CSSPropertyFontWeight)
           || id == CSSPropertyOverflow || id == CSSPropertyVisibility;
}
Exemple #6
0
bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, const String& property, double t)
{
    if (!renderer)
        return false;

    CompositeAnimation& compositeAnimation = ensureCompositeAnimation(renderer);
    if (compositeAnimation.pauseTransitionAtTime(cssPropertyID(property), t)) {
        renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange);
        startUpdateStyleIfNeededDispatcher();
        return true;
    }

    return false;
}
RefPtr<CSSValue> PropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
{
    if (isCustomPropertyName(propertyName)) {
        RefPtr<CSSValue> value = m_propertySet->getCustomPropertyCSSValue(propertyName);
        if (!value)
            return nullptr;
        return cloneAndCacheForCSSOM(value.get());
    }
    
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return nullptr;
    return cloneAndCacheForCSSOM(m_propertySet->getPropertyCSSValue(propertyID).get());
}
Exemple #8
0
bool FatFingers::isElementClickable(Element* element) const
{
    ASSERT(element);
    ASSERT(m_targetType == ClickableElement);

    ExceptionCode ec = 0;

    if (element->webkitMatchesSelector("a[href],*:link,*:visited,*[role=button],button,input,select,label[for],area[href],textarea,embed,object", ec)
        || element->isMediaControlElement()
        || element->isContentEditable())
        return true;

    return hasMousePressListener(element)
        || CSSComputedStyleDeclaration::create(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer";
}
bool JSCSSStyleDeclaration::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
    bool pixelOrPos;
    String prop = cssPropertyName(propertyName, &pixelOrPos);
    if (!cssPropertyID(prop))
        return false;

    String propValue = valueToStringWithNullCheck(exec, value);
    if (pixelOrPos)
        propValue += "px";
    ExceptionCode ec = 0;
    impl()->setProperty(prop, propValue, emptyString(), ec);
    setDOMException(exec, ec);
    return true;
}
CSSPropertyID AnimationInputHelpers::keyframeAttributeToCSSPropertyID(const String& propertyName)
{
    // Disallow prefixed properties.
    if (propertyName[0] == '-' || isASCIIUpper(propertyName[0]))
        return CSSPropertyInvalid;
    if (propertyName == "cssFloat")
        return CSSPropertyFloat;
    StringBuilder builder;
    for (size_t i = 0; i < propertyName.length(); ++i) {
        if (isASCIIUpper(propertyName[i]))
            builder.append('-');
        builder.append(propertyName[i]);
    }
    return cssPropertyID(builder.toString());
}
bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, const String& property, double t)
{
    if (!renderer)
        return false;

    RefPtr<CompositeAnimation> compAnim = accessCompositeAnimation(renderer);
    if (!compAnim)
        return false;

    if (compAnim->pauseTransitionAtTime(cssPropertyID(property), t)) {
        renderer->node()->setChanged(AnimationStyleChange);
        return true;
    }

    return false;
}
void SVGAnimateElement::resetAnimatedType()
{
    SVGAnimatedTypeAnimator* animator = ensureAnimator();
    ASSERT(m_animatedPropertyType == animator->type());

    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.
        m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName);
        SVGElementAnimatedPropertyList::const_iterator end = m_animatedProperties.end();
        for (SVGElementAnimatedPropertyList::const_iterator it = m_animatedProperties.begin(); it != end; ++it)
            document().accessSVGExtensions()->addElementReferencingTarget(this, it->element);

        ASSERT(!m_animatedProperties.isEmpty());

        ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties));
        if (!m_animatedType)
            m_animatedType = animator->startAnimValAnimation(m_animatedProperties);
        else {
            animator->resetAnimValToBaseVal(m_animatedProperties, m_animatedType.get());
            animator->animValDidChange(m_animatedProperties);
        }
        return;
    }

    // CSS properties animation code-path.
    ASSERT(m_animatedProperties.isEmpty());
    String baseValue;

    if (shouldApply == ApplyCSSAnimation) {
        ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName));
        computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
    }

    if (!m_animatedType)
        m_animatedType = animator->constructFromString(baseValue);
    else
        m_animatedType->setValueAsString(attributeName, baseValue);
}
static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName)
{
    ASSERT(targetElement);
    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
        return;

    CSSPropertyID id = cssPropertyID(attributeName.localName());

    SVGElement::InstanceUpdateBlocker blocker(targetElement);
    removeCSSPropertyFromTarget(targetElement, id);

    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
    const HeapHashSet<WeakMember<SVGElement>>& instances = targetElement->instancesForElement();
    for (SVGElement* shadowTreeElement : instances) {
        if (shadowTreeElement)
            removeCSSPropertyFromTarget(shadowTreeElement, id);
    }
}
PassRefPtr<JSONObject> LayoutEditor::createValueDescription(const String& propertyName)
{
    RefPtrWillBeRawPtr<CSSPrimitiveValue> cssValue = getPropertyCSSValue(cssPropertyID(propertyName));
    if (cssValue && !(cssValue->isLength() || cssValue->isPercentage()))
        return nullptr;

    RefPtr<JSONObject> object = JSONObject::create();
    object->setNumber("value", cssValue ? cssValue->getFloatValue() : 0);
    CSSPrimitiveValue::UnitType unitType = cssValue ? cssValue->typeWithCalcResolved() : CSSPrimitiveValue::UnitType::Pixels;
    object->setString("unit", CSSPrimitiveValue::unitTypeToString(unitType));
    object->setBoolean("mutable", isMutableUnitType(unitType));

    if (!m_growsInside.contains(propertyName))
        m_growsInside.set(propertyName, growInside(propertyName, cssValue.get()));

    object->setBoolean("growInside", m_growsInside.get(propertyName));
    return object.release();
}
String AbstractPropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionState& exceptionState)
{
    StyleAttributeMutationScope mutationScope(this);
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return String();

    willMutate();

    String result;
    bool changed = propertySet().removeProperty(propertyID, &result);

    didMutate(changed ? PropertyChanged : NoChanges);

    if (changed)
        mutationScope.enqueueMutationRecord();
    return result;
}
Exemple #16
0
bool DOMWindowCSS::supports(const String& property, const String& value) const
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());
    if (propertyID == CSSPropertyInvalid)
        return false;
    ASSERT(CSSPropertyMetadata::isEnabledProperty(propertyID));

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
    return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, HTMLStandardMode, 0);
}
static inline void applyCSSPropertyToTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName, const String& valueAsString)
{
    ASSERT(targetElement);
    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
        return;

    CSSPropertyID id = cssPropertyID(attributeName.localName());

    SVGElement::InstanceUpdateBlocker blocker(targetElement);
    applyCSSPropertyToTarget(targetElement, id, valueAsString);

    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
    const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
        if (SVGElement* shadowTreeElement = *it)
            applyCSSPropertyToTarget(shadowTreeElement, id, valueAsString);
    }
}
Exemple #18
0
static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetElement, const QualifiedName& attributeName)
{
    ASSERT(targetElement);
    if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
        return;

    CSSPropertyID id = cssPropertyID(attributeName.localName());

    SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
    removeCSSPropertyFromTarget(targetElement, id);

    // If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
    const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
        if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
            removeCSSPropertyFromTarget(shadowTreeElement, id);
    }
}
Exemple #19
0
bool DOMCSSNamespace::supports(const String& property, const String& value)
{
    CSSPropertyID propertyID = cssPropertyID(property.stripWhiteSpace());

    if (propertyID == CSSPropertyInvalid)
        return false;

    // CSSParser::parseValue() won't work correctly if !important is present,
    // so just get rid of it. It doesn't matter to supports() if it's actually
    // there or not, provided how it's specified in the value is correct.
    String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
    normalizedValue = valueWithoutImportant(normalizedValue);

    if (normalizedValue.isEmpty())
        return false;

    auto dummyStyle = MutableStyleProperties::create();
    return CSSParser::parseValue(dummyStyle, propertyID, normalizedValue, false, CSSStrictMode, nullptr) != CSSParser::ParseResult::Error;
}
Exemple #20
0
String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
{
#if ENABLE(MUTATION_OBSERVERS)
    StyleAttributeMutationScope mutationScope(this);
#endif
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return String();
    ec = 0;
    String result;
    bool changes = m_propertySet->removeProperty(propertyID, &result);
    if (changes) {
        setNeedsStyleRecalc();
#if ENABLE(MUTATION_OBSERVERS)
        mutationScope.enqueueMutationRecord();
#endif
    }
    return result;
}
String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
{
    StyleAttributeMutationScope mutationScope(this);
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return String();

    if (!willMutate())
        return String();

    ec = 0;
    String result;
    bool changed = m_propertySet->removeProperty(propertyID, &result);

    didMutate(changed ? PropertyChanged : NoChanges);

    if (changed)
        mutationScope.enqueueMutationRecord();
    return result;
}
Exemple #22
0
String SMILTimeContainer::baseValueFor(ElementAttributePair key)
{
    // FIXME: We wouldn't need to do this if we were keeping base values around properly in DOM.
    // Currently animation overwrites them so we need to save them somewhere.
    BaseValueMap::iterator it = m_savedBaseValues.find(key);
    if (it != m_savedBaseValues.end())
        return it->second;
    
    SVGElement* targetElement = key.first;
    QualifiedName attributeName = key.second;
    ASSERT(targetElement);
    ASSERT(attributeName != anyQName());
    String baseValue;
    if (SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName))
        baseValue = computedStyle(targetElement)->getPropertyValue(cssPropertyID(attributeName.localName()));
    else
        baseValue = targetElement->getAttribute(attributeName);
    m_savedBaseValues.add(key, baseValue);
    return baseValue;
}
Exemple #23
0
void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode& ec)
{
#if ENABLE(MUTATION_OBSERVERS)
    StyleAttributeMutationScope mutationScope(this);
#endif
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return;
    bool important = priority.find("important", 0, false) != notFound;
    ec = 0;
    bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());
    if (changed) {
        // CSS DOM requires raising SYNTAX_ERR of parsing failed, but this is too dangerous for compatibility,
        // see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
        setNeedsStyleRecalc();
#if ENABLE(MUTATION_OBSERVERS)
        mutationScope.enqueueMutationRecord();
#endif
    }
}
ExceptionOr<String> PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName)
{
    StyleAttributeMutationScope mutationScope(this);
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (isCustomPropertyName(propertyName))
        propertyID = CSSPropertyCustom;
    if (!propertyID)
        return String();

    if (!willMutate())
        return String();

    String result;
    bool changed = propertyID != CSSPropertyCustom ? m_propertySet->removeProperty(propertyID, &result) : m_propertySet->removeCustomProperty(propertyName, &result);

    didMutate(changed ? PropertyChanged : NoChanges);

    if (changed)
        mutationScope.enqueueMutationRecord();
    return WTFMove(result);
}
void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
{
    StyleAttributeMutationScope mutationScope(this);
    CSSPropertyID propertyID = cssPropertyID(propertyName);
    if (!propertyID)
        return;

    bool important = priority.find("important", 0, false) != kNotFound;

    willMutate();

    bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());

    didMutate(changed ? PropertyChanged : NoChanges);

    if (changed) {
        // CSS DOM requires raising SyntaxError of parsing failed, but this is too dangerous for compatibility,
        // see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
        mutationScope.enqueueMutationRecord();
    }
}
void SVGAnimateElement::resetAnimatedType()
{
    SVGAnimatedTypeAnimator* animator = ensureAnimator();
    ASSERT(m_animatedPropertyType == animator->type());

    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.
        m_animatedElements = findElementInstances(targetElement);
        ASSERT(!m_animatedElements.isEmpty());

        Vector<SVGElement*>::const_iterator end = m_animatedElements.end();
        for (Vector<SVGElement*>::const_iterator it = m_animatedElements.begin(); it != end; ++it)
            document().accessSVGExtensions().addElementReferencingTarget(this, *it);

        if (!m_animatedProperty)
            m_animatedProperty = animator->startAnimValAnimation(m_animatedElements);
        else
            m_animatedProperty = animator->resetAnimValToBaseVal(m_animatedElements);

        return;
    }

    // CSS properties animation code-path.
    ASSERT(m_animatedElements.isEmpty());
    String baseValue;

    if (shouldApply == ApplyCSSAnimation) {
        ASSERT(SVGAnimationElement::isTargetAttributeCSSProperty(targetElement, attributeName));
        computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
    }

    m_animatedProperty = animator->constructFromString(baseValue);
}
String InspectorAnimationAgent::createCSSId(blink::Animation& animation) {
  String type =
      m_idToAnimationType.get(String::number(animation.sequenceNumber()));
  ASSERT(type != AnimationType::WebAnimation);

  KeyframeEffect* effect = toKeyframeEffect(animation.effect());
  Vector<CSSPropertyID> cssProperties;
  if (type == AnimationType::CSSAnimation) {
    for (CSSPropertyID property : animationProperties)
      cssProperties.append(property);
  } else {
    for (CSSPropertyID property : transitionProperties)
      cssProperties.append(property);
    cssProperties.append(cssPropertyID(animation.id()));
  }

  Element* element = effect->target();
  HeapVector<Member<CSSStyleDeclaration>> styles =
      m_cssAgent->matchingStyles(element);
  std::unique_ptr<WebCryptoDigestor> digestor =
      createDigestor(HashAlgorithmSha1);
  addStringToDigestor(digestor.get(), type);
  addStringToDigestor(digestor.get(), animation.id());
  for (CSSPropertyID property : cssProperties) {
    CSSStyleDeclaration* style =
        m_cssAgent->findEffectiveDeclaration(property, styles);
    // Ignore inline styles.
    if (!style || !style->parentStyleSheet() || !style->parentRule() ||
        style->parentRule()->type() != CSSRule::kStyleRule)
      continue;
    addStringToDigestor(digestor.get(), getPropertyNameString(property));
    addStringToDigestor(digestor.get(),
                        m_cssAgent->styleSheetId(style->parentStyleSheet()));
    addStringToDigestor(digestor.get(),
                        toCSSStyleRule(style->parentRule())->selectorText());
  }
  DigestValue digestResult;
  finishDigestor(digestor.get(), digestResult);
  return base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
}
Exemple #28
0
std::unique_ptr<protocol::DictionaryValue> LayoutEditor::createValueDescription(
    const String& propertyName) {
  const CSSPrimitiveValue* cssValue =
      getPropertyCSSValue(cssPropertyID(propertyName));
  if (cssValue && !(cssValue->isLength() || cssValue->isPercentage()))
    return nullptr;

  std::unique_ptr<protocol::DictionaryValue> object =
      protocol::DictionaryValue::create();
  object->setDouble("value", cssValue ? cssValue->getFloatValue() : 0);
  CSSPrimitiveValue::UnitType unitType =
      cssValue ? cssValue->typeWithCalcResolved()
               : CSSPrimitiveValue::UnitType::Pixels;
  object->setString("unit", CSSPrimitiveValue::unitTypeToString(unitType));
  object->setBoolean("mutable", isMutableUnitType(unitType));

  if (!m_growsInside.contains(propertyName))
    m_growsInside.set(propertyName, growInside(propertyName, cssValue));

  object->setBoolean("growInside", m_growsInside.get(propertyName));
  return object;
}
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 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);
}