author | Boris Zbarsky <bzbarsky@mit.edu> |
Fri, 15 Jan 2016 13:29:58 -0500 | |
changeset 280223 | 31d158e26ea5d10dcf25b042ee7620ed79513b5f |
parent 280222 | 3e2c9a354c87a393d4037fa188a3b9754afb4c3e |
child 280224 | b20e5de65e51400701e5ab8ba7308df37e13ebeb |
push id | 29906 |
push user | ryanvm@gmail.com |
push date | Sun, 17 Jan 2016 19:40:11 +0000 |
treeherder | mozilla-central@b92f5032b4fd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bkelly |
bugs | 1237580 |
milestone | 46.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
|
dom/base/nsDOMAttributeMap.cpp | file | annotate | diff | comparison | revisions | |
testing/web-platform/tests/dom/nodes/attributes.html | file | annotate | diff | comparison | revisions |
--- a/dom/base/nsDOMAttributeMap.cpp +++ b/dom/base/nsDOMAttributeMap.cpp @@ -191,27 +191,42 @@ nsDOMAttributeMap::NameIsEnumerable(cons void nsDOMAttributeMap::GetSupportedNames(unsigned aFlags, nsTArray<nsString>& aNames) { if (!(aFlags & JSITER_HIDDEN)) { return; } + // For HTML elements in HTML documents, only include names that are still the + // same after ASCII-lowercasing, since our named getter will end up + // ASCII-lowercasing the given string. + bool lowercaseNamesOnly = + mContent->IsHTMLElement() && mContent->IsInHTMLDocument(); + const uint32_t count = mContent->GetAttrCount(); bool seenNonAtomName = false; for (uint32_t i = 0; i < count; i++) { const nsAttrName* name = mContent->GetAttrNameAt(i); seenNonAtomName = seenNonAtomName || !name->IsAtom(); nsString qualifiedName; name->GetQualifiedName(qualifiedName); + if (lowercaseNamesOnly && + nsContentUtils::StringContainsASCIIUpper(qualifiedName)) { + continue; + } + + // Omit duplicates. We only need to do this check if we've seen a non-atom + // name, because that's the only way we can have two identical qualified + // names. if (seenNonAtomName && aNames.Contains(qualifiedName)) { continue; } + aNames.AppendElement(qualifiedName); } } Attr* nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName) { bool dummy;
--- a/testing/web-platform/tests/dom/nodes/attributes.html +++ b/testing/web-platform/tests/dom/nodes/attributes.html @@ -581,36 +581,98 @@ test(function() { el.setAttribute("b", ""); el.setAttributeNS("foo", "a", ""); assert_array_equals(getEnumerableOwnProps1(el.attributes), ["0", "1", "2"]) assert_array_equals(getEnumerableOwnProps2(el.attributes), ["0", "1", "2"]) assert_array_equals(Object.getOwnPropertyNames(el.attributes), ["0", "1", "2", "a", "b"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } }, "Own property correctness with non-namespaced attribute before same-name namespaced one"); test(function() { var el = document.createElement("div"); el.setAttributeNS("foo", "a", ""); el.setAttribute("b", ""); el.setAttributeNS("", "a", ""); assert_array_equals(getEnumerableOwnProps1(el.attributes), ["0", "1", "2"]) assert_array_equals(getEnumerableOwnProps2(el.attributes), ["0", "1", "2"]) assert_array_equals(Object.getOwnPropertyNames(el.attributes), ["0", "1", "2", "a", "b"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } }, "Own property correctness with namespaced attribute before same-name non-namespaced one"); test(function() { var el = document.createElement("div"); el.setAttributeNS("foo", "a:b", ""); el.setAttributeNS("foo", "c:d", ""); el.setAttributeNS("bar", "a:b", ""); assert_array_equals(getEnumerableOwnProps1(el.attributes), ["0", "1", "2"]) assert_array_equals(getEnumerableOwnProps2(el.attributes), ["0", "1", "2"]) assert_array_equals(Object.getOwnPropertyNames(el.attributes), ["0", "1", "2", "a:b", "c:d"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } }, "Own property correctness with two namespaced attributes with the same name-with-prefix"); + +test(function() { + var el = document.createElement("div"); + el.setAttributeNS("foo", "A:B", ""); + el.setAttributeNS("bar", "c:D", ""); + el.setAttributeNS("baz", "e:F", ""); + el.setAttributeNS("qux", "g:h", ""); + el.setAttributeNS("", "I", ""); + el.setAttributeNS("", "j", ""); + assert_array_equals(Object.getOwnPropertyNames(el.attributes), + ["0", "1", "2", "3", "4", "5", "g:h", "j"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } +}, "Own property names should only include all-lowercase qualified names for an HTML element in an HTML document"); + +test(function() { + var el = document.createElementNS("", "div"); + el.setAttributeNS("foo", "A:B", ""); + el.setAttributeNS("bar", "c:D", ""); + el.setAttributeNS("baz", "e:F", ""); + el.setAttributeNS("qux", "g:h", ""); + el.setAttributeNS("", "I", ""); + el.setAttributeNS("", "j", ""); + assert_array_equals(Object.getOwnPropertyNames(el.attributes), + ["0", "1", "2", "3", "4", "5", "A:B", "c:D", "e:F", "g:h", "I", "j"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } +}, "Own property names should include all qualified names for a non-HTML element in an HTML document"); + +test(function() { + var doc = document.implementation.createDocument(null, ""); + assert_equals(doc.contentType, "application/xml"); + var el = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); + el.setAttributeNS("foo", "A:B", ""); + el.setAttributeNS("bar", "c:D", ""); + el.setAttributeNS("baz", "e:F", ""); + el.setAttributeNS("qux", "g:h", ""); + el.setAttributeNS("", "I", ""); + el.setAttributeNS("", "j", ""); + assert_array_equals(Object.getOwnPropertyNames(el.attributes), + ["0", "1", "2", "3", "4", "5", "A:B", "c:D", "e:F", "g:h", "I", "j"]) + for (var propName of Object.getOwnPropertyNames(el.attributes)) { + assert_true(el.attributes[propName] instanceof Attr, + "el.attributes has an Attr for property name " + propName); + } +}, "Own property names should include all qualified names for an HTML element in a non-HTML document"); </script>