aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/main/layout
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-05-03 14:25:22 -0400
committerbors-servo <release+servo@mozilla.com>2014-05-03 14:25:22 -0400
commit731e66ff132e41cdc49bc5324c0e15be19c46ec2 (patch)
treeccce9b42e8a6c54245e53620082efe0b9840eae1 /src/components/main/layout
parent4051a8096d7ba7e7f9c86e76d0b4bffd83e85805 (diff)
parent91278da9dd55582401154e07f9eea34425a332c2 (diff)
downloadservo-731e66ff132e41cdc49bc5324c0e15be19c46ec2.tar.gz
servo-731e66ff132e41cdc49bc5324c0e15be19c46ec2.zip
auto merge of #2101 : jdm/servo/newroot_rebase, r=Ms2ger
As described in #1764, this strategy uses the following properties: * DOM members are `JS<T>` types. These cannot be used with being explicitly rooted, but they are required for compiler-derived trace hooks. * Methods that take DOM type arguments receive `&[mut] JSRef<T>`. These are rooted value references that are cloneable but cannot escape. * Methods that return DOM values use `Unrooted<T>`. These are values that may or may not be rooted elsewhere, but callers must root them in order to interact with them in any way. One unsoundness hole exists - `Unrooted` values must be rooted ASAP, or there exists the danger that JSAPI calls could be made that could cause the underlying JS value to be GCed. * All methods are implemented on `JSRef<T>`, enforcing the requirement that all DOM values are rooted for the duration of a method call (with a few exceptions for layout-related code, which cannot root values and therefore interacts with `JS<T>` and `&T` values - this is safe under the assumption that layout code interacts with DOM nodes that are in the tree, therefore rooted, and does not run concurrently with content code)
Diffstat (limited to 'src/components/main/layout')
-rw-r--r--src/components/main/layout/construct.rs5
-rw-r--r--src/components/main/layout/wrapper.rs38
2 files changed, 24 insertions, 19 deletions
diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs
index 72ce8e09b97..46f5c5ef287 100644
--- a/src/components/main/layout/construct.rs
+++ b/src/components/main/layout/construct.rs
@@ -45,7 +45,6 @@ use layout::wrapper::{Before, BeforeBlock, After, AfterBlock, Normal};
use gfx::display_list::OpaqueNode;
use gfx::font_context::FontContext;
-use script::dom::bindings::codegen::InheritTypes::TextCast;
use script::dom::bindings::js::JS;
use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId};
use script::dom::element::{HTMLObjectElementTypeId};
@@ -1064,8 +1063,8 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
match self.type_id() {
Some(TextNodeTypeId) => {
unsafe {
- let text: JS<Text> = TextCast::to(self.get_jsmanaged()).unwrap();
- if !is_whitespace(text.get().characterdata.data) {
+ let text: JS<Text> = self.get_jsmanaged().transmute_copy();
+ if !is_whitespace((*text.unsafe_get()).characterdata.data) {
return false
}
diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs
index 162c06d52a9..4aa10c3ba63 100644
--- a/src/components/main/layout/wrapper.rs
+++ b/src/components/main/layout/wrapper.rs
@@ -37,10 +37,11 @@ use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived};
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementDerived, TextDerived};
use script::dom::bindings::js::JS;
use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId};
-use script::dom::element::{HTMLLinkElementTypeId};
+use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers};
use script::dom::htmliframeelement::HTMLIFrameElement;
-use script::dom::htmlimageelement::HTMLImageElement;
-use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId, NodeHelpers};
+use script::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
+use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId};
+use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers};
use script::dom::text::Text;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_util::namespace;
@@ -95,7 +96,7 @@ pub trait TLayoutNode {
fail!("not an image!")
}
let image_element: JS<HTMLImageElement> = self.get_jsmanaged().transmute_copy();
- (*image_element.unsafe_get()).image().as_ref().map(|url| (*url).clone())
+ image_element.image().as_ref().map(|url| (*url).clone())
}
}
@@ -163,7 +164,9 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
}
fn type_id(&self) -> Option<NodeTypeId> {
- Some(self.node.type_id())
+ unsafe {
+ Some(self.node.type_id_for_layout())
+ }
}
unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> {
@@ -172,7 +175,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
fn first_child(&self) -> Option<LayoutNode<'ln>> {
unsafe {
- self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node))
+ self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
}
}
@@ -221,19 +224,19 @@ impl<'ln> LayoutNode<'ln> {
impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
fn parent_node(&self) -> Option<LayoutNode<'ln>> {
unsafe {
- self.get().parent_node_ref().map(|node| self.new_with_this_lifetime(node))
+ self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(node))
}
}
fn prev_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe {
- self.get().prev_sibling_ref().map(|node| self.new_with_this_lifetime(node))
+ self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(node))
}
}
fn next_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe {
- self.get().next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
+ self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
}
}
@@ -241,8 +244,9 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
#[inline]
fn as_element(&self) -> LayoutElement<'ln> {
unsafe {
+ assert!(self.node.is_element_for_layout());
let elem: JS<Element> = self.node.transmute_copy();
- let element = elem.get();
+ let element = &*elem.unsafe_get();
LayoutElement {
element: cast::transmute_region(element),
}
@@ -258,9 +262,9 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
}
fn match_attr(&self, attr: &AttrSelector, test: |&str| -> bool) -> bool {
- let element = self.as_element();
let name = unsafe {
- if element.element.html_element_in_html_document_for_layout() {
+ let element: JS<Element> = self.node.transmute_copy();
+ if element.html_element_in_html_document_for_layout() {
attr.lower_name.as_slice()
} else {
attr.name.as_slice()
@@ -268,6 +272,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
};
match attr.namespace {
SpecificNamespace(ref ns) => {
+ let element = self.as_element();
element.get_attr(ns, name)
.map_or(false, |attr| test(attr))
},
@@ -459,7 +464,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
}
unsafe {
- self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node))
+ self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
}
}
@@ -509,10 +514,10 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
/// Returns the next sibling of this node. Unsafe and private because this can lead to races.
unsafe fn next_sibling(&self) -> Option<ThreadSafeLayoutNode<'ln>> {
if self.pseudo == Before || self.pseudo == BeforeBlock {
- return self.get().first_child_ref().map(|node| self.new_with_this_lifetime(node))
+ return self.get_jsmanaged().first_child_ref().map(|node| self.new_with_this_lifetime(node))
}
- self.node.get().next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
+ self.get_jsmanaged().next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
}
/// Returns an iterator over this node's children.
@@ -527,7 +532,8 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
#[inline]
pub fn as_element(&self) -> ThreadSafeLayoutElement {
unsafe {
- let elem: JS<Element> = self.node.get_jsmanaged().transmute_copy();
+ assert!(self.get_jsmanaged().is_element_for_layout());
+ let elem: JS<Element> = self.get_jsmanaged().transmute_copy();
let element = elem.unsafe_get();
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
// implementations.