author | Jonathan Kingston <jkt@mozilla.com> |
Tue, 03 Jul 2018 19:12:49 +0000 | |
changeset 424956 | 72cacb766a6f9f5401392384e7c681e35e318cd3 |
parent 424955 | 9c75cab2e32295ee037f0a8f1af2f61ac86f8b8c |
child 424957 | 6e281abe4d39f6d1d3c40fdaca47c009db6720de |
push id | 104946 |
push user | rgurzau@mozilla.com |
push date | Wed, 04 Jul 2018 10:03:16 +0000 |
treeherder | mozilla-inbound@796893f4d2f5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bzbarsky, smaug |
bugs | 1469592 |
milestone | 63.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1316,16 +1316,53 @@ Element::GetAttribute(const nsAString& a // See bug 232598 // aReturn is already empty } else { aReturn.SetNull(); } } } +bool +Element::ToggleAttribute(const nsAString& aName, + const Optional<bool>& aForce, + nsIPrincipal* aTriggeringPrincipal, + ErrorResult& aError) +{ + aError = nsContentUtils::CheckQName(aName, false); + if (aError.Failed()) { + return false; + } + + nsAutoString nameToUse; + const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse); + if (!name) { + if (aForce.WasPassed() && !aForce.Value()) { + return false; + } + RefPtr<nsAtom> nameAtom = NS_AtomizeMainThread(nameToUse); + if (!nameAtom) { + aError.Throw(NS_ERROR_OUT_OF_MEMORY); + return false; + } + aError = SetAttr(kNameSpaceID_None, nameAtom, EmptyString(), aTriggeringPrincipal, true); + return true; + } + if (aForce.WasPassed() && aForce.Value()) { + return true; + } + // Hold a strong reference here so that the atom or nodeinfo doesn't go + // away during UnsetAttr. If it did UnsetAttr would be left with a + // dangling pointer as argument without knowing it. + nsAttrName tmp(*name); + + aError = UnsetAttr(name->NamespaceID(), name->LocalName(), true); + return false; +} + void Element::SetAttribute(const nsAString& aName, const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError) { aError = nsContentUtils::CheckQName(aName, false); if (aError.Failed()) {
--- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1096,16 +1096,18 @@ public: GetAttribute(aName, str); str.ToString(aReturn); } void GetAttribute(const nsAString& aName, DOMString& aReturn); void GetAttributeNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, nsAString& aReturn); + bool ToggleAttribute(const nsAString& aName, const Optional<bool>& aForce, + nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError); void SetAttribute(const nsAString& aName, const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError); void SetAttributeNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, const nsAString& aValue, nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError); void SetAttribute(const nsAString& aName, const nsAString& aValue,
--- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -36,16 +36,18 @@ interface Element : Node { readonly attribute NamedNodeMap attributes; [Pure] sequence<DOMString> getAttributeNames(); [Pure] DOMString? getAttribute(DOMString name); [Pure] DOMString? getAttributeNS(DOMString? namespace, DOMString localName); [CEReactions, NeedsSubjectPrincipal=NonSystem, Throws] + boolean toggleAttribute(DOMString name, optional boolean force); + [CEReactions, NeedsSubjectPrincipal=NonSystem, Throws] void setAttribute(DOMString name, DOMString value); [CEReactions, NeedsSubjectPrincipal=NonSystem, Throws] void setAttributeNS(DOMString? namespace, DOMString name, DOMString value); [CEReactions, Throws] void removeAttribute(DOMString name); [CEReactions, Throws] void removeAttributeNS(DOMString? namespace, DOMString localName); [Pure]
--- a/testing/web-platform/tests/interfaces/dom.idl +++ b/testing/web-platform/tests/interfaces/dom.idl @@ -355,16 +355,17 @@ interface Element : Node { [SameObject] readonly attribute NamedNodeMap attributes; sequence<DOMString> getAttributeNames(); DOMString? getAttribute(DOMString qualifiedName); DOMString? getAttributeNS(DOMString? namespace, DOMString localName); void setAttribute(DOMString qualifiedName, DOMString value); void setAttributeNS(DOMString? namespace, DOMString qualifiedName, DOMString value); void removeAttribute(DOMString qualifiedName); void removeAttributeNS(DOMString? namespace, DOMString localName); + boolean toggleAttribute(DOMString qualifiedName, optional boolean force); boolean hasAttribute(DOMString qualifiedName); boolean hasAttributeNS(DOMString? namespace, DOMString localName); Attr? getAttributeNode(DOMString qualifiedName); Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName); Attr? setAttributeNode(Attr attr); Attr? setAttributeNodeNS(Attr attr); Attr removeAttributeNode(Attr attr);