diff options
-rw-r--r-- | components/layout/layout_task.rs | 29 | ||||
-rw-r--r-- | components/layout/wrapper.rs | 31 | ||||
-rw-r--r-- | components/script/dom/document.rs | 5 | ||||
-rw-r--r-- | components/script/dom/window.rs | 10 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 2 |
5 files changed, 51 insertions, 26 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index f3fd3546671..4ea12e58796 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -52,6 +52,7 @@ use query::{LayoutRPCImpl, process_content_box_request, process_content_boxes_re use query::{MarginPadding, MarginRetrievingFragmentBorderBoxIterator, PositionProperty}; use query::{PositionRetrievingFragmentBorderBoxIterator, Side}; use script::dom::bindings::js::LayoutJS; +use script::dom::document::Document; use script::dom::node::{LayoutData, Node}; use script::layout_interface::Animation; use script::layout_interface::{LayoutChan, LayoutRPC, OffsetParentResponse}; @@ -89,8 +90,7 @@ use util::opts; use util::task::spawn_named_with_send_on_failure; use util::task_state; use util::workqueue::WorkQueue; -use wrapper::LayoutNode; -use wrapper::ThreadSafeLayoutNode; +use wrapper::{LayoutDocument, LayoutNode, ThreadSafeLayoutNode}; /// The number of screens of data we're allowed to generate display lists for in each direction. pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8; @@ -1137,13 +1137,16 @@ impl LayoutTask { let _ajst = AutoJoinScriptTask { data: data }; // FIXME: Isolate this transmutation into a "bridge" module. - // FIXME(rust#16366): The following line had to be moved because of a - // rustc bug. It should be in the next unsafe block. - let mut node: LayoutJS<Node> = unsafe { - LayoutJS::from_trusted_node_address(data.document_root) + let mut doc: LayoutJS<Document> = unsafe { + LayoutJS::from_trusted_node_address(data.document).downcast::<Document>().unwrap() }; - let node: &mut LayoutNode = unsafe { - transmute(&mut node) + let doc: &mut LayoutDocument = unsafe { + transmute(&mut doc) + }; + + let mut node: LayoutNode = match doc.root_node() { + None => return, + Some(x) => x, }; debug!("layout: received layout request for: {}", self.url.serialize()); @@ -1187,11 +1190,11 @@ impl LayoutTask { let needs_reflow = screen_size_changed && !needs_dirtying; unsafe { if needs_dirtying { - LayoutTask::dirty_all_nodes(node); + LayoutTask::dirty_all_nodes(&mut node); } } if needs_reflow { - if let Some(mut flow) = self.try_get_layout_root(*node) { + if let Some(mut flow) = self.try_get_layout_root(node) { LayoutTask::reflow_all_nodes(flow_ref::deref_mut(&mut flow)); } } @@ -1213,16 +1216,16 @@ impl LayoutTask { let rw_data = &mut *rw_data; match rw_data.parallel_traversal { None => { - sequential::traverse_dom_preorder(*node, &shared_layout_context); + sequential::traverse_dom_preorder(node, &shared_layout_context); } Some(ref mut traversal) => { - parallel::traverse_dom_preorder(*node, &shared_layout_context, traversal); + parallel::traverse_dom_preorder(node, &shared_layout_context, traversal); } } }); // Retrieve the (possibly rebuilt) root flow. - rw_data.root_flow = self.try_get_layout_root((*node).clone()); + rw_data.root_flow = self.try_get_layout_root(node.clone()); } // Send new canvas renderers to the paint task diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index c59fb978e38..d42fa386ec2 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -43,6 +43,7 @@ use script::dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, NodeTypeId use script::dom::bindings::conversions::Castable; use script::dom::bindings::js::LayoutJS; use script::dom::characterdata::LayoutCharacterDataHelpers; +use script::dom::document::{Document, LayoutDocumentHelpers}; use script::dom::element; use script::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::htmlcanvaselement::{LayoutHTMLCanvasElementHelpers, HTMLCanvasData}; @@ -105,6 +106,12 @@ impl<'ln> LayoutNode<'ln> { } } + pub fn is_element(&self) -> bool { + unsafe { + self.node.is_element_for_layout() + } + } + pub fn dump(self) { self.dump_indent(0); } @@ -336,6 +343,30 @@ impl<'a> Iterator for LayoutTreeIterator<'a> { } } +// A wrapper around documents that ensures ayout can only ever access safe properties. +#[derive(Copy, Clone)] +pub struct LayoutDocument<'le> { + document: LayoutJS<Document>, + chain: PhantomData<&'le ()>, +} + +impl<'le> LayoutDocument<'le> { + pub fn as_node(&self) -> LayoutNode<'le> { + LayoutNode { + node: self.document.upcast(), + chain: PhantomData, + } + } + + pub fn root_node(&self) -> Option<LayoutNode<'le>> { + let mut node = self.as_node().first_child(); + while node.is_some() && !node.unwrap().is_element() { + node = node.unwrap().next_sibling(); + } + node + } +} + /// A wrapper around elements that ensures layout can only ever access safe properties. #[derive(Copy, Clone)] pub struct LayoutElement<'le> { diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index a05679086e9..b8819fc4c86 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1175,15 +1175,14 @@ pub enum DocumentSource { NotFromParser, } +#[allow(unsafe_code)] pub trait LayoutDocumentHelpers { - #[allow(unsafe_code)] unsafe fn is_html_document_for_layout(&self) -> bool; } +#[allow(unsafe_code)] impl LayoutDocumentHelpers for LayoutJS<Document> { - #[allow(unrooted_must_root)] #[inline] - #[allow(unsafe_code)] unsafe fn is_html_document_for_layout(&self) -> bool { (*self.unsafe_get()).is_html_document } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index afae2923bf5..761ede6edf8 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -885,14 +885,6 @@ impl Window { /// /// TODO(pcwalton): Only wait for style recalc, since we have off-main-thread layout. pub fn force_reflow(&self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason) { - let document = self.Document(); - let root = document.r().GetDocumentElement(); - let root = match root.r() { - Some(root) => root, - None => return, - }; - let root = root.upcast::<Node>(); - let window_size = match self.window_size.get() { Some(window_size) => window_size, None => return, @@ -923,7 +915,7 @@ impl Window { goal: goal, page_clip_rect: self.page_clip_rect.get(), }, - document_root: root.to_trusted_node_address(), + document: self.Document().r().upcast::<Node>().to_trusted_node_address(), window_size: window_size, script_chan: self.control_chan.clone(), script_join_chan: join_chan, diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index 9647ddd4376..5c41a04363c 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -174,7 +174,7 @@ pub struct ScriptReflow { /// General reflow data. pub reflow_info: Reflow, /// The document node. - pub document_root: TrustedNodeAddress, + pub document: TrustedNodeAddress, /// The channel through which messages can be sent back to the script task. pub script_chan: Sender<ConstellationControlMsg>, /// The current window size. |