mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
RadioNodeList now reflects changes to the parent, but has room for performance optimization
This commit is contained in:
parent
6b79a8f042
commit
d59aed606d
6 changed files with 167 additions and 67 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue