Bug 1357645 - Clone attributes rather than reparsing when possible r=bz

Now that the side effects of parsing have been relocated to BeforeSetAttr and AfterSetAttr (Bug 1365092), we can easily switch nsGenericHTMLElement::CopyInnerTo from reparsing attributes to cloning them. They are still reparsed, however, in the case where the owning document is changing since Base URIs may have changed.

MozReview-Commit-ID: 2TlUUyBx6bL

--HG--
extra : rebase_source : b581e797a24230d012cf79c1fc567c05d9acc746
This commit is contained in:
Kirk Steuber 2017-06-15 09:56:18 -07:00
Родитель 981d317f0f
Коммит 25f3dbc5bc
1 изменённых файлов: 21 добавлений и 8 удалений

Просмотреть файл

@ -177,8 +177,12 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElementBase)
nsresult
nsGenericHTMLElement::CopyInnerTo(Element* aDst, bool aPreallocateChildren)
{
MOZ_ASSERT(!aDst->GetUncomposedDoc(),
"Should not CopyInnerTo an Element in a document");
nsresult rv;
bool reparse = (aDst->OwnerDoc() != OwnerDoc());
rv = static_cast<nsGenericHTMLElement*>(aDst)->mAttrsAndChildren.
EnsureCapacityToClone(mAttrsAndChildren, aPreallocateChildren);
NS_ENSURE_SUCCESS(rv, rv);
@ -188,11 +192,14 @@ nsGenericHTMLElement::CopyInnerTo(Element* aDst, bool aPreallocateChildren)
const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
const nsAttrValue *value = mAttrsAndChildren.AttrAt(i);
nsAutoString valStr;
value->ToString(valStr);
if (name->Equals(nsGkAtoms::style, kNameSpaceID_None) &&
value->Type() == nsAttrValue::eCSSDeclaration) {
// We still clone CSS attributes, even in the cross-document case.
// https://github.com/w3c/webappsec-csp/issues/212
nsAutoString valStr;
value->ToString(valStr);
DeclarationBlock* decl = value->GetCSSDeclarationValue();
// We can't just set this as a string, because that will fail
// to reparse the string into style data until the node is
@ -201,13 +208,19 @@ nsGenericHTMLElement::CopyInnerTo(Element* aDst, bool aPreallocateChildren)
rv = aDst->SetInlineStyleDeclaration(declClone, &valStr, false);
NS_ENSURE_SUCCESS(rv, rv);
} else if (reparse) {
nsAutoString valStr;
value->ToString(valStr);
continue;
rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
name->GetPrefix(), valStr, false);
NS_ENSURE_SUCCESS(rv, rv);
} else {
nsAttrValue valueCopy(*value);
rv = aDst->SetParsedAttr(name->NamespaceID(), name->LocalName(),
name->GetPrefix(), valueCopy, false);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
name->GetPrefix(), valStr, false);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;