aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-01-22 03:24:28 -0500
committerKeith Yeung <kungfukeith11@gmail.com>2016-01-24 13:05:47 -0500
commit9e3af70941c74eed41f47ff13d0fc7cfd2300403 (patch)
tree0b34e60d1dcb7aa9eedd034baca30fe9324ba726
parente93a460db4902195ec64e6fe67817f9e3a7c1da9 (diff)
downloadservo-9e3af70941c74eed41f47ff13d0fc7cfd2300403.tar.gz
servo-9e3af70941c74eed41f47ff13d0fc7cfd2300403.zip
Implement RadioNodeList
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/nodelist.rs13
-rw-r--r--components/script/dom/radionodelist.rs152
-rw-r--r--components/script/dom/webidls/HTMLFormControlsCollection.webidl6
-rw-r--r--components/script/dom/webidls/NodeList.webidl5
-rw-r--r--components/script/dom/webidls/RadioNodeList.webidl9
6 files changed, 175 insertions, 11 deletions
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 0a9a7217c53..56693280f2f 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -341,6 +341,7 @@ pub mod performance;
pub mod performancetiming;
pub mod processinginstruction;
pub mod progressevent;
+pub mod radionodelist;
pub mod range;
pub mod screen;
pub mod servohtmlparser;
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 6747ee5a948..5987b1b26f0 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -28,7 +28,7 @@ pub struct NodeList {
impl NodeList {
#[allow(unrooted_must_root)]
- fn new_inherited(list_type: NodeListType) -> NodeList {
+ pub fn new_inherited(list_type: NodeListType) -> NodeList {
NodeList {
reflector_: Reflector::new(),
list_type: list_type,
@@ -36,8 +36,7 @@ impl NodeList {
}
#[allow(unrooted_must_root)]
- pub fn new(window: &Window,
- list_type: NodeListType) -> Root<NodeList> {
+ pub fn new(window: &Window, list_type: NodeListType) -> Root<NodeList> {
reflect_dom_object(box NodeList::new_inherited(list_type),
GlobalRef::Window(window), NodeListBinding::Wrap)
}
@@ -93,6 +92,10 @@ impl NodeList {
panic!("called as_children_list() on a simple node list")
}
}
+
+ pub fn get_list_type(&self) -> &NodeListType {
+ &self.list_type
+ }
}
#[derive(JSTraceable, HeapSizeOf)]
@@ -114,6 +117,10 @@ impl ChildrenList {
}
}
+ pub fn get_parent_node(&self) -> &Node {
+ &*self.node
+ }
+
pub fn len(&self) -> u32 {
self.node.children_count()
}
diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs
new file mode 100644
index 00000000000..ebb9909f1d6
--- /dev/null
+++ b/components/script/dom/radionodelist.rs
@@ -0,0 +1,152 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
+use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
+use dom::bindings::codegen::Bindings::RadioNodeListBinding;
+use dom::bindings::codegen::Bindings::RadioNodeListBinding::RadioNodeListMethods;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::inheritance::Castable;
+use dom::bindings::js::Root;
+use dom::bindings::reflector::reflect_dom_object;
+use dom::htmlinputelement::HTMLInputElement;
+use dom::node::Node;
+use dom::nodelist::{NodeList, NodeListType};
+use dom::window::Window;
+use util::str::DOMString;
+
+#[dom_struct]
+pub struct RadioNodeList {
+ node_list: NodeList,
+}
+
+impl RadioNodeList {
+ #[allow(unrooted_must_root)]
+ fn new_inherited(list_type: NodeListType) -> RadioNodeList {
+ RadioNodeList {
+ node_list: NodeList::new_inherited(list_type)
+ }
+ }
+
+ #[allow(unrooted_must_root)]
+ pub fn new(window: &Window, list_type: NodeListType) -> Root<RadioNodeList> {
+ reflect_dom_object(box RadioNodeList::new_inherited(list_type),
+ GlobalRef::Window(window),
+ RadioNodeListBinding::Wrap)
+ }
+
+ // FIXME: This shouldn't need to be implemented here since NodeList (the parent of
+ // RadioNodeList) implements Length
+ // https://github.com/servo/servo/issues/5875
+ pub fn Length(&self) -> u32 {
+ self.node_list.Length()
+ }
+}
+
+impl RadioNodeListMethods for RadioNodeList {
+ // https://html.spec.whatwg.org/multipage/#dom-radionodelist-value
+ fn Value(&self) -> DOMString {
+ match *self.upcast::<NodeList>().get_list_type() {
+ NodeListType::Simple(ref v) => {
+ v.iter().filter_map(|node| {
+ // Step 1
+ node.downcast::<HTMLInputElement>().and_then(|input| {
+ match input.type_() {
+ atom!("radio") if input.Checked() => {
+ // Step 3-4
+ let value = input.Value();
+ Some(if value.is_empty() { DOMString::from("on") } else { value })
+ }
+ _ => None
+ }
+ })
+ }).next()
+ // Step 2
+ .unwrap_or(DOMString::from(""))
+ }
+ NodeListType::Children(ref cl) => {
+ cl.get_parent_node().traverse_preorder().filter_map(|node| {
+ // Step 1
+ node.downcast::<HTMLInputElement>().and_then(|input| {
+ match input.type_() {
+ atom!("radio") if input.Checked() => {
+ // Step 3-4
+ let value = input.Value();
+ Some(if value.is_empty() { DOMString::from("on") } else { value })
+ }
+ _ => None
+ }
+ })
+ }).next()
+ // Step 2
+ .unwrap_or(DOMString::from(""))
+ }
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/infrastructure.html#dom-radionodelist-value
+ fn SetValue(&self, value: DOMString) {
+ match *self.upcast::<NodeList>().get_list_type() {
+ NodeListType::Simple(ref v) => {
+ for node in v.iter() {
+ // Step 1
+ if let Some(input) = node.downcast::<HTMLInputElement>() {
+ match input.type_() {
+ atom!("radio") if value == DOMString::from("on") => {
+ // Step 2
+ let val = input.Value();
+ if val.is_empty() || val == DOMString::from("on") {
+ input.SetChecked(true);
+ return;
+ }
+ }
+ atom!("radio") => {
+ // Step 2
+ if input.Value() == value {
+ input.SetChecked(true);
+ return;
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ }
+ NodeListType::Children(ref cl) => {
+ for node in cl.get_parent_node().traverse_preorder() {
+ // Step 1
+ if let Some(input) = node.downcast::<HTMLInputElement>() {
+ match input.type_() {
+ atom!("radio") if value == DOMString::from("on") => {
+ // Step 2
+ let val = input.Value();
+ if val.is_empty() || val == DOMString::from("on") {
+ input.SetChecked(true);
+ return;
+ }
+ }
+ atom!("radio") => {
+ // Step 2
+ if input.Value() == value {
+ input.SetChecked(true);
+ return;
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ }
+ };
+ }
+
+ // FIXME: This shouldn't need to be implemented here since NodeList (the parent of
+ // RadioNodeList) implements IndexedGetter.
+ // https://github.com/servo/servo/issues/5875
+ //
+ // https://dom.spec.whatwg.org/#dom-nodelist-item
+ fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Root<Node>> {
+ self.node_list.IndexedGetter(index, found)
+ }
+}
diff --git a/components/script/dom/webidls/HTMLFormControlsCollection.webidl b/components/script/dom/webidls/HTMLFormControlsCollection.webidl
index e7f2e84a566..c4a26c7b20c 100644
--- a/components/script/dom/webidls/HTMLFormControlsCollection.webidl
+++ b/components/script/dom/webidls/HTMLFormControlsCollection.webidl
@@ -8,9 +8,3 @@ interface HTMLFormControlsCollection : HTMLCollection {
// inherits length and item()
// getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem()
};
-
-/*
-interface RadioNodeList : NodeList {
- attribute DOMString value;
-};
-*/
diff --git a/components/script/dom/webidls/NodeList.webidl b/components/script/dom/webidls/NodeList.webidl
index 9d40e9e19cf..413a7154606 100644
--- a/components/script/dom/webidls/NodeList.webidl
+++ b/components/script/dom/webidls/NodeList.webidl
@@ -9,7 +9,8 @@
interface NodeList {
[Pure]
- readonly attribute unsigned long length;
- [Pure]
getter Node? item(unsigned long index);
+ [Pure]
+ readonly attribute unsigned long length;
+ // iterable<Node>;
};
diff --git a/components/script/dom/webidls/RadioNodeList.webidl b/components/script/dom/webidls/RadioNodeList.webidl
new file mode 100644
index 00000000000..d3c1ed892dc
--- /dev/null
+++ b/components/script/dom/webidls/RadioNodeList.webidl
@@ -0,0 +1,9 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// https://html.spec.whatwg.org/multipage/#radionodelist
+interface RadioNodeList : NodeList {
+ attribute DOMString value;
+};