mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Make Node::is_in_doc O(1)
Added a flags variable inside Node to represent boolean flags, with is_in_doc being the first of them. It is updated whenever a node is appended or removed from a parent. This patch is for: https://github.com/mozilla/servo/issues/1030
This commit is contained in:
parent
0e14745762
commit
cfb73ed123
3 changed files with 50 additions and 2 deletions
|
@ -91,6 +91,9 @@ pub struct Node<View> {
|
||||||
/// The live list of children return by .childNodes.
|
/// The live list of children return by .childNodes.
|
||||||
child_list: Option<@mut NodeList>,
|
child_list: Option<@mut NodeList>,
|
||||||
|
|
||||||
|
/// A bitfield of flags for node items.
|
||||||
|
priv flags: NodeFlags,
|
||||||
|
|
||||||
/// Layout information. Only the layout task may touch this data.
|
/// Layout information. Only the layout task may touch this data.
|
||||||
///
|
///
|
||||||
/// FIXME(pcwalton): We need to send these back to the layout task to be destroyed when this
|
/// FIXME(pcwalton): We need to send these back to the layout task to be destroyed when this
|
||||||
|
@ -98,6 +101,23 @@ pub struct Node<View> {
|
||||||
layout_data: LayoutDataRef,
|
layout_data: LayoutDataRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Flags for node items.
|
||||||
|
pub struct NodeFlags(u8);
|
||||||
|
|
||||||
|
impl NodeFlags {
|
||||||
|
pub fn new(type_id: NodeTypeId) -> NodeFlags {
|
||||||
|
let mut flags = NodeFlags(0);
|
||||||
|
match type_id {
|
||||||
|
DocumentNodeTypeId(_) => { flags.set_is_in_doc(true); }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specifies whether this node is in a document.
|
||||||
|
bitfield!(NodeFlags, is_in_doc, set_is_in_doc, 0x01)
|
||||||
|
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
impl<T> Drop for Node<T> {
|
impl<T> Drop for Node<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
@ -546,9 +566,8 @@ impl<'self, View> AbstractNode<View> {
|
||||||
self.node().children()
|
self.node().children()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue #1030: should not walk the tree
|
|
||||||
pub fn is_in_doc(&self) -> bool {
|
pub fn is_in_doc(&self) -> bool {
|
||||||
self.ancestors().any(|node| node.is_document())
|
self.node().flags.is_in_doc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,6 +668,8 @@ impl Node<ScriptView> {
|
||||||
owner_doc: doc,
|
owner_doc: doc,
|
||||||
child_list: None,
|
child_list: None,
|
||||||
|
|
||||||
|
flags: NodeFlags::new(type_id),
|
||||||
|
|
||||||
layout_data: LayoutDataRef::init(),
|
layout_data: LayoutDataRef::init(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,6 +1023,7 @@ impl Node<ScriptView> {
|
||||||
// Step 8.
|
// Step 8.
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
parent.add_child(*node, child);
|
parent.add_child(*node, child);
|
||||||
|
node.mut_node().flags.set_is_in_doc(parent.is_in_doc());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 9.
|
// Step 9.
|
||||||
|
@ -1080,6 +1102,7 @@ impl Node<ScriptView> {
|
||||||
// Step 6-7: mutation observers.
|
// Step 6-7: mutation observers.
|
||||||
// Step 8.
|
// Step 8.
|
||||||
parent.remove_child(node);
|
parent.remove_child(node);
|
||||||
|
node.mut_node().flags.set_is_in_doc(false);
|
||||||
|
|
||||||
// Step 9.
|
// Step 9.
|
||||||
if !suppress_observers {
|
if !suppress_observers {
|
||||||
|
|
22
src/components/script/macros.rs
Normal file
22
src/components/script/macros.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
macro_rules! bitfield(
|
||||||
|
($bitfieldname:ident, $getter:ident, $setter:ident, $value:expr) => (
|
||||||
|
impl $bitfieldname {
|
||||||
|
#[inline]
|
||||||
|
pub fn $getter(self) -> bool {
|
||||||
|
(*self & $value) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn $setter(&mut self, value: bool) {
|
||||||
|
*self = $bitfieldname((**self & !$value) | (if value { $value } else { 0 }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
|
@ -23,6 +23,9 @@ extern mod style;
|
||||||
extern mod servo_msg (name = "msg");
|
extern mod servo_msg (name = "msg");
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
mod macros;
|
||||||
|
|
||||||
pub mod dom {
|
pub mod dom {
|
||||||
pub mod bindings {
|
pub mod bindings {
|
||||||
pub mod element;
|
pub mod element;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue