diff options
author | Nova Fallen <nfallen@seas.upenn.edu> | 2015-10-25 13:05:22 -0400 |
---|---|---|
committer | Nova Fallen <nfallen@seas.upenn.edu> | 2015-10-30 21:13:29 -0400 |
commit | 73c4af626ad261225d0fba23c78b1a8bceeac411 (patch) | |
tree | 7cf9bab0dd611678a85e9d64f6f981ac7e5c825a | |
parent | f6e3146de248554607790108680a43844dff70bf (diff) | |
download | servo-73c4af626ad261225d0fba23c78b1a8bceeac411.tar.gz servo-73c4af626ad261225d0fba23c78b1a8bceeac411.zip |
Implement DOMStringMap::SupportedPropertyNames and NamedNodeMap::SupportedPropertyNames
7 files changed, 145 insertions, 12 deletions
diff --git a/components/script/dom/domstringmap.rs b/components/script/dom/domstringmap.rs index 95f727c93cb..bed48031786 100644 --- a/components/script/dom/domstringmap.rs +++ b/components/script/dom/domstringmap.rs @@ -61,7 +61,6 @@ impl DOMStringMapMethods for DOMStringMap { // https://html.spec.whatwg.org/multipage/#the-domstringmap-interface:supported-property-names fn SupportedPropertyNames(&self) -> Vec<DOMString> { - // FIXME: unimplemented (https://github.com/servo/servo/issues/7273) - vec![] + self.element.supported_prop_names_custom_attr().iter().cloned().collect() } } diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index b04082eae4d..ba2bcdacc16 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -27,6 +27,7 @@ use dom::node::{Node, SEQUENTIALLY_FOCUSABLE}; use dom::node::{document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::FocusType; +use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::default::Default; use std::intrinsics; @@ -275,6 +276,45 @@ fn to_snake_case(name: DOMString) -> DOMString { attr_name } + +// https://html.spec.whatwg.org/multipage/#attr-data-* +// if this attribute is in snake case with a data- prefix, +// this function returns a name converted to camel case +// without the data prefix. + +fn to_camel_case(name: &str) -> Option<DOMString> { + if !name.starts_with("data-") { + return None; + } + let name = &name[5..]; + let has_uppercase = name.chars().any(|curr_char| { + curr_char.is_ascii() && curr_char.is_uppercase() + }); + if has_uppercase { + return None; + } + let mut result = "".to_owned(); + let mut name_chars = name.chars(); + while let Some(curr_char) = name_chars.next() { + //check for hyphen followed by character + if curr_char == '\x2d' { + if let Some(next_char) = name_chars.next() { + if next_char.is_ascii() && next_char.is_lowercase() { + result.push(next_char.to_ascii_uppercase()); + } else { + result.push(curr_char); + result.push(next_char); + } + } else { + result.push(curr_char); + } + } else { + result.push(curr_char); + } + } + Some(result) +} + impl HTMLElement { pub fn set_custom_attr(&self, name: DOMString, value: DOMString) -> ErrorResult { if name.chars() @@ -316,6 +356,14 @@ impl HTMLElement { _ => false, } } + + pub fn supported_prop_names_custom_attr(&self) -> Vec<DOMString> { + let element = self.upcast::<Element>(); + element.attrs().iter().map(JS::root).filter_map(|attr| { + let raw_name = attr.r().local_name(); + to_camel_case(&raw_name) + }).collect() + } } impl VirtualMethods for HTMLElement { diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs index 6070c0bb0c2..5c78de0ed51 100644 --- a/components/script/dom/namednodemap.rs +++ b/components/script/dom/namednodemap.rs @@ -85,8 +85,10 @@ impl NamedNodeMapMethods for NamedNodeMap { item } + // https://heycam.github.io/webidl/#dfn-supported-property-names fn SupportedPropertyNames(&self) -> Vec<DOMString> { - // FIXME: unimplemented (https://github.com/servo/servo/issues/7273) - vec![] + self.owner.attrs().iter().map(JS::root).map(|attr| { + (**attr.name()).to_owned() + }).collect() } } diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index d2d65fe522c..d642e0762be 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -13282,6 +13282,14 @@ "url": "/dom/collections/HTMLCollection-supported-property-names.html" }, { + "path": "dom/collections/domstringmap-supported-property-names.html", + "url": "/dom/collections/domstringmap-supported-property-names.html" + }, + { + "path": "dom/collections/namednodemap-supported-property-names.html", + "url": "/dom/collections/namednodemap-supported-property-names.html" + }, + { "path": "dom/events/Event-constants.html", "url": "/dom/events/Event-constants.html" }, diff --git a/tests/wpt/metadata/html/dom/elements/global-attributes/dataset-enumeration.html.ini b/tests/wpt/metadata/html/dom/elements/global-attributes/dataset-enumeration.html.ini deleted file mode 100644 index 7b228c9e6ea..00000000000 --- a/tests/wpt/metadata/html/dom/elements/global-attributes/dataset-enumeration.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[dataset-enumeration.html] - type: testharness - [A dataset should be enumeratable.] - expected: FAIL - - [Only attributes who qualify as dataset properties should be enumeratable in the dataset.] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/dom/collections/domstringmap-supported-property-names.html b/tests/wpt/web-platform-tests/dom/collections/domstringmap-supported-property-names.html new file mode 100644 index 00000000000..f84ee27ae29 --- /dev/null +++ b/tests/wpt/web-platform-tests/dom/collections/domstringmap-supported-property-names.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>DOMStringMap Test: Supported property names</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> + +<div id="edge1" data-="012">Simple</div> + +<div id="edge2" data-id-="012">Simple</div> + +<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth> + John Doe +</div> + +<div id="user2" data-unique-id="1234567890"> Jane Doe </div> + +<div id="user3" data-unique-id="4324324241"> Jim Doe </div> + +<script> + +test(function() { + var element = document.querySelector('#edge1'); + assert_array_equals(Object.getOwnPropertyNames(element.dataset), + [""]); +}, "Object.getOwnPropertyNames on DOMStringMap, empty data attribute"); + +test(function() { + var element = document.querySelector('#edge2'); + assert_array_equals(Object.getOwnPropertyNames(element.dataset), + ["id-"]); +}, "Object.getOwnPropertyNames on DOMStringMap, data attribute trailing hyphen"); + +test(function() { + var element = document.querySelector('#user'); + assert_array_equals(Object.getOwnPropertyNames(element.dataset), + ['id', 'user', 'dateOfBirth']); +}, "Object.getOwnPropertyNames on DOMStringMap, multiple data attributes"); + +test(function() { + var element = document.querySelector('#user2'); + element.dataset.middleName = "mark"; + assert_array_equals(Object.getOwnPropertyNames(element.dataset), + ['uniqueId', 'middleName']); +}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on dataset in JS"); + +test(function() { + var element = document.querySelector('#user3'); + element.setAttribute("data-age", 30); + assert_array_equals(Object.getOwnPropertyNames(element.dataset), + ['uniqueId', 'age']); +}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on element in JS"); + +</script>
\ No newline at end of file diff --git a/tests/wpt/web-platform-tests/dom/collections/namednodemap-supported-property-names.html b/tests/wpt/web-platform-tests/dom/collections/namednodemap-supported-property-names.html new file mode 100644 index 00000000000..2c5dee4efd6 --- /dev/null +++ b/tests/wpt/web-platform-tests/dom/collections/namednodemap-supported-property-names.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<meta charset=utf-8> +<title>NamedNodeMap Test: Supported property names</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<div id="simple" class="fancy">Simple</div> +<input id="result" type="text" value="" width="200px"> +<script> + +test(function() { + var elt = document.querySelector('#simple'); + assert_array_equals(Object.getOwnPropertyNames(elt.attributes), + ['0','1','id','class']); +}, "Object.getOwnPropertyNames on NamedNodeMap"); + +test(function() { + var result = document.getElementById("result"); + assert_array_equals(Object.getOwnPropertyNames(result.attributes), + ['0','1','2','3','id','type','value','width']); +}, "Object.getOwnPropertyNames on NamedNodeMap of input"); + +test(function() { + var result = document.getElementById("result"); + result.removeAttribute("width"); + assert_array_equals(Object.getOwnPropertyNames(result.attributes), + ['0','1','2','id','type','value']); +}, "Object.getOwnPropertyNames on NamedNodeMap after attribute removal"); + +</script>
\ No newline at end of file |