aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2014-04-10 17:11:08 -0400
committerJosh Matthews <josh@joshmatthews.net>2014-05-03 14:18:30 -0400
commitdfdda0098a3f169a37c100b36d4dd36ec1d815aa (patch)
treeb4835f3c863c6e45849cf036faf5611925e10189 /src
parentd7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1 (diff)
downloadservo-dfdda0098a3f169a37c100b36d4dd36ec1d815aa.tar.gz
servo-dfdda0098a3f169a37c100b36d4dd36ec1d815aa.zip
Remove JS::get/get_mut to enforce sound rooting practices.
Diffstat (limited to 'src')
-rw-r--r--src/components/main/layout/construct.rs5
-rw-r--r--src/components/main/layout/wrapper.rs6
-rw-r--r--src/components/script/dom/attrlist.rs8
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py29
-rw-r--r--src/components/script/dom/bindings/conversions.rs4
-rw-r--r--src/components/script/dom/bindings/js.rs32
-rw-r--r--src/components/script/dom/bindings/utils.rs11
-rw-r--r--src/components/script/dom/browsercontext.rs16
-rw-r--r--src/components/script/dom/document.rs11
-rw-r--r--src/components/script/dom/domimplementation.rs6
-rw-r--r--src/components/script/dom/element.rs37
-rw-r--r--src/components/script/dom/node.rs66
-rw-r--r--src/components/script/script_task.rs12
13 files changed, 113 insertions, 130 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 b9532e2d31c..d779845c5b5 100644
--- a/src/components/main/layout/wrapper.rs
+++ b/src/components/main/layout/wrapper.rs
@@ -242,7 +242,7 @@ impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
fn as_element(&self) -> LayoutElement<'ln> {
unsafe {
let elem: JS<Element> = self.node.transmute_copy();
- let element = elem.get();
+ let element = &*elem.unsafe_get();
LayoutElement {
element: cast::transmute_region(element),
}
@@ -509,10 +509,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().unsafe_get()).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().unsafe_get()).next_sibling_ref().map(|node| self.new_with_this_lifetime(node))
}
/// Returns an iterator over this node's children.
diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs
index 78f8211e3e0..273378347f0 100644
--- a/src/components/script/dom/attrlist.rs
+++ b/src/components/script/dom/attrlist.rs
@@ -4,7 +4,7 @@
use dom::attr::Attr;
use dom::bindings::codegen::BindingDeclarations::AttrListBinding;
-use dom::bindings::js::{JS, JSRef, Unrooted};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::Element;
use dom::window::Window;
@@ -31,11 +31,13 @@ impl AttrList {
}
pub fn Length(&self) -> u32 {
- self.owner.get().attrs.len() as u32
+ let roots = RootCollection::new();
+ self.owner.root(&roots).attrs.len() as u32
}
pub fn Item(&self, index: u32) -> Option<Unrooted<Attr>> {
- self.owner.get().attrs.as_slice().get(index as uint).map(|x| Unrooted::new(x.clone()))
+ let roots = RootCollection::new();
+ self.owner.root(&roots).attrs.as_slice().get(index as uint).map(|x| Unrooted::new(x.clone()))
}
pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<Attr>> {
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 30ff08e21ff..74de0fe75d4 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -2243,12 +2243,7 @@ class CGCallGenerator(CGThing):
self.cgRoot.append(CGGeneric("result = result_fallible.unwrap();"))
if typeRetValNeedsRooting(returnType):
- rooted_value = CGGeneric("result.root(&roots).root_ref().unrooted()")
- if returnType.nullable():
- rooted_value = CGWrapper(rooted_value, pre="result.map(|result| ", post=")")
- rooted_value = CGWrapper(rooted_value, pre="let result = ", post=";")
-
- self.cgRoot.append(rooted_value)
+ self.cgRoot.append(CGGeneric("let result = result.root(&roots);"))
def define(self):
return self.cgRoot.define()
@@ -4321,7 +4316,7 @@ class CGBindingRoot(CGThing):
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'dom::types::*',
'dom::bindings',
- 'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted}',
+ 'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted, OptionalRootable}',
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
@@ -5321,19 +5316,6 @@ class GlobalGenRoots():
cast = [CGGeneric(string.Template('''pub trait ${castTraitName} {
#[inline(always)]
- fn from<T: ${fromBound}>(derived: &JS<T>) -> JS<Self> {
- unsafe { derived.clone().transmute() }
- }
-
- #[inline(always)]
- fn to<T: ${toBound}+Reflectable>(base: &JS<T>) -> Option<JS<Self>> {
- match base.get().${checkFn}() {
- true => unsafe { Some(base.clone().transmute()) },
- false => None
- }
- }
-
- #[inline(always)]
fn to_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, Self>> {
match base.get().${checkFn}() {
true => unsafe { Some(base.transmute()) },
@@ -5350,19 +5332,16 @@ class GlobalGenRoots():
}
#[inline(always)]
- unsafe fn to_unchecked<T: ${toBound}+Reflectable>(base: &JS<T>) -> JS<Self> {
- assert!(base.get().${checkFn}());
- base.clone().transmute()
- }
-
fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> {
unsafe { derived.transmute() }
}
+ #[inline(always)]
fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> {
unsafe { derived.transmute_mut() }
}
+ #[inline(always)]
fn from_unrooted<T: ${fromBound}+Reflectable>(derived: Unrooted<T>) -> Unrooted<Self> {
unsafe { derived.transmute() }
}
diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs
index 90c0251ba2f..02d6983cf3b 100644
--- a/src/components/script/dom/bindings/conversions.rs
+++ b/src/components/script/dom/bindings/conversions.rs
@@ -2,7 +2,7 @@
* 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/. */
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Root};
use dom::bindings::str::ByteString;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::bindings::utils::jsstring_to_str;
@@ -316,7 +316,7 @@ impl<T: Reflectable+IDLInterface> FromJSValConvertible<()> for JS<T> {
}
}
-impl<T: Reflectable> ToJSValConvertible for JS<T> {
+impl<'a, 'b, T: Reflectable> ToJSValConvertible for Root<'a, 'b, T> {
fn to_jsval(&self, cx: *JSContext) -> JSVal {
self.reflector().to_jsval(cx)
}
diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs
index 2386777cac9..3a3b6bd7166 100644
--- a/src/components/script/dom/bindings/js.rs
+++ b/src/components/script/dom/bindings/js.rs
@@ -106,31 +106,23 @@ impl<T: Reflectable> JS<T> {
}
}
+//XXXjdm This is disappointing. This only gets called from trace hooks, in theory,
+// so it's safe to assume that self is rooted and thereby safe to access.
impl<T: Reflectable> Reflectable for JS<T> {
fn reflector<'a>(&'a self) -> &'a Reflector {
- self.get().reflector()
- }
-
- fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
- self.get_mut().mut_reflector()
- }
-}
-
-impl<T: Reflectable> JS<T> {
- pub fn get<'a>(&'a self) -> &'a T {
- let borrowed = self.ptr.borrow();
unsafe {
- &**borrowed
+ (*self.unsafe_get()).reflector()
}
}
- pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
- let mut borrowed = self.ptr.borrow_mut();
+ fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
unsafe {
- &mut **borrowed
+ (*self.unsafe_get()).mut_reflector()
}
}
+}
+impl<T: Reflectable> JS<T> {
/// Returns an unsafe pointer to the interior of this JS object without touching the borrow
/// flags. This is the only method that be safely accessed from layout. (The fact that this
/// is unsafe is what necessitates the layout wrappers.)
@@ -213,6 +205,16 @@ impl<T: Reflectable> OptionalRootable<T> for Option<Unrooted<T>> {
}
}
+pub trait OptionalRootedRootable<T> {
+ fn root<'a, 'b>(&self, roots: &'a RootCollection) -> Option<Root<'a, 'b, T>>;
+}
+
+impl<T: Reflectable> OptionalRootedRootable<T> for Option<JS<T>> {
+ fn root<'a, 'b>(&self, roots: &'a RootCollection) -> Option<Root<'a, 'b, T>> {
+ self.as_ref().map(|inner| inner.root(roots))
+ }
+}
+
pub trait ResultRootable<T,U> {
fn root<'a, 'b>(self, roots: &'a RootCollection) -> Result<Root<'a, 'b, T>, U>;
}
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 80aa9c364ee..65725b9d923 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
use dom::bindings::conversions::{FromJSValConvertible, IDLInterface};
-use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, Root};
use dom::bindings::trace::Untraceable;
use dom::browsercontext;
use dom::window;
@@ -602,13 +602,16 @@ pub extern fn wrap_for_same_compartment(cx: *JSContext, obj: *JSObject) -> *JSOb
pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject {
unsafe {
+ let roots = RootCollection::new();
debug!("outerizing");
let obj = *obj.unnamed;
- let win: JS<window::Window> =
+ let win: Root<window::Window> =
unwrap_jsmanaged(obj,
IDLInterface::get_prototype_id(None::<window::Window>),
- IDLInterface::get_prototype_depth(None::<window::Window>)).unwrap();
- win.get().browser_context.get_ref().window_proxy()
+ IDLInterface::get_prototype_depth(None::<window::Window>))
+ .unwrap()
+ .root(&roots);
+ win.deref().browser_context.get_ref().window_proxy()
}
}
diff --git a/src/components/script/dom/browsercontext.rs b/src/components/script/dom/browsercontext.rs
index fbb63420520..4a452ccd2ae 100644
--- a/src/components/script/dom/browsercontext.rs
+++ b/src/components/script/dom/browsercontext.rs
@@ -2,7 +2,7 @@
* 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/. */
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::trace::Traceable;
use dom::bindings::utils::Reflectable;
use dom::document::Document;
@@ -32,13 +32,14 @@ impl BrowserContext {
context
}
- pub fn active_document(&self) -> JS<Document> {
- self.history.get(self.active_index).document.clone()
+ pub fn active_document(&self) -> Unrooted<Document> {
+ Unrooted::new(self.history.get(self.active_index).document.clone())
}
- pub fn active_window(&self) -> JS<Window> {
- let doc = self.active_document();
- doc.get().window.clone()
+ pub fn active_window(&self) -> Unrooted<Window> {
+ let roots = RootCollection::new();
+ let doc = self.active_document().root(&roots);
+ Unrooted::new(doc.deref().window.clone())
}
pub fn window_proxy(&self) -> *JSObject {
@@ -47,7 +48,8 @@ impl BrowserContext {
}
pub fn create_window_proxy(&self) -> *JSObject {
- let win = self.active_window();
+ let roots = RootCollection::new();
+ let win = self.active_window().root(&roots);
let page = win.get().page();
let js_info = page.js_info();
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index e2984a1bf82..d0ffb203282 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -660,8 +660,9 @@ impl Document {
pub fn Location(&mut self, _abstract_self: &JSRef<Document>) -> Unrooted<Location> {
let roots = RootCollection::new();
- let window = self.window.root(&roots);
- self.window.get_mut().Location(&*window)
+ let mut window = self.window.root(&roots);
+ let window_alias = self.window.root(&roots);
+ window.get_mut().Location(&*window_alias)
}
pub fn Children(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
@@ -695,11 +696,13 @@ impl Document {
}
pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) {
- self.window.get().damage_and_reflow(damage);
+ let roots = RootCollection::new();
+ self.window.root(&roots).damage_and_reflow(damage);
}
pub fn wait_until_safe_to_modify_dom(&self) {
- self.window.get().wait_until_safe_to_modify_dom();
+ let roots = RootCollection::new();
+ self.window.root(&roots).wait_until_safe_to_modify_dom();
}
diff --git a/src/components/script/dom/domimplementation.rs b/src/components/script/dom/domimplementation.rs
index 7cc9e5ef0d0..0e824306343 100644
--- a/src/components/script/dom/domimplementation.rs
+++ b/src/components/script/dom/domimplementation.rs
@@ -61,9 +61,9 @@ impl DOMImplementation {
Name => Err(NamespaceError),
// Step 3.
QName => {
- let document = self.owner.get().Document();
- let document = document.root(&roots);
- Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &document.root_ref()))
+ let owner = self.owner.root(&roots);
+ let document = owner.deref().Document().root(&roots);
+ Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &*document))
}
}
}
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index e0901de01d8..a3bdeb22d3e 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -216,16 +216,15 @@ pub trait AttributeHandlers {
impl<'a> AttributeHandlers for JSRef<'a, Element> {
fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Unrooted<Attr>> {
+ let roots = RootCollection::new();
if self.get().html_element_in_html_document() {
- self.get().attrs.iter().find(|attr| {
- let attr = attr.get();
+ self.get().attrs.iter().map(|attr| attr.root(&roots)).find(|attr| {
name.to_ascii_lower() == attr.local_name && attr.namespace == namespace
- }).map(|x| Unrooted::new(x.clone()))
+ }).map(|x| Unrooted::new_rooted(&*x))
} else {
- self.get().attrs.iter().find(|attr| {
- let attr = attr.get();
+ self.get().attrs.iter().map(|attr| attr.root(&roots)).find(|attr| {
name == attr.local_name && attr.namespace == namespace
- }).map(|x| Unrooted::new(x.clone()))
+ }).map(|x| Unrooted::new_rooted(&*x))
}
}
@@ -279,7 +278,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
};
- self.get_mut().attrs.get_mut(idx).get_mut().set_value(set_type, value);
+ self.get_mut().attrs.get(idx).root(&roots).set_value(set_type, value);
}
// http://dom.spec.whatwg.org/#dom-element-setattribute
@@ -369,21 +368,22 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
}
fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult {
+ let roots = RootCollection::new();
let (_, local_name) = get_attribute_parts(name.clone());
let self_alias = self.clone();
let node: &JSRef<Node> = NodeCast::from_ref(&self_alias);
node.wait_until_safe_to_modify_dom();
- let idx = self.get().attrs.iter().position(|attr| {
- attr.get().local_name == local_name
+ let idx = self.get().attrs.iter().map(|attr| attr.root(&roots)).position(|attr| {
+ attr.local_name == local_name
});
match idx {
None => (),
Some(idx) => {
if namespace == namespace::Null {
- let removed_raw_value = self.get().attrs.get(idx).get().Value();
+ let removed_raw_value = self.get().attrs.get(idx).root(&roots).Value();
vtable_for(node).before_remove_attr(local_name.clone(), removed_raw_value);
}
@@ -528,11 +528,8 @@ impl Element {
} else {
name
};
- abstract_self.get_attribute(Null, name)
- .map(|s| {
- let s = s.root(&roots);
- s.deref().Value()
- })
+ abstract_self.get_attribute(Null, name).root(&roots)
+ .map(|s| s.deref().Value())
}
// http://dom.spec.whatwg.org/#dom-element-getattributens
@@ -541,11 +538,8 @@ impl Element {
local_name: DOMString) -> Option<DOMString> {
let roots = RootCollection::new();
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
- abstract_self.get_attribute(namespace, local_name)
- .map(|attr| {
- let attr = attr.root(&roots);
- attr.deref().Value()
- })
+ abstract_self.get_attribute(namespace, local_name).root(&roots)
+ .map(|attr| attr.deref().Value())
}
// http://dom.spec.whatwg.org/#dom-element-setattribute
@@ -747,9 +741,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
_ => (),
}
- match self.get_attribute(Null, "id") {
+ match self.get_attribute(Null, "id").root(&roots) {
Some(attr) => {
- let attr = attr.root(&roots);
let mut doc = document_from_node(self).root(&roots);
doc.register_named_element(self, attr.deref().Value());
}
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index 6758efeb65d..fd911b3f0ba 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -11,8 +11,8 @@ use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDeri
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast};
use dom::bindings::codegen::BindingDeclarations::NodeBinding::NodeConstants;
use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted, Root};
-use dom::bindings::js::{OptionalAssignable, UnrootedPushable, OptionalRootable};
-use dom::bindings::js::ResultRootable;
+use dom::bindings::js::{OptionalAssignable, UnrootedPushable, OptionalRootedRootable};
+use dom::bindings::js::{ResultRootable, OptionalRootable};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{ErrorResult, Fallible, NotFound, HierarchyRequest};
use dom::bindings::utils;
@@ -479,27 +479,25 @@ impl<'a> NodeHelpers for JSRef<'a, Node> {
let child_node = child.get_mut();
assert!(child_node.parent_node.is_some());
- match child_node.prev_sibling {
+ match child_node.prev_sibling.root(&roots) {
None => {
let next_sibling = child_node.next_sibling.as_ref().map(|next| next.root(&roots));
this_node.set_first_child(next_sibling.root_ref());
}
Some(ref mut prev_sibling) => {
- let prev_sibling_node = prev_sibling.get_mut();
let next_sibling = child_node.next_sibling.as_ref().map(|next| next.root(&roots));
- prev_sibling_node.set_next_sibling(next_sibling.root_ref());
+ prev_sibling.set_next_sibling(next_sibling.root_ref());
}
}
- match child_node.next_sibling {
+ match child_node.next_sibling.root(&roots) {
None => {
let prev_sibling = child_node.prev_sibling.as_ref().map(|prev| prev.root(&roots));
this_node.set_last_child(prev_sibling.root_ref());
}
Some(ref mut next_sibling) => {
- let next_sibling_node = next_sibling.get_mut();
let prev_sibling = child_node.prev_sibling.as_ref().map(|prev| prev.root(&roots));
- next_sibling_node.set_prev_sibling(prev_sibling.root_ref());
+ next_sibling.set_prev_sibling(prev_sibling.root_ref());
}
}
@@ -916,18 +914,18 @@ impl Node {
pub fn NodeName(&self, abstract_self: &JSRef<Node>) -> DOMString {
match self.type_id {
ElementNodeTypeId(..) => {
- let elem: JS<Element> = ElementCast::to(&abstract_self.unrooted()).unwrap();
+ let elem: &JSRef<Element> = ElementCast::to_ref(abstract_self).unwrap();
elem.get().TagName()
}
TextNodeTypeId => ~"#text",
ProcessingInstructionNodeTypeId => {
- let processing_instruction: JS<ProcessingInstruction> =
- ProcessingInstructionCast::to(&abstract_self.unrooted()).unwrap();
+ let processing_instruction: &JSRef<ProcessingInstruction> =
+ ProcessingInstructionCast::to_ref(abstract_self).unwrap();
processing_instruction.get().Target()
}
CommentNodeTypeId => ~"#comment",
DoctypeNodeTypeId => {
- let doctype: JS<DocumentType> = DocumentTypeCast::to(&abstract_self.unrooted()).unwrap();
+ let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(abstract_self).unwrap();
doctype.get().name.clone()
},
DocumentFragmentNodeTypeId => ~"#document-fragment",
@@ -1016,7 +1014,7 @@ impl Node {
CommentNodeTypeId |
TextNodeTypeId |
ProcessingInstructionNodeTypeId => {
- let chardata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap();
+ let chardata: &JSRef<CharacterData> = CharacterDataCast::to_ref(abstract_self).unwrap();
Some(chardata.get().Data())
}
_ => {
@@ -1091,7 +1089,7 @@ impl Node {
ProcessingInstructionNodeTypeId => {
self.wait_until_safe_to_modify_dom();
- let mut characterdata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap();
+ let characterdata: &mut JSRef<CharacterData> = CharacterDataCast::to_mut_ref(abstract_self).unwrap();
characterdata.get_mut().data = value.clone();
// Notify the document that the content of this node is different
@@ -1482,13 +1480,12 @@ impl Node {
// FIXME: https://github.com/mozilla/servo/issues/1737
copy_elem.namespace = node_elem.namespace.clone();
let window = document.get().window.root(&roots);
- for attr in node_elem.attrs.iter() {
- let attr = attr.get();
+ for attr in node_elem.attrs.iter().map(|attr| attr.root(&roots)) {
copy_elem.attrs.push_unrooted(
Attr::new(&*window,
- attr.local_name.clone(), attr.value.clone(),
- attr.name.clone(), attr.namespace.clone(),
- attr.prefix.clone(), &copy_elem_alias));
+ attr.deref().local_name.clone(), attr.deref().value.clone(),
+ attr.deref().name.clone(), attr.deref().namespace.clone(),
+ attr.deref().prefix.clone(), &copy_elem_alias));
}
},
_ => ()
@@ -1703,40 +1700,41 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-isequalnode
pub fn IsEqualNode(&self, abstract_self: &JSRef<Node>, maybe_node: Option<JSRef<Node>>) -> bool {
fn is_equal_doctype(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
- let doctype: JS<DocumentType> = DocumentTypeCast::to(&node.unrooted()).unwrap();
- let other_doctype: JS<DocumentType> = DocumentTypeCast::to(&other.unrooted()).unwrap();
+ let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap();
+ let other_doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(other).unwrap();
(doctype.get().name == other_doctype.get().name) &&
(doctype.get().public_id == other_doctype.get().public_id) &&
(doctype.get().system_id == other_doctype.get().system_id)
}
fn is_equal_element(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
- let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
- let other_element: JS<Element> = ElementCast::to(&other.unrooted()).unwrap();
+ let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
+ let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap();
// FIXME: namespace prefix
(element.get().namespace == other_element.get().namespace) &&
(element.get().local_name == other_element.get().local_name) &&
(element.get().attrs.len() == other_element.get().attrs.len())
}
fn is_equal_processinginstruction(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
- let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node.unrooted()).unwrap();
- let other_pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&other.unrooted()).unwrap();
+ let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
+ let other_pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(other).unwrap();
(pi.get().target == other_pi.get().target) &&
(pi.get().characterdata.data == other_pi.get().characterdata.data)
}
fn is_equal_characterdata(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
- let characterdata: JS<CharacterData> = CharacterDataCast::to(&node.unrooted()).unwrap();
- let other_characterdata: JS<CharacterData> = CharacterDataCast::to(&other.unrooted()).unwrap();
+ let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(node).unwrap();
+ let other_characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(other).unwrap();
characterdata.get().data == other_characterdata.get().data
}
fn is_equal_element_attrs(node: &JSRef<Node>, other: &JSRef<Node>) -> bool {
- let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
- let other_element: JS<Element> = ElementCast::to(&other.unrooted()).unwrap();
+ let roots = RootCollection::new();
+ let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
+ let other_element: &JSRef<Element> = ElementCast::to_ref(other).unwrap();
assert!(element.get().attrs.len() == other_element.get().attrs.len());
- element.get().attrs.iter().all(|attr| {
- other_element.get().attrs.iter().any(|other_attr| {
- (attr.get().namespace == other_attr.get().namespace) &&
- (attr.get().local_name == other_attr.get().local_name) &&
- (attr.get().value == other_attr.get().value)
+ element.get().attrs.iter().map(|attr| attr.root(&roots)).all(|attr| {
+ other_element.get().attrs.iter().map(|attr| attr.root(&roots)).any(|other_attr| {
+ (attr.namespace == other_attr.namespace) &&
+ (attr.local_name == other_attr.local_name) &&
+ (attr.value == other_attr.value)
})
})
}
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index f29a18b850a..36fc83b1aee 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -277,7 +277,7 @@ impl Page {
let roots = RootCollection::new();
let root = match *self.frame() {
None => return,
- Some(ref frame) => frame.document.get().GetDocumentElement()
+ Some(ref frame) => frame.document.root(&roots).GetDocumentElement()
};
match root.root(&roots) {
None => {},
@@ -359,7 +359,7 @@ impl Page {
let root = match *self.frame() {
None => return,
Some(ref frame) => {
- frame.document.get().GetDocumentElement()
+ frame.document.root(&roots).GetDocumentElement()
}
};
@@ -444,7 +444,7 @@ impl Page {
pub fn hit_test(&self, point: &Point2D<f32>) -> Option<UntrustedNodeAddress> {
let roots = RootCollection::new();
let frame = self.frame();
- let document = frame.get_ref().document.clone();
+ let document = frame.get_ref().document.root(&roots);
let root = document.get().GetDocumentElement().root(&roots);
if root.is_none() {
return None;
@@ -467,7 +467,7 @@ impl Page {
pub fn get_nodes_under_mouse(&self, point: &Point2D<f32>) -> Option<Vec<UntrustedNodeAddress>> {
let roots = RootCollection::new();
let frame = self.frame();
- let document = frame.get_ref().document.clone();
+ let document = frame.get_ref().document.root(&roots);
let root = document.get().GetDocumentElement().root(&roots);
if root.is_none() {
return None;
@@ -737,11 +737,13 @@ impl ScriptTask {
/// Handles a timer that fired.
fn handle_fire_timer_msg(&self, id: PipelineId, timer_id: TimerId) {
+ let roots = RootCollection::new();
+
let mut page_tree = self.page_tree.borrow_mut();
let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a
pipeline ID not associated with this script task. This is a bug.").page();
let frame = page.frame();
- let mut window = frame.get_ref().window.clone();
+ let mut window = frame.get_ref().window.root(&roots);
let is_interval;
match window.get().active_timers.find(&timer_id) {