nsresult
ChangeStyleTransaction::SetStyle(bool aAttributeWasSet,
                                 nsAString& aValue)
{
  if (aAttributeWasSet) {
    // The style attribute was not empty, let's recreate the declaration
    nsAutoString propertyNameString;
    mProperty->ToString(propertyNameString);

    nsCOMPtr<nsStyledElement> inlineStyles = do_QueryInterface(mElement);
    NS_ENSURE_TRUE(inlineStyles, NS_ERROR_NULL_POINTER);
    nsCOMPtr<nsICSSDeclaration> cssDecl = inlineStyles->Style();

    if (aValue.IsEmpty()) {
      // An empty value means we have to remove the property
      nsAutoString returnString;
      return cssDecl->RemoveProperty(propertyNameString, returnString);
    }
    // Let's recreate the declaration as it was
    nsAutoString priority;
    cssDecl->GetPropertyPriority(propertyNameString, priority);
    return cssDecl->SetProperty(propertyNameString, aValue, priority);
  }
  return mElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true);
}
NS_IMETHODIMP
nsXTFElementWrapper::RemoveAttribute(const nsAString& aName)
{
  const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);

  if (name) {
    nsAttrName tmp(*name);
    return UnsetAttr(name->NamespaceID(), name->LocalName(), PR_TRUE);
  }

  // Maybe this attribute is handled by our inner element:
  if (mAttributeHandler) {
    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
    return UnsetAttr(kNameSpaceID_None, nameAtom, PR_TRUE);
  }

  return NS_OK;
}
NS_IMETHODIMP
ChangeStyleTransaction::DoTransaction()
{
  nsCOMPtr<nsStyledElement> inlineStyles = do_QueryInterface(mElement);
  NS_ENSURE_TRUE(inlineStyles, NS_ERROR_NULL_POINTER);

  nsCOMPtr<nsICSSDeclaration> cssDecl = inlineStyles->Style();
 
  nsAutoString propertyNameString;
  mProperty->ToString(propertyNameString);

  mUndoAttributeWasSet = mElement->HasAttr(kNameSpaceID_None,
                                           nsGkAtoms::style);

  nsAutoString values;
  nsresult rv = cssDecl->GetPropertyValue(propertyNameString, values);
  NS_ENSURE_SUCCESS(rv, rv);
  mUndoValue.Assign(values);

  // Does this property accept more than one value? (bug 62682)
  bool multiple = AcceptsMoreThanOneValue(*mProperty);

  if (mRemoveProperty) {
    nsAutoString returnString;
    if (multiple) {
      // Let's remove only the value we have to remove and not the others

      // The two lines below are a workaround because
      // nsDOMCSSDeclaration::GetPropertyCSSValue is not yet implemented (bug
      // 62682)
      RemoveValueFromListOfValues(values, NS_LITERAL_STRING("none"));
      RemoveValueFromListOfValues(values, mValue);
      if (values.IsEmpty()) {
        rv = cssDecl->RemoveProperty(propertyNameString, returnString);
        NS_ENSURE_SUCCESS(rv, rv);
      } else {
        nsAutoString priority;
        cssDecl->GetPropertyPriority(propertyNameString, priority);
        rv = cssDecl->SetProperty(propertyNameString, values, priority);
        NS_ENSURE_SUCCESS(rv, rv);
      }
    } else {
      rv = cssDecl->RemoveProperty(propertyNameString, returnString);
      NS_ENSURE_SUCCESS(rv, rv);
    }
  } else {
    nsAutoString priority;
    cssDecl->GetPropertyPriority(propertyNameString, priority);
    if (multiple) {
      // Let's add the value we have to add to the others

      // The line below is a workaround because
      // nsDOMCSSDeclaration::GetPropertyCSSValue is not yet implemented (bug
      // 62682)
      AddValueToMultivalueProperty(values, mValue);
    } else {
      values.Assign(mValue);
    }
    rv = cssDecl->SetProperty(propertyNameString, values, priority);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Let's be sure we don't keep an empty style attribute
  uint32_t length = cssDecl->Length();
  if (!length) {
    rv = mElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true);
    NS_ENSURE_SUCCESS(rv, rv);
  } else {
    mRedoAttributeWasSet = true;
  }

  return cssDecl->GetPropertyValue(propertyNameString, mRedoValue);
}