aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/layout_task.rs29
-rw-r--r--components/layout/wrapper.rs31
-rw-r--r--components/script/dom/document.rs5
-rw-r--r--components/script/dom/window.rs10
-rw-r--r--components/script/layout_interface.rs2
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.