diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2015-02-27 16:29:02 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2015-03-03 07:12:51 +1000 |
commit | 611fd7a8461a27387c06786d06dd48a39c112393 (patch) | |
tree | 4884357277b9324a8f6d06af9c1a96918a2679e9 /components/script | |
parent | 8ad3c5aeb65e473a4c099b12e9439dfc556024f8 (diff) | |
download | servo-611fd7a8461a27387c06786d06dd48a39c112393.tar.gz servo-611fd7a8461a27387c06786d06dd48a39c112393.zip |
Reap layout data whenever a node is removed from the tree.
Also introduce a clear() function to layout data which will be used to clear items such as compositor layouts.
Clear the layout data when a node becomes display:none.
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/node.rs | 47 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 4 |
2 files changed, 17 insertions, 34 deletions
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 18910764188..a7b5e5484d6 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -177,9 +177,7 @@ impl NodeFlags { impl Drop for Node { #[allow(unsafe_blocks)] fn drop(&mut self) { - unsafe { - self.reap_layout_data(); - } + self.layout_data.dispose(); } } @@ -205,6 +203,8 @@ pub struct LayoutData { _data: NonZero<*const ()>, } +unsafe impl Send for LayoutData {} + pub struct LayoutDataRef { pub data_cell: RefCell<Option<LayoutData>>, } @@ -218,18 +218,17 @@ impl LayoutDataRef { } } - /// Returns true if there is layout data present. - #[inline] - pub fn is_present(&self) -> bool { - self.data_cell.borrow().is_some() - } - - /// Take the chan out of the layout data if it is present. - pub fn take_chan(&self) -> Option<LayoutChan> { - let mut layout_data = self.data_cell.borrow_mut(); - match &mut *layout_data { - &mut None => None, - &mut Some(ref mut layout_data) => Some(layout_data.chan.take().unwrap()), + /// Sends layout data, if any, back to the layout task to be destroyed. + pub fn dispose(&self) { + if let Some(mut layout_data) = mem::replace(&mut *self.borrow_mut(), None) { + let layout_chan = layout_data.chan.take(); + match layout_chan { + None => {} + Some(chan) => { + let LayoutChan(chan) = chan; + chan.send(Msg::ReapLayoutData(layout_data)).unwrap() + } + } } } @@ -258,8 +257,6 @@ impl LayoutDataRef { } } -unsafe impl Send for LayoutDataRef {} - /// The different types of nodes. #[derive(Copy, PartialEq, Debug)] #[jstraceable] @@ -302,6 +299,7 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { for node in self.traverse_preorder() { vtable_for(&node).unbind_from_tree(parent_in_doc); } + self.layout_data.dispose(); } // @@ -1648,21 +1646,6 @@ impl Node { Temporary::from_rooted(copy.r()) } - /// Sends layout data, if any, back to the layout task to be destroyed. - unsafe fn reap_layout_data(&mut self) { - if self.layout_data.is_present() { - let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new()); - let layout_chan = layout_data.take_chan(); - match layout_chan { - None => {} - Some(chan) => { - let LayoutChan(chan) = chan; - chan.send(Msg::ReapLayoutData(layout_data)).unwrap() - }, - } - } - } - pub fn collect_text_contents<'a, T: Iterator<Item=JSRef<'a, Node>>>(iterator: T) -> String { let mut content = String::new(); for node in iterator { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index c82370207cf..5b83c471b73 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -6,7 +6,7 @@ //! interface helps reduce coupling between these two components, and enables //! the DOM to be placed in a separate crate from layout. -use dom::node::LayoutDataRef; +use dom::node::LayoutData; use geom::point::Point2D; use geom::rect::Rect; @@ -41,7 +41,7 @@ pub enum Msg { /// Destroys layout data associated with a DOM node. /// /// TODO(pcwalton): Maybe think about batching to avoid message traffic. - ReapLayoutData(LayoutDataRef), + ReapLayoutData(LayoutData), /// Requests that the layout task enter a quiescent state in which no more messages are /// accepted except `ExitMsg`. A response message will be sent on the supplied channel when |