Exemplo n.º 1
0
nsresult
SVGLengthList::SetValueFromString(const nsAString& aValue)
{
  SVGLengthList temp;

  NS_ConvertUTF16toUTF8 value(aValue);
  char* start = SkipWhitespace(value.BeginWriting());

  // We can't use strtok with SVG_COMMA_WSP_DELIM because to correctly handle
  // invalid input in the form of two commas without a value between them, we
  // would need to know if strtok overwrote a comma or not.

  while (*start != '\0') {
    int end = strcspn(start, SVG_COMMA_WSP_DELIM);
    if (end == 0) {
      // found comma in an invalid location
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    SVGLength length;
    if (!length.SetValueFromString(NS_ConvertUTF8toUTF16(start, PRUint32(end)))) {
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    if (!temp.AppendItem(length)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
    start = SkipWhitespace(start + end);
    if (*start == ',') {
      start = SkipWhitespace(start + 1);
    }
  }

  return CopyFrom(temp);
}
void
DOMSVGAnimatedLengthList::InternalBaseValListWillChangeTo(const SVGLengthList& aNewValue)
{
  // When the number of items in our internal counterpart's baseVal changes,
  // we MUST keep our baseVal in sync. If we don't, script will either see a
  // list that is too short and be unable to access indexes that should be
  // valid, or else, MUCH WORSE, script will see a list that is too long and be
  // able to access "items" at indexes that are out of bounds (read/write to
  // bad memory)!!

  nsRefPtr<DOMSVGAnimatedLengthList> kungFuDeathGrip;
  if (mBaseVal) {
    if (aNewValue.Length() < mBaseVal->Length()) {
      // InternalListLengthWillChange might clear last reference to |this|.
      // Retain a temporary reference to keep from dying before returning.
      kungFuDeathGrip = this;
    }
    mBaseVal->InternalListLengthWillChange(aNewValue.Length());
  }

  // If our attribute is not animating, then our animVal mirrors our baseVal
  // and we must sync its length too. (If our attribute is animating, then the
  // SMIL engine takes care of calling InternalAnimValListWillChangeTo() if
  // necessary.)

  if (!IsAnimating()) {
    InternalAnimValListWillChangeTo(aNewValue);
  }
}
nsresult
SVGAnimatedLengthList::SetBaseValueString(const nsAString& aValue)
{
  SVGLengthList newBaseValue;
  nsresult rv = newBaseValue.SetValueFromString(aValue);
  if (NS_FAILED(rv)) {
    return rv;
  }

  DOMSVGAnimatedLengthList *domWrapper =
    DOMSVGAnimatedLengthList::GetDOMWrapperIfExists(this);
  if (domWrapper) {
    // We must send this notification *before* changing mBaseVal! If the length
    // of our baseVal is being reduced, our baseVal's DOM wrapper list may have
    // to remove DOM items from itself, and any removed DOM items need to copy
    // their internal counterpart values *before* we change them.
    //
    domWrapper->InternalBaseValListWillChangeTo(newBaseValue);
  }

  // We don't need to call DidChange* here - we're only called by
  // nsSVGElement::ParseAttribute under nsGenericElement::SetAttr,
  // which takes care of notifying.

  rv = mBaseVal.CopyFrom(newBaseValue);
  if (NS_FAILED(rv) && domWrapper) {
    // Attempting to increase mBaseVal's length failed - reduce domWrapper
    // back to the same length:
    domWrapper->InternalBaseValListWillChangeTo(mBaseVal);
  }
  return rv;
}
Exemplo n.º 4
0
JSValue* JSSVGLengthList::getValueProperty(ExecState* exec, int token) const
{
    switch (token) {
    case NumberOfItemsAttrNum: {
        SVGLengthList* imp = static_cast<SVGLengthList*>(impl());

        return jsNumber(imp->numberOfItems());
    }
    }
    return 0;
}
Exemplo n.º 5
0
void SVGLengthList::add(SVGPropertyBase* other, SVGElement* contextElement) {
  SVGLengthList* otherList = toSVGLengthList(other);

  if (length() != otherList->length())
    return;

  SVGLengthContext lengthContext(contextElement);
  for (size_t i = 0; i < length(); ++i)
    at(i)->setValue(
        at(i)->value(lengthContext) + otherList->at(i)->value(lengthContext),
        lengthContext);
}
static inline void extractFloatValuesFromSVGLengthList(SVGElement* lengthContext, const SVGLengthList& list, Vector<float>& floatValues, unsigned textContentLength)
{
    ASSERT(lengthContext);

    unsigned length = list.size();
    if (length > textContentLength)
        length = textContentLength;
    floatValues.reserveCapacity(length);

    for (unsigned i = 0; i < length; ++i) {
        const SVGLength& length = list.at(i);
        floatValues.append(length.value(lengthContext));
    }
}
void
DOMSVGAnimatedLengthList::InternalAnimValListWillChangeTo(const SVGLengthList& aNewValue)
{
  if (mAnimVal) {
    mAnimVal->InternalListLengthWillChange(aNewValue.Length());
  }
}
Exemplo n.º 8
0
nsresult
SVGLengthList::CopyFrom(const SVGLengthList& rhs)
{
  if (!mLengths.SetCapacity(rhs.Length())) {
    // Yes, we do want fallible alloc here
    return NS_ERROR_OUT_OF_MEMORY;
  }
  mLengths = rhs.mLengths;
  return NS_OK;
}
Exemplo n.º 9
0
bool SVGLengthList::operator==(const SVGLengthList& rhs) const {
  if (Length() != rhs.Length()) {
    return false;
  }
  for (uint32_t i = 0; i < Length(); ++i) {
    if (!(mLengths[i] == rhs.mLengths[i])) {
      return false;
    }
  }
  return true;
}
Exemplo n.º 10
0
nsresult SVGLengthList::SetValueFromString(const nsAString& aValue) {
  SVGLengthList temp;

  nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
      aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);

  while (tokenizer.hasMoreTokens()) {
    SVGLength length;
    if (!length.SetValueFromString(tokenizer.nextToken())) {
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    if (!temp.AppendItem(length)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  if (tokenizer.separatorAfterCurrentToken()) {
    return NS_ERROR_DOM_SYNTAX_ERR;  // trailing comma
  }
  return CopyFrom(temp);
}
Exemplo n.º 11
0
PRBool
SVGLengthList::operator==(const SVGLengthList& rhs) const
{
  if (Length() != rhs.Length()) {
    return PR_FALSE;
  }
  for (PRUint32 i = 0; i < Length(); ++i) {
    if (!(mLengths[i] == rhs.mLengths[i])) {
      return PR_FALSE;
    }
  }
  return PR_TRUE;
}
void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
{
    ASSERT(m_animationElement);
    ASSERT(m_contextElement);

    SVGLengthList fromLengthList = m_animationElement->animationMode() == ToAnimation ? animated->lengthList() : from->lengthList();
    SVGLengthList toLengthList = to->lengthList();
    const SVGLengthList& toAtEndOfDurationLengthList = toAtEndOfDuration->lengthList();
    SVGLengthList& animatedLengthList = animated->lengthList();

    // Apply CSS inheritance rules.
    m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->fromPropertyValueType(), fromLengthList, m_contextElement);
    m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->toPropertyValueType(), toLengthList, m_contextElement);

    if (!m_animationElement->adjustFromToListValues<SVGLengthList>(fromLengthList, toLengthList, animatedLengthList, percentage))
        return;

    unsigned fromLengthListSize = fromLengthList.size();
    unsigned toLengthListSize = toLengthList.size();
    unsigned toAtEndOfDurationListSize = toAtEndOfDurationLengthList.size();

    SVGLengthContext lengthContext(m_contextElement);
    for (unsigned i = 0; i < toLengthListSize; ++i) {
        float animatedNumber = animatedLengthList[i].value(lengthContext);
        SVGLengthType unitType = toLengthList[i].unitType();
        float effectiveFrom = 0;
        if (fromLengthListSize) {
            if (percentage < 0.5)
                unitType = fromLengthList[i].unitType();
            effectiveFrom = fromLengthList[i].value(lengthContext);
        }
        float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationLengthList[i].value(lengthContext) : 0;

        m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), effectiveToAtEnd, animatedNumber);
        animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION);
    }
}
Exemplo n.º 13
0
JSValue JSC_HOST_CALL jsSVGLengthListPrototypeFunctionAppendItem(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSSVGLengthList::s_info))
        return throwError(exec, TypeError);
    JSSVGLengthList* castedThisObj = static_cast<JSSVGLengthList*>(asObject(thisValue));
    SVGLengthList* imp = static_cast<SVGLengthList*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    SVGLength item = toSVGLength(args.at(0));


    JSC::JSValue result = toJS(exec, deprecatedGlobalObjectForPrototype(exec), JSSVGStaticPODTypeWrapper<SVGLength>::create(imp->appendItem(item, ec)).get(), castedThisObj->context());
    setDOMException(exec, ec);
    return result;
}
Exemplo n.º 14
0
nsresult
SVGLengthList::SetValueFromString(const nsAString& aValue)
{
  SVGLengthList temp;

  nsCharSeparatedTokenizerTemplate<IsSVGWhitespace>
    tokenizer(aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);

  nsCAutoString str;  // outside loop to minimize memory churn

  while (tokenizer.hasMoreTokens()) {
    SVGLength length;
    if (!length.SetValueFromString(tokenizer.nextToken())) {
      return NS_ERROR_DOM_SYNTAX_ERR;
    }
    if (!temp.AppendItem(length)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  if (tokenizer.lastTokenEndedWithSeparator()) {
    return NS_ERROR_DOM_SYNTAX_ERR; // trailing comma
  }
  return CopyFrom(temp);
}
void
DOMSVGAnimatedLengthList::InternalBaseValListWillChangeTo(const SVGLengthList& aNewValue)
{
  // When the number of items in our internal counterpart's baseVal changes,
  // we MUST keep our baseVal in sync. If we don't, script will either see a
  // list that is too short and be unable to access indexes that should be
  // valid, or else, MUCH WORSE, script will see a list that is too long and be
  // able to access "items" at indexes that are out of bounds (read/write to
  // bad memory)!!

  if (mBaseVal) {
    mBaseVal->InternalListLengthWillChange(aNewValue.Length());
  }

  // If our attribute is not animating, then our animVal mirrors our baseVal
  // and we must sync its length too. (If our attribute is animating, then the
  // SMIL engine takes care of calling InternalAnimValListWillChangeTo() if
  // necessary.)

  if (!IsAnimating()) {
    InternalAnimValListWillChangeTo(aNewValue);
  }
}
Exemplo n.º 16
0
SVGLengthList* SVGLengthList::clone() {
  SVGLengthList* ret = SVGLengthList::create(m_mode);
  ret->deepCopy(this);
  return ret;
}
static SVGLengthList parseLengthListFromString(SVGAnimationElement* animationElement, const String& string)
{
    SVGLengthList lengthList;
    lengthList.parse(string, SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
    return lengthList;
}
Exemplo n.º 18
0
SVGPropertyBase* SVGLengthList::cloneForAnimation(const String& value) const {
  SVGLengthList* ret = SVGLengthList::create(m_mode);
  ret->setValueAsString(value);
  return ret;
}
Exemplo n.º 19
0
void SVGLengthList::calculateAnimatedValue(
    SVGAnimationElement* animationElement,
    float percentage,
    unsigned repeatCount,
    SVGPropertyBase* fromValue,
    SVGPropertyBase* toValue,
    SVGPropertyBase* toAtEndOfDurationValue,
    SVGElement* contextElement) {
  SVGLengthList* fromList = toSVGLengthList(fromValue);
  SVGLengthList* toList = toSVGLengthList(toValue);
  SVGLengthList* toAtEndOfDurationList =
      toSVGLengthList(toAtEndOfDurationValue);

  SVGLengthContext lengthContext(contextElement);
  ASSERT(m_mode == SVGLength::lengthModeForAnimatedLengthAttribute(
                       animationElement->attributeName()));

  size_t fromLengthListSize = fromList->length();
  size_t toLengthListSize = toList->length();
  size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();

  if (!adjustFromToListValues(fromList, toList, percentage,
                              animationElement->getAnimationMode()))
    return;

  for (size_t i = 0; i < toLengthListSize; ++i) {
    // TODO(shanmuga.m): Support calc for SVGLengthList animation
    float animatedNumber = at(i)->value(lengthContext);
    CSSPrimitiveValue::UnitType unitType =
        toList->at(i)->typeWithCalcResolved();
    float effectiveFrom = 0;
    if (fromLengthListSize) {
      if (percentage < 0.5)
        unitType = fromList->at(i)->typeWithCalcResolved();
      effectiveFrom = fromList->at(i)->value(lengthContext);
    }
    float effectiveTo = toList->at(i)->value(lengthContext);
    float effectiveToAtEnd =
        i < toAtEndOfDurationListSize
            ? toAtEndOfDurationList->at(i)->value(lengthContext)
            : 0;

    animationElement->animateAdditiveNumber(percentage, repeatCount,
                                            effectiveFrom, effectiveTo,
                                            effectiveToAtEnd, animatedNumber);
    at(i)->setUnitType(unitType);
    at(i)->setValue(animatedNumber, lengthContext);
  }
}
void SVGTextPositioningElement::parseMappedAttribute(Attribute* attr)
{
    if (attr->name() == SVGNames::xAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeWidth);
        detachAnimatedXListWrappers(newList.size());
        setXBaseValue(newList);
    } else if (attr->name() == SVGNames::yAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeHeight);
        detachAnimatedYListWrappers(newList.size());
        setYBaseValue(newList);
    } else if (attr->name() == SVGNames::dxAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeWidth);
        detachAnimatedDxListWrappers(newList.size());
        setDxBaseValue(newList);
    } else if (attr->name() == SVGNames::dyAttr) {
        SVGLengthList newList;
        newList.parse(attr->value(), LengthModeHeight);
        detachAnimatedDyListWrappers(newList.size());
        setDyBaseValue(newList);
    } else if (attr->name() == SVGNames::rotateAttr) {
        SVGNumberList newList;
        newList.parse(attr->value());
        detachAnimatedRotateListWrappers(newList.size());
        setRotateBaseValue(newList);
    } else
        SVGTextContentElement::parseMappedAttribute(attr);
}
void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
    if (!isSupportedAttribute(name)) {
        SVGTextContentElement::parseAttribute(name, value);
        return;
    }

    if (name == SVGNames::xAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeWidth);
        detachAnimatedXListWrappers(newList.size());
        setXBaseValue(newList);
        return;
    }

    if (name == SVGNames::yAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeHeight);
        detachAnimatedYListWrappers(newList.size());
        setYBaseValue(newList);
        return;
    }

    if (name == SVGNames::dxAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeWidth);
        detachAnimatedDxListWrappers(newList.size());
        setDxBaseValue(newList);
        return;
    }

    if (name == SVGNames::dyAttr) {
        SVGLengthList newList;
        newList.parse(value, LengthModeHeight);
        detachAnimatedDyListWrappers(newList.size());
        setDyBaseValue(newList);
        return;
    }

    if (name == SVGNames::rotateAttr) {
        SVGNumberList newList;
        newList.parse(value);
        detachAnimatedRotateListWrappers(newList.size());
        setRotateBaseValue(newList);
        return;
    }

    ASSERT_NOT_REACHED();
}
Exemplo n.º 22
0
JSValue* JSSVGLengthListPrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSSVGLengthList::info))
      return throwError(exec, TypeError);

    JSSVGLengthList* castedThisObj = static_cast<JSSVGLengthList*>(thisObj);
    SVGLengthList* imp = static_cast<SVGLengthList*>(castedThisObj->impl());

    switch (id) {
    case JSSVGLengthList::ClearFuncNum: {
        ExceptionCode ec = 0;

        imp->clear(ec);
        setDOMException(exec, ec);
        return jsUndefined();
    }
    case JSSVGLengthList::InitializeFuncNum: {
        ExceptionCode ec = 0;
        SVGLength item = toSVGLength(args[0]);


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->initialize(item, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    case JSSVGLengthList::GetItemFuncNum: {
        ExceptionCode ec = 0;
        bool indexOk;
        unsigned index = args[0]->toInt32(exec, indexOk);
        if (!indexOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->getItem(index, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    case JSSVGLengthList::InsertItemBeforeFuncNum: {
        ExceptionCode ec = 0;
        SVGLength item = toSVGLength(args[0]);
        bool indexOk;
        unsigned index = args[1]->toInt32(exec, indexOk);
        if (!indexOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->insertItemBefore(item, index, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    case JSSVGLengthList::ReplaceItemFuncNum: {
        ExceptionCode ec = 0;
        SVGLength item = toSVGLength(args[0]);
        bool indexOk;
        unsigned index = args[1]->toInt32(exec, indexOk);
        if (!indexOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->replaceItem(item, index, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    case JSSVGLengthList::RemoveItemFuncNum: {
        ExceptionCode ec = 0;
        bool indexOk;
        unsigned index = args[0]->toInt32(exec, indexOk);
        if (!indexOk) {
            setDOMException(exec, TYPE_MISMATCH_ERR);
            return jsUndefined();
        }


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->removeItem(index, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    case JSSVGLengthList::AppendItemFuncNum: {
        ExceptionCode ec = 0;
        SVGLength item = toSVGLength(args[0]);


        KJS::JSValue* result = toJS(exec, new JSSVGPODTypeWrapperCreatorReadOnly<SVGLength>(imp->appendItem(item, ec)), castedThisObj->context());
        setDOMException(exec, ec);
        return result;
    }
    }
    return 0;
}