aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/node.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2015-07-25 02:13:35 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2015-07-31 23:32:30 +0200
commita49eb14615b12960b0bb35cc2b5c59e46f47d869 (patch)
treebd4024195743abaa1cb055636da1407db89371b0 /components/script/dom/node.rs
parenta54404c92180b839d2cf089d9ec9a6afe8bd5ba3 (diff)
downloadservo-a49eb14615b12960b0bb35cc2b5c59e46f47d869.tar.gz
servo-a49eb14615b12960b0bb35cc2b5c59e46f47d869.zip
Cache the number of children of each node
Diffstat (limited to 'components/script/dom/node.rs')
-rw-r--r--components/script/dom/node.rs56
1 files changed, 41 insertions, 15 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 1f6a681e582..e8cb5641e29 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -106,6 +106,9 @@ pub struct Node {
/// The live list of children return by .childNodes.
child_list: MutNullableHeap<JS<NodeList>>,
+ /// The live count of children of this node.
+ children_count: Cell<u32>,
+
/// A bitfield of flags for node items.
flags: Cell<NodeFlags>,
@@ -430,6 +433,7 @@ pub trait NodeHelpers {
fn type_id(self) -> NodeTypeId;
fn len(self) -> u32;
fn index(self) -> u32;
+ fn children_count(self) -> u32;
fn owner_doc(self) -> Root<Document>;
fn set_owner_doc(self, document: &Document);
@@ -567,7 +571,7 @@ impl<'a> NodeHelpers for &'a Node {
NodeTypeId::CharacterData(_) => {
CharacterDataCast::to_ref(self).unwrap().Length()
},
- _ => self.children().count() as u32
+ _ => self.children_count(),
}
}
@@ -576,6 +580,10 @@ impl<'a> NodeHelpers for &'a Node {
self.preceding_siblings().count() as u32
}
+ fn children_count(self) -> u32 {
+ self.children_count.get()
+ }
+
#[inline]
fn is_anchor_element(self) -> bool {
self.type_id == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement))
@@ -1076,36 +1084,26 @@ pub fn from_untrusted_node_address(_runtime: *mut JSRuntime, candidate: Untruste
}
}
+#[allow(unsafe_code)]
pub trait LayoutNodeHelpers {
- #[allow(unsafe_code)]
unsafe fn type_id_for_layout(&self) -> NodeTypeId;
- #[allow(unsafe_code)]
unsafe fn parent_node_ref(&self) -> Option<LayoutJS<Node>>;
- #[allow(unsafe_code)]
unsafe fn first_child_ref(&self) -> Option<LayoutJS<Node>>;
- #[allow(unsafe_code)]
unsafe fn last_child_ref(&self) -> Option<LayoutJS<Node>>;
- #[allow(unsafe_code)]
unsafe fn prev_sibling_ref(&self) -> Option<LayoutJS<Node>>;
- #[allow(unsafe_code)]
unsafe fn next_sibling_ref(&self) -> Option<LayoutJS<Node>>;
- #[allow(unsafe_code)]
unsafe fn owner_doc_for_layout(&self) -> LayoutJS<Document>;
- #[allow(unsafe_code)]
unsafe fn is_element_for_layout(&self) -> bool;
- #[allow(unsafe_code)]
unsafe fn get_flag(&self, flag: NodeFlags) -> bool;
- #[allow(unsafe_code)]
unsafe fn set_flag(&self, flag: NodeFlags, value: bool);
- #[allow(unsafe_code)]
+ unsafe fn children_count(&self) -> u32;
+
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
- #[allow(unsafe_code)]
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
- #[allow(unsafe_code)]
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
fn get_hover_state_for_layout(&self) -> bool;
@@ -1186,6 +1184,12 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
#[inline]
#[allow(unsafe_code)]
+ unsafe fn children_count(&self) -> u32 {
+ (*self.unsafe_get()).children_count.get()
+ }
+
+ #[inline]
+ #[allow(unsafe_code)]
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>> {
(*self.unsafe_get()).layout_data.borrow()
}
@@ -1482,6 +1486,7 @@ impl Node {
prev_sibling: Default::default(),
owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)),
child_list: Default::default(),
+ children_count: Cell::new(0u32),
flags: Cell::new(NodeFlags::new(type_id)),
layout_data: LayoutDataRef::new(),
@@ -2404,7 +2409,7 @@ impl<'a> NodeMethods for &'a Node {
}
// Step 5.
- if this.children().count() != node.children().count() {
+ if this.children_count() != node.children_count() {
return false;
}
@@ -2557,6 +2562,27 @@ impl<'a> VirtualMethods for &'a Node {
let eventtarget: &&EventTarget = EventTargetCast::from_borrowed_ref(self);
Some(eventtarget as &VirtualMethods)
}
+
+ fn children_changed(&self, mutation: &ChildrenMutation) {
+ if let Some(ref s) = self.super_type() {
+ s.children_changed(mutation);
+ }
+ match *mutation {
+ ChildrenMutation::Append { added, .. } |
+ ChildrenMutation::Insert { added, .. } |
+ ChildrenMutation::Prepend { added, .. } => {
+ self.children_count.set(
+ self.children_count.get() + added.len() as u32);
+ },
+ ChildrenMutation::Replace { added, .. } => {
+ self.children_count.set(
+ self.children_count.get() - 1u32 + added.len() as u32);
+ },
+ ChildrenMutation::ReplaceAll { added, .. } => {
+ self.children_count.set(added.len() as u32);
+ },
+ }
+ }
}
pub trait DisabledStateHelpers {