aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/nodelist.rs
diff options
context:
space:
mode:
authorPatrick Shaughnessy <pshaughn@comcast.net>2020-01-05 12:58:28 -0500
committerPatrick Shaughnessy <pshaughn@comcast.net>2020-01-10 19:09:38 -0500
commitd59aed606d6c6e96256eecce73c6940c1863c655 (patch)
tree69297639e687693ec75bd20aec7ae17b00938d59 /components/script/dom/nodelist.rs
parent6b79a8f042847aff95b1a4a06a90b637629596a0 (diff)
downloadservo-d59aed606d6c6e96256eecce73c6940c1863c655.tar.gz
servo-d59aed606d6c6e96256eecce73c6940c1863c655.zip
RadioNodeList now reflects changes to the parent, but has room for performance optimization
Diffstat (limited to 'components/script/dom/nodelist.rs')
-rw-r--r--components/script/dom/nodelist.rs54
1 files changed, 49 insertions, 5 deletions
diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs
index 88fdd4cb70c..1fdcef4b340 100644
--- a/components/script/dom/nodelist.rs
+++ b/components/script/dom/nodelist.rs
@@ -7,7 +7,9 @@ use crate::dom::bindings::codegen::Bindings::NodeListBinding;
use crate::dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
+use crate::dom::bindings::str::DOMString;
use crate::dom::htmlelement::HTMLElement;
+use crate::dom::htmlformelement::HTMLFormElement;
use crate::dom::node::{ChildrenMutation, Node};
use crate::dom::window::Window;
use dom_struct::dom_struct;
@@ -19,6 +21,7 @@ pub enum NodeListType {
Simple(Vec<Dom<Node>>),
Children(ChildrenList),
Labels(LabelsList),
+ Radio(RadioList),
}
// https://dom.spec.whatwg.org/#interface-nodelist
@@ -83,6 +86,7 @@ impl NodeListMethods for NodeList {
NodeListType::Simple(ref elems) => elems.len() as u32,
NodeListType::Children(ref list) => list.len(),
NodeListType::Labels(ref list) => list.len(),
+ NodeListType::Radio(ref list) => list.len(),
}
}
@@ -94,6 +98,7 @@ impl NodeListMethods for NodeList {
.map(|node| DomRoot::from_ref(&**node)),
NodeListType::Children(ref list) => list.item(index),
NodeListType::Labels(ref list) => list.item(index),
+ NodeListType::Radio(ref list) => list.item(index),
}
}
@@ -108,20 +113,22 @@ impl NodeList {
if let NodeListType::Children(ref list) = self.list_type {
list
} else {
- panic!("called as_children_list() on a simple node list")
+ panic!("called as_children_list() on a non-children node list")
}
}
- pub fn as_simple_list(&self) -> &Vec<Dom<Node>> {
- if let NodeListType::Simple(ref list) = self.list_type {
+ pub fn as_radio_list(&self) -> &RadioList {
+ if let NodeListType::Radio(ref list) = self.list_type {
list
} else {
- panic!("called as_simple_list() on a children node list")
+ panic!("called as_radio_list() on a non-radio node list")
}
}
pub fn iter<'a>(&'a self) -> impl Iterator<Item = DomRoot<Node>> + 'a {
let len = self.Length();
+ // There is room for optimization here in non-simple cases,
+ // as calling Item repeatedly on a live list can involve redundant work.
(0..len).flat_map(move |i| self.Item(i))
}
}
@@ -328,7 +335,7 @@ impl ChildrenList {
}
}
-// Labels lists: There might room for performance optimization
+// Labels lists: There might be room for performance optimization
// analogous to the ChildrenMutation case of a children list,
// in which we can keep information from an older access live
// if we know nothing has happened that would change it.
@@ -357,3 +364,40 @@ impl LabelsList {
self.element.label_at(index)
}
}
+
+// Radio node lists: There is room for performance improvement here;
+// a form is already aware of changes to its set of controls,
+// so a radio list can cache and cache-invalidate its contents
+// just by hooking into what the form already knows without a
+// separate mutation observer. FIXME #25482
+#[derive(Clone, Copy, JSTraceable, MallocSizeOf)]
+pub enum RadioListMode {
+ ControlsExceptImageInputs,
+ Images,
+}
+
+#[derive(JSTraceable, MallocSizeOf)]
+#[unrooted_must_root_lint::must_root]
+pub struct RadioList {
+ form: Dom<HTMLFormElement>,
+ mode: RadioListMode,
+ name: DOMString,
+}
+
+impl RadioList {
+ pub fn new(form: &HTMLFormElement, mode: RadioListMode, name: DOMString) -> RadioList {
+ RadioList {
+ form: Dom::from_ref(form),
+ mode: mode,
+ name: name,
+ }
+ }
+
+ pub fn len(&self) -> u32 {
+ self.form.count_for_radio_list(self.mode, &self.name)
+ }
+
+ pub fn item(&self, index: u32) -> Option<DomRoot<Node>> {
+ self.form.nth_for_radio_list(index, self.mode, &self.name)
+ }
+}