aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2014-03-31 18:41:28 -0400
committerJosh Matthews <josh@joshmatthews.net>2014-05-03 14:18:30 -0400
commitd7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1 (patch)
treeefd1e7f7ec1dd30467c2a67306e1a639837abead /src
parentffdc3f5b32a345b88eed774848924e862d47c093 (diff)
downloadservo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.tar.gz
servo-d7b96db33ca8f2b8a162df38e0f00e95f5ea6fa1.zip
Implement safe rooting strategy via Unrooted, Root, JSRef, and JS.
Diffstat (limited to 'src')
-rw-r--r--src/components/main/layout/wrapper.rs4
-rw-r--r--src/components/script/dom/attr.rs16
-rw-r--r--src/components/script/dom/attrlist.rs10
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py46
-rw-r--r--src/components/script/dom/bindings/codegen/Configuration.py1
-rw-r--r--src/components/script/dom/bindings/js.rs207
-rw-r--r--src/components/script/dom/bindings/utils.rs14
-rw-r--r--src/components/script/dom/blob.rs8
-rw-r--r--src/components/script/dom/browsercontext.rs8
-rw-r--r--src/components/script/dom/clientrect.rs4
-rw-r--r--src/components/script/dom/clientrectlist.rs14
-rw-r--r--src/components/script/dom/comment.rs6
-rw-r--r--src/components/script/dom/console.rs4
-rw-r--r--src/components/script/dom/document.rs284
-rw-r--r--src/components/script/dom/documentfragment.rs10
-rw-r--r--src/components/script/dom/documenttype.rs4
-rw-r--r--src/components/script/dom/domexception.rs4
-rw-r--r--src/components/script/dom/domimplementation.rs86
-rw-r--r--src/components/script/dom/domparser.rs8
-rw-r--r--src/components/script/dom/element.rs253
-rw-r--r--src/components/script/dom/event.rs21
-rw-r--r--src/components/script/dom/eventdispatcher.rs37
-rw-r--r--src/components/script/dom/eventtarget.rs12
-rw-r--r--src/components/script/dom/formdata.rs6
-rw-r--r--src/components/script/dom/htmlanchorelement.rs4
-rw-r--r--src/components/script/dom/htmlappletelement.rs4
-rw-r--r--src/components/script/dom/htmlareaelement.rs4
-rw-r--r--src/components/script/dom/htmlaudioelement.rs4
-rw-r--r--src/components/script/dom/htmlbaseelement.rs4
-rw-r--r--src/components/script/dom/htmlbodyelement.rs4
-rw-r--r--src/components/script/dom/htmlbrelement.rs4
-rw-r--r--src/components/script/dom/htmlbuttonelement.rs13
-rw-r--r--src/components/script/dom/htmlcanvaselement.rs4
-rw-r--r--src/components/script/dom/htmlcollection.rs73
-rw-r--r--src/components/script/dom/htmldataelement.rs4
-rw-r--r--src/components/script/dom/htmldatalistelement.rs10
-rw-r--r--src/components/script/dom/htmldirectoryelement.rs4
-rw-r--r--src/components/script/dom/htmldivelement.rs4
-rw-r--r--src/components/script/dom/htmldlistelement.rs4
-rw-r--r--src/components/script/dom/htmlelement.rs12
-rw-r--r--src/components/script/dom/htmlembedelement.rs6
-rw-r--r--src/components/script/dom/htmlfieldsetelement.rs25
-rw-r--r--src/components/script/dom/htmlfontelement.rs4
-rw-r--r--src/components/script/dom/htmlformelement.rs15
-rw-r--r--src/components/script/dom/htmlframeelement.rs8
-rw-r--r--src/components/script/dom/htmlframesetelement.rs4
-rw-r--r--src/components/script/dom/htmlheadelement.rs4
-rw-r--r--src/components/script/dom/htmlheadingelement.rs4
-rw-r--r--src/components/script/dom/htmlhrelement.rs4
-rw-r--r--src/components/script/dom/htmlhtmlelement.rs4
-rw-r--r--src/components/script/dom/htmliframeelement.rs20
-rw-r--r--src/components/script/dom/htmlimageelement.rs74
-rw-r--r--src/components/script/dom/htmlinputelement.rs4
-rw-r--r--src/components/script/dom/htmllabelelement.rs4
-rw-r--r--src/components/script/dom/htmllegendelement.rs4
-rw-r--r--src/components/script/dom/htmllielement.rs4
-rw-r--r--src/components/script/dom/htmllinkelement.rs4
-rw-r--r--src/components/script/dom/htmlmainelement.rs4
-rw-r--r--src/components/script/dom/htmlmapelement.rs13
-rw-r--r--src/components/script/dom/htmlmetaelement.rs4
-rw-r--r--src/components/script/dom/htmlmeterelement.rs4
-rw-r--r--src/components/script/dom/htmlmodelement.rs4
-rw-r--r--src/components/script/dom/htmlobjectelement.rs37
-rw-r--r--src/components/script/dom/htmlolistelement.rs4
-rw-r--r--src/components/script/dom/htmloptgroupelement.rs4
-rw-r--r--src/components/script/dom/htmloptionelement.rs6
-rw-r--r--src/components/script/dom/htmloutputelement.rs15
-rw-r--r--src/components/script/dom/htmlparagraphelement.rs4
-rw-r--r--src/components/script/dom/htmlparamelement.rs4
-rw-r--r--src/components/script/dom/htmlpreelement.rs4
-rw-r--r--src/components/script/dom/htmlprogresselement.rs4
-rw-r--r--src/components/script/dom/htmlquoteelement.rs4
-rw-r--r--src/components/script/dom/htmlscriptelement.rs6
-rw-r--r--src/components/script/dom/htmlselectelement.rs21
-rw-r--r--src/components/script/dom/htmlserializer.rs46
-rw-r--r--src/components/script/dom/htmlsourceelement.rs4
-rw-r--r--src/components/script/dom/htmlspanelement.rs4
-rw-r--r--src/components/script/dom/htmlstyleelement.rs21
-rw-r--r--src/components/script/dom/htmltablecaptionelement.rs4
-rw-r--r--src/components/script/dom/htmltablecolelement.rs4
-rw-r--r--src/components/script/dom/htmltabledatacellelement.rs4
-rw-r--r--src/components/script/dom/htmltableelement.rs4
-rw-r--r--src/components/script/dom/htmltableheadercellelement.rs4
-rw-r--r--src/components/script/dom/htmltablerowelement.rs4
-rw-r--r--src/components/script/dom/htmltablesectionelement.rs4
-rw-r--r--src/components/script/dom/htmltemplateelement.rs4
-rw-r--r--src/components/script/dom/htmltextareaelement.rs4
-rw-r--r--src/components/script/dom/htmltimeelement.rs4
-rw-r--r--src/components/script/dom/htmltitleelement.rs4
-rw-r--r--src/components/script/dom/htmltrackelement.rs4
-rw-r--r--src/components/script/dom/htmlulistelement.rs4
-rw-r--r--src/components/script/dom/htmlunknownelement.rs4
-rw-r--r--src/components/script/dom/htmlvideoelement.rs4
-rw-r--r--src/components/script/dom/location.rs4
-rw-r--r--src/components/script/dom/mouseevent.rs14
-rw-r--r--src/components/script/dom/navigator.rs4
-rw-r--r--src/components/script/dom/node.rs765
-rw-r--r--src/components/script/dom/nodelist.rs29
-rw-r--r--src/components/script/dom/processinginstruction.rs4
-rw-r--r--src/components/script/dom/testbinding.rs10
-rw-r--r--src/components/script/dom/text.rs8
-rw-r--r--src/components/script/dom/uievent.rs16
-rw-r--r--src/components/script/dom/validitystate.rs4
-rw-r--r--src/components/script/dom/virtualmethods.rs30
-rw-r--r--src/components/script/dom/window.rs38
-rw-r--r--src/components/script/dom/xmlhttprequest.rs24
-rw-r--r--src/components/script/dom/xmlhttprequestupload.rs4
-rw-r--r--src/components/script/html/hubbub_html_parser.rs91
-rw-r--r--src/components/script/script_task.rs159
109 files changed, 1569 insertions, 1327 deletions
diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs
index 162c06d52a9..b9532e2d31c 100644
--- a/src/components/main/layout/wrapper.rs
+++ b/src/components/main/layout/wrapper.rs
@@ -40,7 +40,7 @@ use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementType
use script::dom::element::{HTMLLinkElementTypeId};
use script::dom::htmliframeelement::HTMLIFrameElement;
use script::dom::htmlimageelement::HTMLImageElement;
-use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId, NodeHelpers};
+use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId, LayoutNodeHelpers};
use script::dom::text::Text;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_util::namespace;
@@ -163,7 +163,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
}
fn type_id(&self) -> Option<NodeTypeId> {
- Some(self.node.type_id())
+ Some(self.node.type_id_for_layout())
}
unsafe fn get_jsmanaged<'a>(&'a self) -> &'a JS<Node> {
diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs
index 5b5fc39d1c9..d6c2d530862 100644
--- a/src/components/script/dom/attr.rs
+++ b/src/components/script/dom/attr.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::AttrBinding;
use dom::bindings::codegen::InheritTypes::NodeCast;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::Element;
use dom::node::Node;
@@ -45,7 +45,7 @@ impl Reflectable for Attr {
impl Attr {
fn new_inherited(local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
- prefix: Option<DOMString>, owner: JS<Element>) -> Attr {
+ prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr {
Attr {
reflector_: Reflector::new(),
local_name: local_name,
@@ -53,25 +53,27 @@ impl Attr {
name: name, //TODO: Intern attribute names
namespace: namespace,
prefix: prefix,
- owner: owner,
+ owner: owner.unrooted(),
}
}
pub fn new(window: &JSRef<Window>, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
- prefix: Option<DOMString>, owner: JS<Element>) -> JS<Attr> {
+ prefix: Option<DOMString>, owner: &JSRef<Element>) -> Unrooted<Attr> {
let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner);
reflect_dom_object(~attr, window, AttrBinding::Wrap)
}
pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) {
- let node: JS<Node> = NodeCast::from(&self.owner);
+ let roots = RootCollection::new();
+ let owner = self.owner.root(&roots);
+ let node: &JSRef<Node> = NodeCast::from_ref(&*owner);
let namespace_is_null = self.namespace == namespace::Null;
match set_type {
ReplacedAttr => {
if namespace_is_null {
- vtable_for(&node).before_remove_attr(self.local_name.clone(), self.value.clone());
+ vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.clone());
}
}
FirstSetAttr => {}
@@ -80,7 +82,7 @@ impl Attr {
self.value = value;
if namespace_is_null {
- vtable_for(&node).after_set_attr(self.local_name.clone(), self.value.clone());
+ vtable_for(node).after_set_attr(self.local_name.clone(), self.value.clone());
}
}
diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs
index ed476897c82..78f8211e3e0 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};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::Element;
use dom::window::Window;
@@ -25,7 +25,7 @@ impl AttrList {
}
}
- pub fn new(window: &JSRef<Window>, elem: &JSRef<Element>) -> JS<AttrList> {
+ pub fn new(window: &JSRef<Window>, elem: &JSRef<Element>) -> Unrooted<AttrList> {
reflect_dom_object(~AttrList::new_inherited(window.unrooted(), elem.unrooted()),
window, AttrListBinding::Wrap)
}
@@ -34,11 +34,11 @@ impl AttrList {
self.owner.get().attrs.len() as u32
}
- pub fn Item(&self, index: u32) -> Option<JS<Attr>> {
- self.owner.get().attrs.as_slice().get(index as uint).map(|x| x.clone())
+ 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()))
}
- pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Attr>> {
+ pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<Attr>> {
let item = self.Item(index);
*found = item.is_some();
item
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 5d4f6cc9bf4..30ff08e21ff 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1008,6 +1008,13 @@ def typeNeedsCx(type, retVal=False):
return True
return type.isCallback() or type.isAny() or type.isObject()
+def typeRetValNeedsRooting(type):
+ if type is None:
+ return False
+ if type.nullable():
+ type = type.inner
+ return type.isGeckoInterface() and not type.isCallback()
+
def memberIsCreator(member):
return member.getExtendedAttribute("Creator") is not None
@@ -1039,7 +1046,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.isGeckoInterface():
descriptor = descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name)
- result = CGGeneric(descriptor.nativeType)
+ result = CGGeneric(descriptor.returnType)
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
return result
@@ -2235,6 +2242,14 @@ class CGCallGenerator(CGThing):
self.cgRoot.append(CGGeneric("}"))
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)
+
def define(self):
return self.cgRoot.define()
@@ -4306,7 +4321,7 @@ class CGBindingRoot(CGThing):
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'dom::types::*',
'dom::bindings',
- 'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}',
+ 'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted}',
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}',
@@ -5277,8 +5292,9 @@ class GlobalGenRoots():
descriptors = config.getDescriptors(register=True, hasInterfaceObject=True)
allprotos = [CGGeneric("#![allow(unused_imports)]\n"),
CGGeneric("use dom::types::*;\n"),
- CGGeneric("use dom::bindings::js::{JS, JSRef};\n"),
+ CGGeneric("use dom::bindings::js::{JS, JSRef, Unrooted};\n"),
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
+ CGGeneric("use dom::bindings::utils::Reflectable;\n"),
CGGeneric("use serialize::{Encodable, Encoder};\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n")]
for descriptor in descriptors:
@@ -5310,7 +5326,7 @@ class GlobalGenRoots():
}
#[inline(always)]
- fn to<T: ${toBound}>(base: &JS<T>) -> Option<JS<Self>> {
+ fn to<T: ${toBound}+Reflectable>(base: &JS<T>) -> Option<JS<Self>> {
match base.get().${checkFn}() {
true => unsafe { Some(base.clone().transmute()) },
false => None
@@ -5318,7 +5334,23 @@ class GlobalGenRoots():
}
#[inline(always)]
- unsafe fn to_unchecked<T: ${toBound}>(base: &JS<T>) -> JS<Self> {
+ 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()) },
+ false => None
+ }
+ }
+
+ #[inline(always)]
+ fn to_mut_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a mut JSRef<'b, T>) -> Option<&'a mut JSRef<'b, Self>> {
+ match base.get().${checkFn}() {
+ true => unsafe { Some(base.transmute_mut()) },
+ false => None
+ }
+ }
+
+ #[inline(always)]
+ unsafe fn to_unchecked<T: ${toBound}+Reflectable>(base: &JS<T>) -> JS<Self> {
assert!(base.get().${checkFn}());
base.clone().transmute()
}
@@ -5330,6 +5362,10 @@ class GlobalGenRoots():
fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> {
unsafe { derived.transmute_mut() }
}
+
+ fn from_unrooted<T: ${fromBound}+Reflectable>(derived: Unrooted<T>) -> Unrooted<Self> {
+ unsafe { derived.transmute() }
+ }
}
''').substitute({'checkFn': 'is_' + name.lower(),
'castTraitName': name + 'Cast',
diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py
index a1ccb460ee2..eedb200c75e 100644
--- a/src/components/script/dom/bindings/codegen/Configuration.py
+++ b/src/components/script/dom/bindings/codegen/Configuration.py
@@ -133,6 +133,7 @@ class Descriptor(DescriptorProvider):
else:
nativeTypeDefault = 'JS<%s>' % ifaceName
+ self.returnType = "Unrooted<%s>" % ifaceName
self.nativeType = desc.get('nativeType', nativeTypeDefault)
self.concreteType = desc.get('concreteType', ifaceName)
self.needsAbstract = desc.get('needsAbstract', [])
diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs
index dac459f9c03..2386777cac9 100644
--- a/src/components/script/dom/bindings/js.rs
+++ b/src/components/script/dom/bindings/js.rs
@@ -10,8 +10,52 @@ use layout_interface::TrustedNodeAddress;
use std::cast;
use std::cell::{Cell, RefCell};
use std::ptr;
-//use std::ops::{Deref, DerefMut};
+/// A type that represents a JS-owned value that may or may not be rooted.
+/// Importantly, it requires rooting in order to interact with the value in any way.
+/// Can be assigned into JS-owned member fields (ie. JS<T> types) safely via the
+/// `JS<T>::assign` method or `OptionalAssignable::assign` (for Option<JS<T>> fields).
+pub struct Unrooted<T> {
+ inner: JS<T>
+}
+
+impl<T> Eq for Unrooted<T> {
+ fn eq(&self, other: &Unrooted<T>) -> bool {
+ self.inner == other.inner
+ }
+}
+
+impl<T: Reflectable> Unrooted<T> {
+ /// Create a new Unrooted value from a JS-owned value.
+ pub fn new(inner: JS<T>) -> Unrooted<T> {
+ Unrooted {
+ inner: inner
+ }
+ }
+
+ /// Create a new Unrooted value from a rooted value.
+ pub fn new_rooted<'a>(root: &JSRef<'a, T>) -> Unrooted<T> {
+ Unrooted {
+ inner: root.unrooted()
+ }
+ }
+
+ /// Root this unrooted value.
+ pub fn root<'a, 'b>(self, collection: &'a RootCollection) -> Root<'a, 'b, T> {
+ collection.new_root(&self.inner)
+ }
+
+ unsafe fn inner(&self) -> JS<T> {
+ self.inner.clone()
+ }
+
+ //XXXjdm It would be lovely if this could be private.
+ pub unsafe fn transmute<To>(self) -> Unrooted<To> {
+ cast::transmute(self)
+ }
+}
+
+/// A rooted, JS-owned value. Must only be used as a field in other JS-owned types.
pub struct JS<T> {
ptr: RefCell<*mut T>
}
@@ -32,12 +76,15 @@ impl <T> Clone for JS<T> {
}
impl<T: Reflectable> JS<T> {
+ /// Create a new JS-reflected DOM object; returns an Unrooted type because the new value
+ /// is not safe to use until it is rooted.
pub fn new(obj: ~T,
window: &JSRef<Window>,
- wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~T) -> JS<T>) -> JS<T> {
- wrap_fn(window.get().get_cx(), window, obj)
+ wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~T) -> JS<T>) -> Unrooted<T> {
+ Unrooted::new(wrap_fn(window.get().get_cx(), window, obj))
}
+ /// Create a new JS-owned value wrapped from a raw Rust pointer.
pub unsafe fn from_raw(raw: *mut T) -> JS<T> {
JS {
ptr: RefCell::new(raw)
@@ -45,6 +92,7 @@ impl<T: Reflectable> JS<T> {
}
+ /// Create a new JS-owned value wrapped from an address known to be a Node pointer.
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> {
let TrustedNodeAddress(addr) = inner;
JS {
@@ -52,7 +100,8 @@ impl<T: Reflectable> JS<T> {
}
}
- pub fn root<'a>(&self, collection: &'a RootCollection) -> Root<'a, T> {
+ /// Root this JS-owned value to prevent its collection as garbage.
+ pub fn root<'a, 'b>(&self, collection: &'a RootCollection) -> Root<'a, 'b, T> {
collection.new_root(self)
}
}
@@ -67,7 +116,7 @@ impl<T: Reflectable> Reflectable for JS<T> {
}
}
-impl<T> JS<T> {
+impl<T: Reflectable> JS<T> {
pub fn get<'a>(&'a self) -> &'a T {
let borrowed = self.ptr.borrow();
unsafe {
@@ -88,6 +137,13 @@ impl<T> JS<T> {
pub unsafe fn unsafe_get(&self) -> *mut T {
cast::transmute_copy(&self.ptr)
}
+
+ /// Store an unrooted value in this field. This is safe under the assumption that JS<T>
+ /// values are only used as fields in DOM types that are reachable in the GC graph,
+ /// so this unrooted value becomes transitively rooted for the lifetime of its new owner.
+ pub fn assign(&mut self, val: Unrooted<T>) {
+ *self = unsafe { val.inner() };
+ }
}
impl<From, To> JS<From> {
@@ -105,17 +161,86 @@ pub trait RootedReference<T> {
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>>;
}
-impl<'a, T: Reflectable> RootedReference<T> for Option<Root<'a, T>> {
+impl<'a, 'b, T: Reflectable> RootedReference<T> for Option<Root<'a, 'b, T>> {
fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>> {
self.as_ref().map(|root| root.root_ref())
}
}
+// This trait should never be public; it allows access to unrooted values, and is thus
+// easy to misuse.
+/*definitely not public*/ trait Assignable<T> {
+ fn get_js(&self) -> JS<T>;
+}
+
+impl<T> Assignable<T> for JS<T> {
+ fn get_js(&self) -> JS<T> {
+ self.clone()
+ }
+}
+
+impl<'a, T> Assignable<T> for JSRef<'a, T> {
+ fn get_js(&self) -> JS<T> {
+ self.unrooted()
+ }
+}
+
+// Assignable should not be exposed publically, since it's used to
+// extract unrooted values in a safe way WHEN USED CORRECTLY.
+impl<T: Reflectable> Assignable<T> for Unrooted<T> {
+ fn get_js(&self) -> JS<T> {
+ unsafe { self.inner() }
+ }
+}
+
+pub trait OptionalAssignable<T> {
+ fn assign(&mut self, val: Option<T>);
+}
+
+impl<T: Assignable<U>, U: Reflectable> OptionalAssignable<T> for Option<JS<U>> {
+ fn assign(&mut self, val: Option<T>) {
+ *self = val.map(|val| val.get_js());
+ }
+}
+
+pub trait OptionalRootable<T> {
+ fn root<'a, 'b>(self, roots: &'a RootCollection) -> Option<Root<'a, 'b, T>>;
+}
+
+impl<T: Reflectable> OptionalRootable<T> for Option<Unrooted<T>> {
+ fn root<'a, 'b>(self, roots: &'a RootCollection) -> Option<Root<'a, 'b, T>> {
+ self.map(|inner| inner.root(roots))
+ }
+}
+
+pub trait ResultRootable<T,U> {
+ fn root<'a, 'b>(self, roots: &'a RootCollection) -> Result<Root<'a, 'b, T>, U>;
+}
+
+impl<T: Reflectable, U> ResultRootable<T, U> for Result<Unrooted<T>, U> {
+ fn root<'a, 'b>(self, roots: &'a RootCollection) -> Result<Root<'a, 'b, T>, U> {
+ self.map(|inner| inner.root(roots))
+ }
+}
+
+/// Provides a facility to push unrooted values onto lists of rooted values. This is safe
+/// under the assumption that said lists are reachable via the GC graph, and therefore the
+/// new values are transitively rooted for the lifetime of their new owner.
+pub trait UnrootedPushable<T> {
+ fn push_unrooted(&mut self, val: Unrooted<T>);
+}
+
+impl<T: Reflectable> UnrootedPushable<T> for Vec<JS<T>> {
+ fn push_unrooted(&mut self, val: Unrooted<T>) {
+ unsafe { self.push(val.inner()) };
+ }
+}
+
#[deriving(Eq, Clone)]
struct RootReference(*JSObject);
impl RootReference {
- fn new<'a, T: Reflectable>(unrooted: &Root<'a, T>) -> RootReference {
+ fn new<'a, 'b, T: Reflectable>(unrooted: &Root<'a, 'b, T>) -> RootReference {
RootReference(unrooted.rooted())
}
@@ -126,6 +251,7 @@ impl RootReference {
static MAX_STACK_ROOTS: uint = 10;
+/// An opaque, LIFO rooting mechanism.
pub struct RootCollection {
roots: [Cell<RootReference>, ..MAX_STACK_ROOTS],
current: Cell<uint>,
@@ -139,7 +265,7 @@ impl RootCollection {
}
}
- fn new_root<'a, T: Reflectable>(&'a self, unrooted: &JS<T>) -> Root<'a, T> {
+ fn new_root<'a, 'b, T: Reflectable>(&'a self, unrooted: &JS<T>) -> Root<'a, 'b, T> {
Root::new(self, unrooted)
}
@@ -147,13 +273,15 @@ impl RootCollection {
let current = self.current.get();
assert!(current < MAX_STACK_ROOTS);
self.roots[current].set(unrooted);
+ debug!(" rooting {:?}", unrooted);
self.current.set(current + 1);
}
- fn root<'a, T: Reflectable>(&self, unrooted: &Root<'a, T>) {
+ fn root<'a, 'b, T: Reflectable>(&self, unrooted: &Root<'a, 'b, T>) {
self.root_impl(RootReference::new(unrooted));
}
+ /// Root a raw JS pointer.
pub fn root_raw(&self, unrooted: *JSObject) {
self.root_impl(RootReference(unrooted));
}
@@ -162,29 +290,41 @@ impl RootCollection {
let mut current = self.current.get();
assert!(current != 0);
current -= 1;
+ debug!("unrooting {:?} (expecting {:?}", self.roots[current].get(), rooted);
assert!(self.roots[current].get() == rooted);
self.roots[current].set(RootReference::null());
self.current.set(current);
}
- fn unroot<'a, T: Reflectable>(&self, rooted: &Root<'a, T>) {
+ fn unroot<'a, 'b, T: Reflectable>(&self, rooted: &Root<'a, 'b, T>) {
self.unroot_impl(RootReference::new(rooted));
}
+ /// Unroot a raw JS pointer. Must occur in reverse order to its rooting.
pub fn unroot_raw(&self, rooted: *JSObject) {
self.unroot_impl(RootReference(rooted));
}
}
-pub struct Root<'a, T> {
+/// A rooted JS value. The JS value is pinned for the duration of this object's lifetime;
+/// roots are additive, so this object's destruction will not invalidate other roots
+/// for the same JS value. Roots cannot outlive the associated RootCollection object.
+/// Attempts to transfer ownership of a Root via moving will trigger dynamic unrooting
+/// failures due to incorrect ordering.
+pub struct Root<'a, 'b, T> {
root_list: &'a RootCollection,
+ jsref: JSRef<'b, T>,
ptr: RefCell<*mut T>,
}
-impl<'a, T: Reflectable> Root<'a, T> {
- fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, T> {
+impl<'a, 'b, T: Reflectable> Root<'a, 'b, T> {
+ fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, 'b, T> {
let root = Root {
root_list: roots,
+ jsref: JSRef {
+ ptr: unrooted.ptr.clone(),
+ chain: unsafe { ::std::cast::transmute_region(&()) },
+ },
ptr: unrooted.ptr.clone()
};
roots.root(&root);
@@ -209,24 +349,27 @@ impl<'a, T: Reflectable> Root<'a, T> {
self.reflector().get_jsobject()
}
+ fn internal_root_ref<'a>(&'a self) -> &'a JSRef<'b, T> {
+ &'a self.jsref
+ }
+
+ fn mut_internal_root_ref<'a>(&'a mut self) -> &'a mut JSRef<'b, T> {
+ &'a mut self.jsref
+ }
+
pub fn root_ref<'b>(&'b self) -> JSRef<'b,T> {
- unsafe {
- JSRef {
- ptr: self.ptr.clone(),
- chain: ::std::cast::transmute_region(&()),
- }
- }
+ self.internal_root_ref().clone()
}
}
#[unsafe_destructor]
-impl<'a, T: Reflectable> Drop for Root<'a, T> {
+impl<'a, 'b, T: Reflectable> Drop for Root<'a, 'b, T> {
fn drop(&mut self) {
self.root_list.unroot(self);
}
}
-impl<'a, T: Reflectable> Reflectable for Root<'a, T> {
+impl<'a, 'b, T: Reflectable> Reflectable for Root<'a, 'b, T> {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.get().reflector()
}
@@ -236,17 +379,29 @@ impl<'a, T: Reflectable> Reflectable for Root<'a, T> {
}
}
-/*impl<'a, T> Deref for Root<'a, T> {
- fn deref<'a>(&'a self) -> &'a T {
+impl<'a, 'b, T: Reflectable> Deref<JSRef<'b, T>> for Root<'a, 'b, T> {
+ fn deref<'c>(&'c self) -> &'c JSRef<'b, T> {
+ self.internal_root_ref()
+ }
+}
+
+impl<'a, 'b, T: Reflectable> DerefMut<JSRef<'b, T>> for Root<'a, 'b, T> {
+ fn deref_mut<'c>(&'c mut self) -> &'c mut JSRef<'b, T> {
+ self.mut_internal_root_ref()
+ }
+}
+
+impl<'a, T: Reflectable> Deref<T> for JSRef<'a, T> {
+ fn deref<'b>(&'b self) -> &'b T {
self.get()
}
}
-impl<'a, T> DerefMut for Root<'a, T> {
- fn deref_mut<'a>(&'a mut self) -> &'a mut T {
+impl<'a, T: Reflectable> DerefMut<T> for JSRef<'a, T> {
+ fn deref_mut<'b>(&'b mut self) -> &'b mut T {
self.get_mut()
}
-}*/
+}
/// Encapsulates a reference to something that is guaranteed to be alive. This is freely copyable.
pub struct JSRef<'a, T> {
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 7f240070ea1..80aa9c364ee 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};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::trace::Untraceable;
use dom::browsercontext;
use dom::window;
@@ -391,7 +391,7 @@ pub fn reflect_dom_object<T: Reflectable>
(obj: ~T,
window: &JSRef<window::Window>,
wrap_fn: extern "Rust" fn(*JSContext, &JSRef<window::Window>, ~T) -> JS<T>)
- -> JS<T> {
+ -> Unrooted<T> {
JS::new(obj, window, wrap_fn)
}
@@ -613,18 +613,20 @@ pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject
}
/// Returns the global object of the realm that the given JS object was created in.
-pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
+pub fn global_object_for_js_object(obj: *JSObject) -> Unrooted<window::Window> {
unsafe {
let global = GetGlobalForObjectCrossCompartment(obj);
let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
- FromJSValConvertible::from_jsval(ptr::null(), ObjectOrNullValue(global), ())
- .ok().expect("found DOM global that doesn't unwrap to Window")
+ Unrooted::new(
+ FromJSValConvertible::from_jsval(ptr::null(), ObjectOrNullValue(global), ())
+ .ok().expect("found DOM global that doesn't unwrap to Window"))
}
}
fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
- let win = global_object_for_js_object(obj);
+ let roots = RootCollection::new();
+ let win = global_object_for_js_object(obj).root(&roots);
let js_info = win.get().page().js_info();
match *js_info {
Some(ref info) => info.js_context.deref().deref().ptr,
diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs
index 8dba1775ff6..0399568063d 100644
--- a/src/components/script/dom/blob.rs
+++ b/src/components/script/dom/blob.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, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::bindings::codegen::BindingDeclarations::BlobBinding;
@@ -23,7 +23,7 @@ impl Blob {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<Blob> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<Blob> {
reflect_dom_object(~Blob::new_inherited(window.unrooted()),
window,
BlobBinding::Wrap)
@@ -31,7 +31,7 @@ impl Blob {
}
impl Blob {
- pub fn Constructor(window: &JSRef<Window>) -> Fallible<JS<Blob>> {
+ pub fn Constructor(window: &JSRef<Window>) -> Fallible<Unrooted<Blob>> {
Ok(Blob::new(window))
}
@@ -43,7 +43,7 @@ impl Blob {
~""
}
- pub fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> JS<Blob> {
+ pub fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> Unrooted<Blob> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
Blob::new(&window.root_ref())
diff --git a/src/components/script/dom/browsercontext.rs b/src/components/script/dom/browsercontext.rs
index 86540c12a53..fbb63420520 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;
+use dom::bindings::js::{JS, JSRef};
use dom::bindings::trace::Traceable;
use dom::bindings::utils::Reflectable;
use dom::document::Document;
@@ -22,7 +22,7 @@ pub struct BrowserContext {
}
impl BrowserContext {
- pub fn new(document: &JS<Document>) -> BrowserContext {
+ pub fn new(document: &JSRef<Document>) -> BrowserContext {
let mut context = BrowserContext {
history: vec!(SessionHistoryEntry::new(document)),
active_index: 0,
@@ -71,9 +71,9 @@ pub struct SessionHistoryEntry {
}
impl SessionHistoryEntry {
- fn new(document: &JS<Document>) -> SessionHistoryEntry {
+ fn new(document: &JSRef<Document>) -> SessionHistoryEntry {
SessionHistoryEntry {
- document: document.clone(),
+ document: document.unrooted(),
children: vec!()
}
}
diff --git a/src/components/script/dom/clientrect.rs b/src/components/script/dom/clientrect.rs
index 977c4569bf5..4e4e2dbdcc6 100644
--- a/src/components/script/dom/clientrect.rs
+++ b/src/components/script/dom/clientrect.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::ClientRectBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
use servo_util::geometry::Au;
@@ -34,7 +34,7 @@ impl ClientRect {
pub fn new(window: &JSRef<Window>,
top: Au, bottom: Au,
- left: Au, right: Au) -> JS<ClientRect> {
+ left: Au, right: Au) -> Unrooted<ClientRect> {
let rect = ClientRect::new_inherited(window.unrooted(), top, bottom, left, right);
reflect_dom_object(~rect, window, ClientRectBinding::Wrap)
}
diff --git a/src/components/script/dom/clientrectlist.rs b/src/components/script/dom/clientrectlist.rs
index abd87c47455..a9beec896e8 100644
--- a/src/components/script/dom/clientrectlist.rs
+++ b/src/components/script/dom/clientrectlist.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::ClientRectListBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::clientrect::ClientRect;
use dom::window::Window;
@@ -17,16 +17,16 @@ pub struct ClientRectList {
impl ClientRectList {
pub fn new_inherited(window: JS<Window>,
- rects: Vec<JS<ClientRect>>) -> ClientRectList {
+ rects: Vec<JSRef<ClientRect>>) -> ClientRectList {
ClientRectList {
reflector_: Reflector::new(),
- rects: rects,
+ rects: rects.iter().map(|rect| rect.unrooted()).collect(),
window: window,
}
}
pub fn new(window: &JSRef<Window>,
- rects: Vec<JS<ClientRect>>) -> JS<ClientRectList> {
+ rects: Vec<JSRef<ClientRect>>) -> Unrooted<ClientRectList> {
reflect_dom_object(~ClientRectList::new_inherited(window.unrooted(), rects),
window, ClientRectListBinding::Wrap)
}
@@ -35,15 +35,15 @@ impl ClientRectList {
self.rects.len() as u32
}
- pub fn Item(&self, index: u32) -> Option<JS<ClientRect>> {
+ pub fn Item(&self, index: u32) -> Option<Unrooted<ClientRect>> {
if index < self.rects.len() as u32 {
- Some(self.rects.get(index as uint).clone())
+ Some(Unrooted::new(self.rects.get(index as uint).clone()))
} else {
None
}
}
- pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<ClientRect>> {
+ pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<ClientRect>> {
*found = index < self.rects.len() as u32;
self.Item(index)
}
diff --git a/src/components/script/dom/comment.rs b/src/components/script/dom/comment.rs
index a0786441fe6..779fb6415e9 100644
--- a/src/components/script/dom/comment.rs
+++ b/src/components/script/dom/comment.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::CommentDerived;
use dom::bindings::codegen::BindingDeclarations::CommentBinding;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::Fallible;
use dom::characterdata::CharacterData;
use dom::document::Document;
@@ -35,12 +35,12 @@ impl Comment {
}
}
- pub fn new(text: DOMString, document: &JSRef<Document>) -> JS<Comment> {
+ pub fn new(text: DOMString, document: &JSRef<Document>) -> Unrooted<Comment> {
let node = Comment::new_inherited(text, document.unrooted());
Node::reflect_node(~node, document, CommentBinding::Wrap)
}
- pub fn Constructor(owner: &JSRef<Window>, data: DOMString) -> Fallible<JS<Comment>> {
+ pub fn Constructor(owner: &JSRef<Window>, data: DOMString) -> Fallible<Unrooted<Comment>> {
let roots = RootCollection::new();
let document = owner.get().Document();
let document = document.root(&roots);
diff --git a/src/components/script/dom/console.rs b/src/components/script/dom/console.rs
index a7908c6bc4f..ce41ed45212 100644
--- a/src/components/script/dom/console.rs
+++ b/src/components/script/dom/console.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::ConsoleBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
use servo_util::str::DOMString;
@@ -20,7 +20,7 @@ impl Console {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<Console> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<Console> {
reflect_dom_object(~Console::new_inherited(), window, ConsoleBinding::Wrap)
}
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index 44b141dcea5..e2984a1bf82 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -3,11 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::InheritTypes::{DocumentDerived, EventCast, HTMLElementCast};
-use dom::bindings::codegen::InheritTypes::{DocumentBase, NodeCast, DocumentCast};
use dom::bindings::codegen::InheritTypes::{HTMLHeadElementCast, TextCast, ElementCast};
-use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast};
+use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast, NodeCast};
use dom::bindings::codegen::BindingDeclarations::DocumentBinding;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, OptionalAssignable};
+use dom::bindings::js::OptionalRootable;
use dom::bindings::trace::Untraceable;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError};
@@ -22,14 +22,14 @@ use dom::element::{HTMLBodyElementTypeId, HTMLFrameSetElementTypeId};
use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::{HTMLCollection, CollectionFilter};
-use dom::nodelist::NodeList;
use dom::htmlelement::HTMLElement;
use dom::htmlheadelement::HTMLHeadElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmltitleelement::HTMLTitleElement;
use dom::mouseevent::MouseEvent;
-use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, INode};
-use dom::node::{CloneChildren, DoNotCloneChildren};
+use dom::node::{Node, ElementNodeTypeId, DocumentNodeTypeId, NodeHelpers, AppendChild};
+use dom::node::{CloneChildren, DoNotCloneChildren, RemoveChild, ReplaceChild};
+use dom::nodelist::NodeList;
use dom::text::Text;
use dom::processinginstruction::ProcessingInstruction;
use dom::uievent::UIEvent;
@@ -77,21 +77,19 @@ impl DocumentDerived for EventTarget {
}
impl Document {
- pub fn reflect_document<D: Reflectable+DocumentBase>
- (document: ~D,
- window: &JSRef<Window>,
- wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~D) -> JS<D>)
- -> JS<D> {
+ pub fn reflect_document(document: ~Document,
+ window: &JSRef<Window>,
+ wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~Document) -> JS<Document>)
+ -> Unrooted<Document> {
let roots = RootCollection::new();
assert!(document.reflector().get_jsobject().is_null());
- let raw_doc = reflect_dom_object(document, window, wrap_fn);
+ let mut raw_doc = reflect_dom_object(document, window, wrap_fn).root(&roots);
assert!(raw_doc.reflector().get_jsobject().is_not_null());
- let document = DocumentCast::from(&raw_doc);
- let document_root = document.root(&roots);
- let mut node: JS<Node> = NodeCast::from(&document);
- node.get_mut().set_owner_doc(&document_root.root_ref());
- raw_doc
+ let mut doc_alias = raw_doc.clone();
+ let node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut doc_alias);
+ node.get_mut().set_owner_doc(&*raw_doc);
+ Unrooted::new_rooted(&*raw_doc)
}
pub fn new_inherited(window: JS<Window>,
@@ -124,7 +122,7 @@ impl Document {
}
}
- pub fn new(window: &JSRef<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> JS<Document> {
+ pub fn new(window: &JSRef<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> Unrooted<Document> {
let document = Document::new_inherited(window.unrooted(), url, doctype, content_type);
Document::reflect_document(~document, window, DocumentBinding::Wrap)
}
@@ -138,7 +136,7 @@ impl Document {
impl Document {
// http://dom.spec.whatwg.org/#dom-document
- pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<Document>> {
+ pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Unrooted<Document>> {
Ok(Document::new(owner, None, NonHTMLDocument, None))
}
}
@@ -155,13 +153,13 @@ impl Reflectable for Document {
impl Document {
// http://dom.spec.whatwg.org/#dom-document-implementation
- pub fn Implementation(&mut self) -> JS<DOMImplementation> {
+ pub fn Implementation(&mut self) -> Unrooted<DOMImplementation> {
if self.implementation.is_none() {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- self.implementation = Some(DOMImplementation::new(&window.root_ref()));
+ self.implementation.assign(Some(DOMImplementation::new(&*window)));
}
- self.implementation.get_ref().clone()
+ Unrooted::new(self.implementation.get_ref().clone())
}
// http://dom.spec.whatwg.org/#dom-document-url
@@ -205,25 +203,29 @@ impl Document {
}
// http://dom.spec.whatwg.org/#dom-document-doctype
- pub fn GetDoctype(&self) -> Option<JS<DocumentType>> {
- self.node.children().find(|child| child.is_doctype())
- .map(|node| DocumentTypeCast::to(&node).unwrap())
+ pub fn GetDoctype(&self) -> Option<Unrooted<DocumentType>> {
+ self.node.children().find(|child| {
+ child.is_doctype()
+ }).map(|node| {
+ let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap();
+ Unrooted::new(doctype.unrooted())
+ })
}
// http://dom.spec.whatwg.org/#dom-document-documentelement
- pub fn GetDocumentElement(&self) -> Option<JS<Element>> {
- self.node.child_elements().next()
+ pub fn GetDocumentElement(&self) -> Option<Unrooted<Element>> {
+ self.node.child_elements().next().map(|elem| Unrooted::new_rooted(&elem))
}
// http://dom.spec.whatwg.org/#dom-document-getelementsbytagname
- pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Document>, tag_name: DOMString) -> JS<HTMLCollection> {
+ pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Document>, tag_name: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- HTMLCollection::by_tag_name(&window.root_ref(), NodeCast::from_ref(abstract_self), tag_name)
+ HTMLCollection::by_tag_name(&*window, NodeCast::from_ref(abstract_self), tag_name)
}
// http://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens
- pub fn GetElementsByTagNameNS(&self, abstract_self: &JSRef<Document>, maybe_ns: Option<DOMString>, tag_name: DOMString) -> JS<HTMLCollection> {
+ pub fn GetElementsByTagNameNS(&self, abstract_self: &JSRef<Document>, maybe_ns: Option<DOMString>, tag_name: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -231,28 +233,28 @@ impl Document {
Some(namespace) => Namespace::from_str(namespace),
None => Null
};
- HTMLCollection::by_tag_name_ns(&window.root_ref(), NodeCast::from_ref(abstract_self), tag_name, namespace)
+ HTMLCollection::by_tag_name_ns(&*window, NodeCast::from_ref(abstract_self), tag_name, namespace)
}
// http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname
- pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Document>, classes: DOMString) -> JS<HTMLCollection> {
+ pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Document>, classes: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- HTMLCollection::by_class_name(&window.root_ref(), NodeCast::from_ref(abstract_self), classes)
+ HTMLCollection::by_class_name(&*window, NodeCast::from_ref(abstract_self), classes)
}
// http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
- pub fn GetElementById(&self, id: DOMString) -> Option<JS<Element>> {
+ pub fn GetElementById(&self, id: DOMString) -> Option<Unrooted<Element>> {
match self.idmap.find_equiv(&id) {
None => None,
- Some(ref elements) => Some(elements.get(0).clone()),
+ Some(ref elements) => Some(Unrooted::new(elements.get(0).clone())),
}
}
// http://dom.spec.whatwg.org/#dom-document-createelement
pub fn CreateElement(&self, abstract_self: &JSRef<Document>, local_name: DOMString)
- -> Fallible<JS<Element>> {
+ -> Fallible<Unrooted<Element>> {
if xml_name_type(local_name) == InvalidXMLName {
debug!("Not a valid element name");
return Err(InvalidCharacter);
@@ -264,7 +266,7 @@ impl Document {
// http://dom.spec.whatwg.org/#dom-document-createelementns
pub fn CreateElementNS(&self, abstract_self: &JSRef<Document>,
namespace: Option<DOMString>,
- qualified_name: DOMString) -> Fallible<JS<Element>> {
+ qualified_name: DOMString) -> Fallible<Unrooted<Element>> {
let ns = Namespace::from_str(null_str_as_empty_ref(&namespace));
match xml_name_type(qualified_name) {
InvalidXMLName => {
@@ -308,24 +310,24 @@ impl Document {
}
// http://dom.spec.whatwg.org/#dom-document-createdocumentfragment
- pub fn CreateDocumentFragment(&self, abstract_self: &JSRef<Document>) -> JS<DocumentFragment> {
+ pub fn CreateDocumentFragment(&self, abstract_self: &JSRef<Document>) -> Unrooted<DocumentFragment> {
DocumentFragment::new(abstract_self)
}
// http://dom.spec.whatwg.org/#dom-document-createtextnode
pub fn CreateTextNode(&self, abstract_self: &JSRef<Document>, data: DOMString)
- -> JS<Text> {
+ -> Unrooted<Text> {
Text::new(data, abstract_self)
}
// http://dom.spec.whatwg.org/#dom-document-createcomment
- pub fn CreateComment(&self, abstract_self: &JSRef<Document>, data: DOMString) -> JS<Comment> {
+ pub fn CreateComment(&self, abstract_self: &JSRef<Document>, data: DOMString) -> Unrooted<Comment> {
Comment::new(data, abstract_self)
}
// http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
pub fn CreateProcessingInstruction(&self, abstract_self: &JSRef<Document>, target: DOMString,
- data: DOMString) -> Fallible<JS<ProcessingInstruction>> {
+ data: DOMString) -> Fallible<Unrooted<ProcessingInstruction>> {
// Step 1.
if xml_name_type(target) == InvalidXMLName {
return Err(InvalidCharacter);
@@ -341,9 +343,9 @@ impl Document {
}
// http://dom.spec.whatwg.org/#dom-document-importnode
- pub fn ImportNode(&self, abstract_self: &JSRef<Document>, node: &JSRef<Node>, deep: bool) -> Fallible<JS<Node>> {
+ pub fn ImportNode(&self, abstract_self: &JSRef<Document>, node: &JSRef<Node>, deep: bool) -> Fallible<Unrooted<Node>> {
// Step 1.
- if node.unrooted().is_document() {
+ if node.is_document() {
return Err(NotSupported);
}
@@ -357,30 +359,29 @@ impl Document {
}
// http://dom.spec.whatwg.org/#dom-document-adoptnode
- pub fn AdoptNode(&self, abstract_self: &JSRef<Document>, node: &JSRef<Node>) -> Fallible<JS<Node>> {
+ pub fn AdoptNode(&self, abstract_self: &JSRef<Document>, node: &mut JSRef<Node>) -> Fallible<Unrooted<Node>> {
// Step 1.
- if node.unrooted().is_document() {
+ if node.is_document() {
return Err(NotSupported);
}
// Step 2.
- let mut adoptee = node.clone();
- Node::adopt(&mut adoptee, abstract_self);
+ Node::adopt(node, abstract_self);
// Step 3.
- Ok(adoptee.unrooted())
+ Ok(Unrooted::new_rooted(node))
}
// http://dom.spec.whatwg.org/#dom-document-createevent
- pub fn CreateEvent(&self, interface: DOMString) -> Fallible<JS<Event>> {
+ pub fn CreateEvent(&self, interface: DOMString) -> Fallible<Unrooted<Event>> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
match interface.to_ascii_lower().as_slice() {
// FIXME: Implement CustomEvent (http://dom.spec.whatwg.org/#customevent)
- "uievents" | "uievent" => Ok(EventCast::from(&UIEvent::new(&window.root_ref()))),
- "mouseevents" | "mouseevent" => Ok(EventCast::from(&MouseEvent::new(&window.root_ref()))),
- "htmlevents" | "events" | "event" => Ok(Event::new(&window.root_ref())),
+ "uievents" | "uievent" => Ok(EventCast::from_unrooted(UIEvent::new(&*window))),
+ "mouseevents" | "mouseevent" => Ok(EventCast::from_unrooted(MouseEvent::new(&*window))),
+ "htmlevents" | "events" | "event" => Ok(Event::new(&*window)),
_ => Err(NotSupported)
}
}
@@ -388,14 +389,15 @@ impl Document {
// http://www.whatwg.org/specs/web-apps/current-work/#document.title
pub fn Title(&self, _: &JSRef<Document>) -> DOMString {
let mut title = ~"";
- self.GetDocumentElement().map(|root| {
- let root: JS<Node> = NodeCast::from(&root);
- root.traverse_preorder()
+ let roots = RootCollection::new();
+ self.GetDocumentElement().root(&roots).map(|root| {
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
+ root.traverse_preorder(&roots)
.find(|node| node.type_id() == ElementNodeTypeId(HTMLTitleElementTypeId))
.map(|title_elem| {
- for child in title_elem.children() {
+ for child in title_elem.deref().children() {
if child.is_text() {
- let text: JS<Text> = TextCast::to(&child).unwrap();
+ let text: &JSRef<Text> = TextCast::to_ref(&child).unwrap();
title.push_str(text.get().characterdata.data.as_slice());
}
}
@@ -410,9 +412,9 @@ impl Document {
pub fn SetTitle(&self, abstract_self: &JSRef<Document>, title: DOMString) -> ErrorResult {
let roots = RootCollection::new();
- self.GetDocumentElement().map(|root| {
- let root: JS<Node> = NodeCast::from(&root);
- let mut head_node = root.traverse_preorder().find(|child| {
+ self.GetDocumentElement().root(&roots).map(|root| {
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
+ let mut head_node = root.traverse_preorder(&roots).find(|child| {
child.get().type_id == ElementNodeTypeId(HTMLHeadElementTypeId)
});
head_node.as_mut().map(|head| {
@@ -422,25 +424,21 @@ impl Document {
match title_node {
Some(ref mut title_node) => {
- for title_child in title_node.children() {
- let title_child = title_child.root(&roots);
- assert!(title_node.RemoveChild(&mut title_child.root_ref()).is_ok());
+ for mut title_child in title_node.children() {
+ assert!(RemoveChild(&mut *title_node, &mut title_child).is_ok());
}
- let new_text = self.CreateTextNode(abstract_self, title.clone());
- let new_text = new_text.root(&roots);
+ let mut new_text = self.CreateTextNode(abstract_self, title.clone()).root(&roots);
- assert!(title_node.AppendChild(NodeCast::from_mut_ref(&mut new_text.root_ref())).is_ok());
+ assert!(AppendChild(&mut *title_node, NodeCast::from_mut_ref(&mut *new_text)).is_ok());
},
None => {
- let mut new_title: JS<Node> =
- NodeCast::from(&HTMLTitleElement::new(~"title", abstract_self));
- let new_title_root = new_title.root(&roots);
+ let mut new_title = HTMLTitleElement::new(~"title", abstract_self).root(&roots);
+ let new_title: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *new_title);
- let new_text = self.CreateTextNode(abstract_self, title.clone());
- let new_text = new_text.root(&roots);
+ let mut new_text = self.CreateTextNode(abstract_self, title.clone()).root(&roots);
- assert!(new_title.AppendChild(NodeCast::from_mut_ref(&mut new_text.root_ref())).is_ok());
- assert!(head.AppendChild(&mut new_title_root.root_ref()).is_ok());
+ assert!(AppendChild(&mut *new_title, NodeCast::from_mut_ref(&mut *new_text)).is_ok());
+ assert!(AppendChild(&mut *head, &mut *new_title).is_ok());
},
}
});
@@ -448,33 +446,44 @@ impl Document {
Ok(())
}
- fn get_html_element(&self) -> Option<JS<HTMLHtmlElement>> {
- self.GetDocumentElement().filtered(|root| {
- root.get().node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId)
- }).map(|elem| HTMLHtmlElementCast::to(&elem).unwrap())
+ fn get_html_element(&self) -> Option<Unrooted<HTMLHtmlElement>> {
+ let roots = RootCollection::new();
+ self.GetDocumentElement().root(&roots).filtered(|root| {
+ root.node.type_id == ElementNodeTypeId(HTMLHtmlElementTypeId)
+ }).map(|elem| {
+ Unrooted::new_rooted(HTMLHtmlElementCast::to_ref(&*elem).unwrap())
+ })
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-head
- pub fn GetHead(&self) -> Option<JS<HTMLHeadElement>> {
+ pub fn GetHead(&self) -> Option<Unrooted<HTMLHeadElement>> {
+ let roots = RootCollection::new();
self.get_html_element().and_then(|root| {
- let node: JS<Node> = NodeCast::from(&root);
+ let root = root.root(&roots);
+ let node: &JSRef<Node> = NodeCast::from_ref(&*root);
node.children().find(|child| {
child.type_id() == ElementNodeTypeId(HTMLHeadElementTypeId)
- }).map(|node| HTMLHeadElementCast::to(&node).unwrap())
+ }).map(|node| {
+ Unrooted::new_rooted(HTMLHeadElementCast::to_ref(&node).unwrap())
+ })
})
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body
- pub fn GetBody(&self, _: &JSRef<Document>) -> Option<JS<HTMLElement>> {
+ pub fn GetBody(&self, _: &JSRef<Document>) -> Option<Unrooted<HTMLElement>> {
+ let roots = RootCollection::new();
self.get_html_element().and_then(|root| {
- let node: JS<Node> = NodeCast::from(&root);
+ let root = root.root(&roots);
+ let node: &JSRef<Node> = NodeCast::from_ref(&*root);
node.children().find(|child| {
match child.type_id() {
ElementNodeTypeId(HTMLBodyElementTypeId) |
ElementNodeTypeId(HTMLFrameSetElementTypeId) => true,
_ => false
}
- }).map(|node| HTMLElementCast::to(&node).unwrap())
+ }).map(|node| {
+ Unrooted::new_rooted(HTMLElementCast::to_ref(&node).unwrap())
+ })
})
}
@@ -494,28 +503,28 @@ impl Document {
}
// Step 2.
- let old_body: Option<JS<HTMLElement>> = self.GetBody(abstract_self);
- if old_body == new_body.as_ref().map(|new_body| new_body.unrooted()) {
+ let mut old_body = self.GetBody(abstract_self).root(&roots);
+ //FIXME: covariant lifetime workaround. do not judge.
+ if old_body.as_ref().map(|body| body.deref()) == new_body.as_ref().map(|a| &*a) {
return Ok(());
}
// Step 3.
- match self.get_html_element() {
+ match self.get_html_element().root(&roots) {
// Step 4.
None => return Err(HierarchyRequest),
- Some(root) => {
+ Some(ref mut root) => {
let mut new_body_unwrapped = new_body.unwrap();
let new_body: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut new_body_unwrapped);
- let mut root: JS<Node> = NodeCast::from(&root);
+ let root: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut **root);
match old_body {
- Some(child) => {
- let child: JS<Node> = NodeCast::from(&child);
- let child = child.root(&roots);
+ Some(ref mut child) => {
+ let child: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut **child);
- assert!(root.ReplaceChild(new_body, &mut child.root_ref()).is_ok())
+ assert!(ReplaceChild(&mut *root, new_body, child).is_ok())
}
- None => assert!(root.AppendChild(new_body).is_ok())
+ None => assert!(AppendChild(&mut *root, new_body).is_ok())
};
}
}
@@ -523,20 +532,22 @@ impl Document {
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname
- pub fn GetElementsByName(&self, name: DOMString) -> JS<NodeList> {
+ pub fn GetElementsByName(&self, name: DOMString) -> Unrooted<NodeList> {
+ let roots = RootCollection::new();
+
self.createNodeList(|node| {
if !node.get().is_element() {
return false;
}
- let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
- element.get_attribute(Null, "name").map_or(false, |attr| {
- attr.get().value_ref() == name
+ let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
+ element.get_attribute(Null, "name").root(&roots).map_or(false, |mut attr| {
+ attr.value_ref() == name
})
})
}
- pub fn Images(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Images(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -548,10 +559,10 @@ impl Document {
}
}
let filter = ~ImagesFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Embeds(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Embeds(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -563,15 +574,15 @@ impl Document {
}
}
let filter = ~EmbedsFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Plugins(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Plugins(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
// FIXME: https://github.com/mozilla/servo/issues/1847
self.Embeds(abstract_self)
}
- pub fn Links(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Links(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -580,14 +591,14 @@ impl Document {
impl CollectionFilter for LinksFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
(elem.get().local_name == ~"a" || elem.get().local_name == ~"area") &&
- elem.unrooted().get_attribute(Null, "href").is_some()
+ elem.get_attribute(Null, "href").is_some()
}
}
let filter = ~LinksFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Forms(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Forms(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -599,10 +610,10 @@ impl Document {
}
}
let filter = ~FormsFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Scripts(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Scripts(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -614,10 +625,10 @@ impl Document {
}
}
let filter = ~ScriptsFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Anchors(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Anchors(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -625,14 +636,14 @@ impl Document {
struct AnchorsFilter;
impl CollectionFilter for AnchorsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
- elem.get().local_name == ~"a" && elem.unrooted().get_attribute(Null, "name").is_some()
+ elem.get().local_name == ~"a" && elem.get_attribute(Null, "name").is_some()
}
}
let filter = ~AnchorsFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Applets(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Applets(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
@@ -644,40 +655,39 @@ impl Document {
}
}
let filter = ~AppletsFilter;
- HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter)
+ HTMLCollection::create(&*window, NodeCast::from_ref(abstract_self), filter)
}
- pub fn Location(&mut self, _abstract_self: &JSRef<Document>) -> JS<Location> {
+ 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.root_ref())
+ self.window.get_mut().Location(&*window)
}
- pub fn Children(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> {
+ pub fn Children(&self, abstract_self: &JSRef<Document>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(abstract_self))
+ HTMLCollection::children(&*window, NodeCast::from_ref(abstract_self))
}
- pub fn createNodeList(&self, callback: |node: &JSRef<Node>| -> bool) -> JS<NodeList> {
+ pub fn createNodeList(&self, callback: |node: &JSRef<Node>| -> bool) -> Unrooted<NodeList> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
let mut nodes = vec!();
- match self.GetDocumentElement() {
+ match self.GetDocumentElement().root(&roots) {
None => {},
Some(root) => {
- let root: JS<Node> = NodeCast::from(&root);
- for child in root.traverse_preorder() {
- let child = child.root(&roots);
- if callback(&child.root_ref()) {
- nodes.push(child.root_ref().unrooted());
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
+ for child in root.traverse_preorder(&roots) {
+ if callback(&child) {
+ nodes.push(child);
}
}
}
}
- NodeList::new_simple_list(&window.root_ref(), nodes)
+ NodeList::new_simple_list(&*window, nodes)
}
pub fn content_changed(&self) {
@@ -697,12 +707,14 @@ impl Document {
pub fn unregister_named_element(&mut self,
abstract_self: &JSRef<Element>,
id: DOMString) {
+ let roots = RootCollection::new();
let mut is_empty = false;
match self.idmap.find_mut(&id) {
None => {},
Some(elements) => {
let position = elements.iter()
- .position(|element| element == &abstract_self.unrooted())
+ .map(|elem| elem.root(&roots))
+ .position(|element| &*element == abstract_self)
.expect("This element should be in registered.");
elements.remove(position);
is_empty = elements.is_empty();
@@ -717,26 +729,28 @@ impl Document {
pub fn register_named_element(&mut self,
element: &JSRef<Element>,
id: DOMString) {
+ let roots = RootCollection::new();
assert!({
- let node: JS<Node> = NodeCast::from(&element.unrooted());
+ let node: &JSRef<Node> = NodeCast::from_ref(element);
node.is_in_doc()
});
// FIXME https://github.com/mozilla/rust/issues/13195
// Use mangle() when it exists again.
- let root = self.GetDocumentElement().expect("The element is in the document, so there must be a document element.");
+ let root = self.GetDocumentElement().expect("The element is in the document, so there must be a document element.").root(&roots);
match self.idmap.find_mut(&id) {
Some(elements) => {
- let new_node = NodeCast::from_ref(element);
+ let new_node: &JSRef<Node> = NodeCast::from_ref(element);
let mut head : uint = 0u;
- let root: JS<Node> = NodeCast::from(&root);
- for node in root.traverse_preorder() {
- match ElementCast::to(&node) {
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
+ for node in root.traverse_preorder(&roots) {
+ let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node);
+ match elem {
Some(elem) => {
- if elements.get(head) == &elem {
+ if elements.get(head) == &elem.unrooted() {
head = head + 1;
}
- if new_node.unrooted() == node || head == elements.len() {
+ if new_node == &node || head == elements.len() {
break;
}
}
diff --git a/src/components/script/dom/documentfragment.rs b/src/components/script/dom/documentfragment.rs
index e10e9e1204c..629b68ffdec 100644
--- a/src/components/script/dom/documentfragment.rs
+++ b/src/components/script/dom/documentfragment.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::{DocumentFragmentDerived, NodeCast};
use dom::bindings::codegen::BindingDeclarations::DocumentFragmentBinding;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::Fallible;
use dom::document::Document;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -34,14 +34,14 @@ impl DocumentFragment {
}
}
- pub fn new(document: &JSRef<Document>) -> JS<DocumentFragment> {
+ pub fn new(document: &JSRef<Document>) -> Unrooted<DocumentFragment> {
let node = DocumentFragment::new_inherited(document.unrooted());
Node::reflect_node(~node, document, DocumentFragmentBinding::Wrap)
}
}
impl DocumentFragment {
- pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<DocumentFragment>> {
+ pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Unrooted<DocumentFragment>> {
let roots = RootCollection::new();
let document = owner.get().Document();
let document = document.root(&roots);
@@ -51,9 +51,9 @@ impl DocumentFragment {
}
impl DocumentFragment {
- pub fn Children(&self, abstract_self: &JSRef<DocumentFragment>) -> JS<HTMLCollection> {
+ pub fn Children(&self, abstract_self: &JSRef<DocumentFragment>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
- let window = window_from_node(&abstract_self.unrooted()).root(&roots);
+ let window = window_from_node(abstract_self).root(&roots);
HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(abstract_self))
}
}
diff --git a/src/components/script/dom/documenttype.rs b/src/components/script/dom/documenttype.rs
index dacce041f5c..21b1a784456 100644
--- a/src/components/script/dom/documenttype.rs
+++ b/src/components/script/dom/documenttype.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::DocumentTypeDerived;
use dom::bindings::codegen::BindingDeclarations::DocumentTypeBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::node::{Node, DoctypeNodeTypeId};
@@ -46,7 +46,7 @@ impl DocumentType {
public_id: Option<DOMString>,
system_id: Option<DOMString>,
document: &JSRef<Document>)
- -> JS<DocumentType> {
+ -> Unrooted<DocumentType> {
let documenttype = DocumentType::new_inherited(name,
public_id,
system_id,
diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs
index db562d08c71..08a8c364deb 100644
--- a/src/components/script/dom/domexception.rs
+++ b/src/components/script/dom/domexception.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding;
use dom::bindings::codegen::BindingDeclarations::DOMExceptionBinding::DOMExceptionConstants;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
use servo_util::str::DOMString;
@@ -49,7 +49,7 @@ impl DOMException {
}
}
- pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> JS<DOMException> {
+ pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> Unrooted<DOMException> {
reflect_dom_object(~DOMException::new_inherited(code), window, DOMExceptionBinding::Wrap)
}
}
diff --git a/src/components/script/dom/domimplementation.rs b/src/components/script/dom/domimplementation.rs
index e002cf9d28c..7cc9e5ef0d0 100644
--- a/src/components/script/dom/domimplementation.rs
+++ b/src/components/script/dom/domimplementation.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::DOMImplementationBinding;
use dom::bindings::codegen::InheritTypes::NodeCast;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, OptionalRootable};
use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
use dom::bindings::error::{Fallible, InvalidCharacter, NamespaceError};
use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
@@ -14,7 +14,7 @@ use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlheadelement::HTMLHeadElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmltitleelement::HTMLTitleElement;
-use dom::node::{Node, INode};
+use dom::node::{Node, AppendChild};
use dom::text::Text;
use dom::window::Window;
use servo_util::str::DOMString;
@@ -33,7 +33,7 @@ impl DOMImplementation {
}
}
- pub fn new(owner: &JSRef<Window>) -> JS<DOMImplementation> {
+ pub fn new(owner: &JSRef<Window>) -> Unrooted<DOMImplementation> {
reflect_dom_object(~DOMImplementation::new_inherited(owner.unrooted()), owner,
DOMImplementationBinding::Wrap)
}
@@ -52,7 +52,7 @@ impl Reflectable for DOMImplementation {
// http://dom.spec.whatwg.org/#domimplementation
impl DOMImplementation {
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
- pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<JS<DocumentType>> {
+ pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<Unrooted<DocumentType>> {
let roots = RootCollection::new();
match xml_name_type(qname) {
// Step 1.
@@ -70,37 +70,39 @@ impl DOMImplementation {
// http://dom.spec.whatwg.org/#dom-domimplementation-createdocument
pub fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString,
- mut maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<JS<Document>> {
+ mut maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<Unrooted<Document>> {
let roots = RootCollection::new();
let win = self.owner.root(&roots);
// Step 1.
- let doc = Document::new(&win.root_ref(), None, NonHTMLDocument, None);
- let doc_root = doc.root(&roots);
- let mut doc_node: JS<Node> = NodeCast::from(&doc);
-
+ let mut doc = Document::new(&win.root_ref(), None, NonHTMLDocument, None).root(&roots);
// Step 2-3.
let mut maybe_elem = if qname.is_empty() {
None
} else {
- match doc.get().CreateElementNS(&doc_root.root_ref(), namespace, qname) {
+ match doc.get().CreateElementNS(&*doc, namespace, qname) {
Err(error) => return Err(error),
Ok(elem) => Some(elem)
}
};
- // Step 4.
- match maybe_doctype {
- None => (),
- Some(ref mut doctype) => assert!(doc_node.AppendChild(NodeCast::from_mut_ref(doctype)).is_ok())
- }
+ {
+ let doc_node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut *doc);
+
+ // Step 4.
+ match maybe_doctype {
+ None => (),
+ Some(ref mut doctype) => {
+ assert!(AppendChild(doc_node, NodeCast::from_mut_ref(doctype)).is_ok())
+ }
+ }
- // Step 5.
- match maybe_elem {
- None => (),
- Some(ref elem) => {
- let elem = elem.root(&roots);
- assert!(doc_node.AppendChild(NodeCast::from_mut_ref(&mut elem.root_ref())).is_ok())
+ // Step 5.
+ match maybe_elem.root(&roots) {
+ None => (),
+ Some(mut elem) => {
+ assert!(AppendChild(doc_node, NodeCast::from_mut_ref(&mut *elem)).is_ok())
+ }
}
}
@@ -108,65 +110,59 @@ impl DOMImplementation {
// FIXME: https://github.com/mozilla/servo/issues/1522
// Step 7.
- Ok(doc)
+ Ok(Unrooted::new_rooted(&*doc))
}
// http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
- pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> JS<Document> {
+ pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> Unrooted<Document> {
let roots = RootCollection::new();
let owner = self.owner.root(&roots);
// Step 1-2.
- let doc = Document::new(&owner.root_ref(), None, HTMLDocument, None);
- let doc_root = doc.root(&roots);
- let mut doc_node: JS<Node> = NodeCast::from(&doc);
+ let mut doc = Document::new(&owner.root_ref(), None, HTMLDocument, None).root(&roots);
+ let mut doc_alias = doc.clone();
+ let doc_node: &mut JSRef<Node> = NodeCast::from_mut_ref(&mut doc_alias);
{
// Step 3.
- let doc_type = DocumentType::new(~"html", None, None, &doc_root.root_ref());
- let doc_type = doc_type.root(&roots);
- assert!(doc_node.AppendChild(NodeCast::from_mut_ref(&mut doc_type.root_ref())).is_ok());
+ let mut doc_type = DocumentType::new(~"html", None, None, &*doc).root(&roots);
+ assert!(AppendChild(&mut *doc_node, NodeCast::from_mut_ref(&mut *doc_type)).is_ok());
}
{
// Step 4.
- let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc_root.root_ref()));
- let doc_html_root = {doc_html.root(&roots)};
- assert!(doc_node.AppendChild(&mut doc_html_root.root_ref()).is_ok());
+ let mut doc_html = NodeCast::from_unrooted(HTMLHtmlElement::new(~"html", &*doc)).root(&roots);
+ assert!(AppendChild(&mut *doc_node, &mut *doc_html).is_ok());
{
// Step 5.
- let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc_root.root_ref()));
- let doc_head_root = doc_head.root(&roots);
- assert!(doc_html.AppendChild(&mut doc_head_root.root_ref()).is_ok());
+ let mut doc_head = NodeCast::from_unrooted(HTMLHeadElement::new(~"head", &*doc)).root(&roots);
+ assert!(AppendChild(&mut *doc_html, &mut *doc_head).is_ok());
// Step 6.
match title {
None => (),
Some(title_str) => {
// Step 6.1.
- let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc_root.root_ref()));
- let doc_title_root = doc_title.root(&roots);
- assert!(doc_head.AppendChild(&mut doc_title_root.root_ref()).is_ok());
+ let mut doc_title = NodeCast::from_unrooted(HTMLTitleElement::new(~"title", &*doc)).root(&roots);
+ assert!(AppendChild(&mut *doc_head, &mut *doc_title).is_ok());
// Step 6.2.
- let title_text = Text::new(title_str, &doc_root.root_ref());
- let title_text = title_text.root(&roots);
- assert!(doc_title.AppendChild(NodeCast::from_mut_ref(&mut title_text.root_ref())).is_ok());
+ let mut title_text = Text::new(title_str, &*doc).root(&roots);
+ assert!(AppendChild(&mut *doc_title, NodeCast::from_mut_ref(&mut *title_text)).is_ok());
}
}
}
// Step 7.
- let doc_body = HTMLBodyElement::new(~"body", &doc_root.root_ref());
- let doc_body = doc_body.root(&roots);
- assert!(doc_html.AppendChild(NodeCast::from_mut_ref(&mut doc_body.root_ref())).is_ok());
+ let mut doc_body = HTMLBodyElement::new(~"body", &*doc).root(&roots);
+ assert!(AppendChild(&mut *doc_html, NodeCast::from_mut_ref(&mut *doc_body)).is_ok());
}
// Step 8.
// FIXME: https://github.com/mozilla/servo/issues/1522
// Step 9.
- doc
+ Unrooted::new_rooted(&*doc)
}
}
diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs
index d11c7270057..6d77273e11e 100644
--- a/src/components/script/dom/domparser.rs
+++ b/src/components/script/dom/domparser.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::DOMParserBinding;
use dom::bindings::codegen::BindingDeclarations::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
use dom::bindings::error::{Fallible, FailureUnknown};
use dom::document::{Document, HTMLDocument, NonHTMLDocument};
@@ -25,19 +25,19 @@ impl DOMParser {
}
}
- pub fn new(owner: &JSRef<Window>) -> JS<DOMParser> {
+ pub fn new(owner: &JSRef<Window>) -> Unrooted<DOMParser> {
reflect_dom_object(~DOMParser::new_inherited(owner.unrooted()), owner,
DOMParserBinding::Wrap)
}
- pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<DOMParser>> {
+ pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Unrooted<DOMParser>> {
Ok(DOMParser::new(owner))
}
pub fn ParseFromString(&self,
_s: DOMString,
ty: DOMParserBinding::SupportedType)
- -> Fallible<JS<Document>> {
+ -> Fallible<Unrooted<Document>> {
let roots = RootCollection::new();
let owner = self.owner.root(&roots);
match ty {
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index 179f2c7571d..e0901de01d8 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -4,11 +4,12 @@
//! Element nodes.
-use dom::attr::{Attr, AttrSettingType, ReplacedAttr, FirstSetAttr};
+use dom::attr::{Attr, ReplacedAttr, FirstSetAttr};
use dom::attrlist::AttrList;
use dom::bindings::codegen::BindingDeclarations::ElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, UnrootedPushable};
+use dom::bindings::js::{OptionalAssignable, OptionalRootable, Root};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::bindings::error::{ErrorResult, Fallible, NamespaceError, InvalidCharacter};
use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
@@ -152,14 +153,15 @@ impl Element {
}
}
- pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JSRef<Document>) -> JS<Element> {
+ pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JSRef<Document>) -> Unrooted<Element> {
let element = Element::new_inherited(ElementTypeId, local_name, namespace, prefix, document.unrooted());
Node::reflect_node(~element, document, ElementBinding::Wrap)
}
pub fn html_element_in_html_document(&self) -> bool {
+ let roots = RootCollection::new();
self.namespace == namespace::HTML &&
- self.node.owner_doc().get().is_html_document
+ self.node.owner_doc().root(&roots).is_html_document
}
}
@@ -168,7 +170,7 @@ impl Element {
if self.namespace != namespace::HTML {
return false
}
- let owner_doc: *JS<Document> = self.node.owner_doc();
+ let owner_doc: *JS<Document> = self.node.owner_doc_for_layout();
let owner_doc: **Document = owner_doc as **Document;
(**owner_doc).is_html_document
}
@@ -189,15 +191,15 @@ impl Element {
}
pub trait AttributeHandlers {
- fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>>;
+ fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Unrooted<Attr>>;
fn set_attr(&mut self, name: DOMString, value: DOMString) -> ErrorResult;
fn set_attribute(&mut self, namespace: Namespace, name: DOMString,
value: DOMString) -> ErrorResult;
fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
- prefix: Option<DOMString>, cb: |&JS<Attr>| -> bool);
- fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult;
- fn SetAttributeNS(&mut self, namespace_url: Option<DOMString>,
+ prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool);
+ fn SetAttribute_(&mut self, name: DOMString, value: DOMString) -> ErrorResult;
+ fn SetAttributeNS_(&mut self, namespace_url: Option<DOMString>,
name: DOMString, value: DOMString) -> ErrorResult;
fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult;
@@ -212,18 +214,18 @@ pub trait AttributeHandlers {
fn set_uint_attribute(&mut self, name: &str, value: u32);
}
-impl AttributeHandlers for JS<Element> {
- fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<JS<Attr>> {
+impl<'a> AttributeHandlers for JSRef<'a, Element> {
+ fn get_attribute(&self, namespace: Namespace, name: &str) -> Option<Unrooted<Attr>> {
if self.get().html_element_in_html_document() {
self.get().attrs.iter().find(|attr| {
let attr = attr.get();
name.to_ascii_lower() == attr.local_name && attr.namespace == namespace
- }).map(|x| x.clone())
+ }).map(|x| Unrooted::new(x.clone()))
} else {
self.get().attrs.iter().find(|attr| {
let attr = attr.get();
name == attr.local_name && attr.namespace == namespace
- }).map(|x| x.clone())
+ }).map(|x| Unrooted::new(x.clone()))
}
}
@@ -245,10 +247,11 @@ impl AttributeHandlers for JS<Element> {
None => {}
}
- let node: JS<Node> = NodeCast::from(self);
- node.get().wait_until_safe_to_modify_dom();
+ let self_alias = self.clone();
+ let node: &JSRef<Node> = NodeCast::from_ref(&self_alias);
+ node.wait_until_safe_to_modify_dom();
- let position: |&JS<Attr>| -> bool =
+ let position: |&JSRef<Attr>| -> bool =
if self.get().html_element_in_html_document() {
|attr| attr.get().local_name.eq_ignore_ascii_case(local_name)
} else {
@@ -260,33 +263,31 @@ impl AttributeHandlers for JS<Element> {
fn do_set_attribute(&mut self, local_name: DOMString, value: DOMString,
name: DOMString, namespace: Namespace,
- prefix: Option<DOMString>, cb: |&JS<Attr>| -> bool) {
+ prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) {
let roots = RootCollection::new();
- let node: JS<Node> = NodeCast::from(self);
- let idx = self.get().attrs.iter().position(cb);
- let (mut attr, set_type): (JS<Attr>, AttrSettingType) = match idx {
- Some(idx) => {
- let attr = self.get_mut().attrs.get(idx).clone();
- (attr, ReplacedAttr)
- }
-
+ let idx = self.get().attrs.iter()
+ .map(|attr| attr.root(&roots))
+ .position(|attr| cb(&*attr));
+ let (idx, set_type) = match idx {
+ Some(idx) => (idx, ReplacedAttr),
None => {
- let doc = node.get().owner_doc().get();
- let window = doc.window.root(&roots);
- let attr = Attr::new(&window.root_ref(), local_name.clone(), value.clone(),
- name, namespace.clone(), prefix, self.clone());
- self.get_mut().attrs.push(attr.clone());
- (attr, FirstSetAttr)
+ let window = window_from_node(self).root(&roots);
+ let attr = Attr::new(&*window, local_name.clone(), value.clone(),
+ name, namespace.clone(), prefix, self);
+ self.get_mut().attrs.push_unrooted(attr);
+ (self.get().attrs.len() - 1, FirstSetAttr)
}
};
- attr.get_mut().set_value(set_type, value);
+ self.get_mut().attrs.get_mut(idx).get_mut().set_value(set_type, value);
}
// http://dom.spec.whatwg.org/#dom-element-setattribute
- fn SetAttribute(&mut self, name: DOMString, value: DOMString) -> ErrorResult {
- let node: JS<Node> = NodeCast::from(self);
- node.get().wait_until_safe_to_modify_dom();
+ fn SetAttribute_(&mut self, name: DOMString, value: DOMString) -> ErrorResult {
+ {
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ node.get().wait_until_safe_to_modify_dom();
+ }
// Step 1.
match xml_name_type(name) {
@@ -308,10 +309,12 @@ impl AttributeHandlers for JS<Element> {
Ok(())
}
- fn SetAttributeNS(&mut self, namespace_url: Option<DOMString>,
- name: DOMString, value: DOMString) -> ErrorResult {
- let node: JS<Node> = NodeCast::from(self);
- node.get().wait_until_safe_to_modify_dom();
+ fn SetAttributeNS_(&mut self, namespace_url: Option<DOMString>,
+ name: DOMString, value: DOMString) -> ErrorResult {
+ {
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ node.get().wait_until_safe_to_modify_dom();
+ }
// Step 1.
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace_url));
@@ -368,8 +371,9 @@ impl AttributeHandlers for JS<Element> {
fn remove_attribute(&mut self, namespace: Namespace, name: DOMString) -> ErrorResult {
let (_, local_name) = get_attribute_parts(name.clone());
- let node: JS<Node> = NodeCast::from(self);
- node.get().wait_until_safe_to_modify_dom();
+ 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
@@ -380,7 +384,7 @@ impl AttributeHandlers for JS<Element> {
Some(idx) => {
if namespace == namespace::Null {
let removed_raw_value = self.get().attrs.get(idx).get().Value();
- vtable_for(&node).before_remove_attr(local_name.clone(), removed_raw_value);
+ vtable_for(node).before_remove_attr(local_name.clone(), removed_raw_value);
}
self.get_mut().attrs.remove(idx);
@@ -391,14 +395,15 @@ impl AttributeHandlers for JS<Element> {
}
fn notify_attribute_changed(&self, local_name: DOMString) {
- let node: JS<Node> = NodeCast::from(self);
+ let roots = RootCollection::new();
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
if node.is_in_doc() {
let damage = match local_name.as_slice() {
"style" | "id" | "class" => MatchSelectorsDocumentDamage,
_ => ContentChangedDocumentDamage
};
- let document = node.get().owner_doc();
- document.get().damage_and_reflow(damage);
+ let document = node.owner_doc().root(&roots);
+ document.deref().damage_and_reflow(damage);
}
}
@@ -417,8 +422,12 @@ impl AttributeHandlers for JS<Element> {
}
fn get_string_attribute(&self, name: &str) -> DOMString {
+ let roots = RootCollection::new();
match self.get_attribute(Null, name) {
- Some(x) => x.get().Value(),
+ Some(x) => {
+ let x = x.root(&roots);
+ x.deref().Value()
+ }
None => ~""
}
}
@@ -478,65 +487,72 @@ impl Element {
// http://dom.spec.whatwg.org/#dom-element-id
pub fn Id(&self, abstract_self: &JSRef<Element>) -> DOMString {
- abstract_self.unrooted().get_string_attribute("id")
+ abstract_self.get_string_attribute("id")
}
// http://dom.spec.whatwg.org/#dom-element-id
pub fn SetId(&mut self, abstract_self: &mut JSRef<Element>, id: DOMString) {
- abstract_self.unrooted().set_string_attribute("id", id);
+ abstract_self.set_string_attribute("id", id);
}
// http://dom.spec.whatwg.org/#dom-element-classname
pub fn ClassName(&self, abstract_self: &JSRef<Element>) -> DOMString {
- abstract_self.unrooted().get_string_attribute("class")
+ abstract_self.get_string_attribute("class")
}
// http://dom.spec.whatwg.org/#dom-element-classname
pub fn SetClassName(&self, abstract_self: &mut JSRef<Element>, class: DOMString) {
- abstract_self.unrooted().set_string_attribute("class", class);
+ abstract_self.set_string_attribute("class", class);
}
// http://dom.spec.whatwg.org/#dom-element-attributes
- pub fn Attributes(&mut self, abstract_self: &JSRef<Element>) -> JS<AttrList> {
+ pub fn Attributes(&mut self, abstract_self: &JSRef<Element>) -> Unrooted<AttrList> {
let roots = RootCollection::new();
match self.attr_list {
None => {
- let doc = self.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
+ let doc = self.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
let list = AttrList::new(&window.root_ref(), abstract_self);
- self.attr_list = Some(list.clone());
- list
+ self.attr_list.assign(Some(list));
+ Unrooted::new(self.attr_list.get_ref().clone())
}
- Some(ref list) => list.clone()
+ Some(ref list) => Unrooted::new(list.clone())
}
}
// http://dom.spec.whatwg.org/#dom-element-getattribute
pub fn GetAttribute(&self, abstract_self: &JSRef<Element>, name: DOMString) -> Option<DOMString> {
+ let roots = RootCollection::new();
let name = if abstract_self.get().html_element_in_html_document() {
name.to_ascii_lower()
} else {
name
};
- abstract_self.unrooted().get_attribute(Null, name).map(|s| s.get().Value())
+ abstract_self.get_attribute(Null, name)
+ .map(|s| {
+ let s = s.root(&roots);
+ s.deref().Value()
+ })
}
// http://dom.spec.whatwg.org/#dom-element-getattributens
pub fn GetAttributeNS(&self, abstract_self: &JSRef<Element>,
namespace: Option<DOMString>,
local_name: DOMString) -> Option<DOMString> {
+ let roots = RootCollection::new();
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
- abstract_self.unrooted()
- .get_attribute(namespace, local_name)
- .map(|attr| attr.get().value.clone())
+ abstract_self.get_attribute(namespace, local_name)
+ .map(|attr| {
+ let attr = attr.root(&roots);
+ attr.deref().Value()
+ })
}
// http://dom.spec.whatwg.org/#dom-element-setattribute
pub fn SetAttribute(&self, abstract_self: &mut JSRef<Element>,
name: DOMString,
value: DOMString) -> ErrorResult {
- abstract_self.unrooted().SetAttribute(name, value)
+ abstract_self.SetAttribute_(name, value)
}
// http://dom.spec.whatwg.org/#dom-element-setattributens
@@ -545,7 +561,7 @@ impl Element {
namespace_url: Option<DOMString>,
name: DOMString,
value: DOMString) -> ErrorResult {
- abstract_self.unrooted().SetAttributeNS(namespace_url, name, value)
+ abstract_self.SetAttributeNS_(namespace_url, name, value)
}
// http://dom.spec.whatwg.org/#dom-element-removeattribute
@@ -557,7 +573,7 @@ impl Element {
} else {
name
};
- abstract_self.unrooted().remove_attribute(namespace::Null, name)
+ abstract_self.remove_attribute(namespace::Null, name)
}
// http://dom.spec.whatwg.org/#dom-element-removeattributens
@@ -566,7 +582,7 @@ impl Element {
namespace: Option<DOMString>,
localname: DOMString) -> ErrorResult {
let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace));
- abstract_self.unrooted().remove_attribute(namespace, localname)
+ abstract_self.remove_attribute(namespace, localname)
}
// http://dom.spec.whatwg.org/#dom-element-hasattribute
@@ -582,63 +598,55 @@ impl Element {
self.GetAttributeNS(abstract_self, namespace, local_name).is_some()
}
- pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Element>, localname: DOMString) -> JS<HTMLCollection> {
+ pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Element>, localname: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
- let doc = self.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- HTMLCollection::by_tag_name(&window.root_ref(), NodeCast::from_ref(abstract_self), localname)
+ let window = window_from_node(abstract_self).root(&roots);
+ HTMLCollection::by_tag_name(&*window, NodeCast::from_ref(abstract_self), localname)
}
pub fn GetElementsByTagNameNS(&self, abstract_self: &JSRef<Element>, maybe_ns: Option<DOMString>,
- localname: DOMString) -> JS<HTMLCollection> {
+ localname: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
- let doc = self.node.owner_doc();
- let doc = doc.get();
let namespace = match maybe_ns {
Some(namespace) => Namespace::from_str(namespace),
None => Null
};
- let window = doc.window.root(&roots);
- HTMLCollection::by_tag_name_ns(&window.root_ref(), NodeCast::from_ref(abstract_self), localname, namespace)
+ let window = window_from_node(abstract_self).root(&roots);
+ HTMLCollection::by_tag_name_ns(&*window, NodeCast::from_ref(abstract_self), localname, namespace)
}
- pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Element>, classes: DOMString) -> JS<HTMLCollection> {
+ pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Element>, classes: DOMString) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
- let doc = self.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- HTMLCollection::by_class_name(&window.root_ref(), NodeCast::from_ref(abstract_self), classes)
+ let window = window_from_node(abstract_self).root(&roots);
+ HTMLCollection::by_class_name(&*window, NodeCast::from_ref(abstract_self), classes)
}
// http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects
- pub fn GetClientRects(&self, abstract_self: &JSRef<Element>) -> JS<ClientRectList> {
+ pub fn GetClientRects(&self, abstract_self: &JSRef<Element>) -> Unrooted<ClientRectList> {
let roots = RootCollection::new();
- let doc = self.node.owner_doc();
- let win = doc.get().window.root(&roots);
- let node: JS<Node> = NodeCast::from(&abstract_self.unrooted());
+ let win = window_from_node(abstract_self).root(&roots);
+ let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let rects = node.get_content_boxes();
- let rects = rects.iter().map(|r| {
+ let rects: ~[Root<ClientRect>] = rects.iter().map(|r| {
ClientRect::new(
- &win.root_ref(),
+ &*win,
r.origin.y,
r.origin.y + r.size.height,
r.origin.x,
- r.origin.x + r.size.width)
+ r.origin.x + r.size.width).root(&roots)
}).collect();
- ClientRectList::new(&win.root_ref(), rects)
+ ClientRectList::new(&*win, rects.iter().map(|rect| rect.deref().clone()).collect())
}
// http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect
- pub fn GetBoundingClientRect(&self, abstract_self: &JSRef<Element>) -> JS<ClientRect> {
+ pub fn GetBoundingClientRect(&self, abstract_self: &JSRef<Element>) -> Unrooted<ClientRect> {
let roots = RootCollection::new();
- let doc = self.node.owner_doc();
- let win = doc.get().window.root(&roots);
- let node: JS<Node> = NodeCast::from(&abstract_self.unrooted());
+ let win = window_from_node(abstract_self).root(&roots);
+ let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let rect = node.get_bounding_content_box();
ClientRect::new(
- &win.root_ref(),
+ &*win,
rect.origin.y,
rect.origin.y + rect.size.height,
rect.origin.x,
@@ -647,16 +655,18 @@ impl Element {
pub fn GetInnerHTML(&self, abstract_self: &JSRef<Element>) -> Fallible<DOMString> {
//XXX TODO: XML case
- Ok(serialize(&mut NodeIterator::new(NodeCast::from(&abstract_self.unrooted()), false, false)))
+ let roots = RootCollection::new();
+ Ok(serialize(&mut NodeIterator::new(&roots, NodeCast::from_ref(abstract_self), false, false)))
}
pub fn GetOuterHTML(&self, abstract_self: &JSRef<Element>) -> Fallible<DOMString> {
- Ok(serialize(&mut NodeIterator::new(NodeCast::from(&abstract_self.unrooted()), true, false)))
+ let roots = RootCollection::new();
+ Ok(serialize(&mut NodeIterator::new(&roots, NodeCast::from_ref(abstract_self), true, false)))
}
- pub fn Children(&self, abstract_self: &JSRef<Element>) -> JS<HTMLCollection> {
+ pub fn Children(&self, abstract_self: &JSRef<Element>) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
- let window = window_from_node(&abstract_self.unrooted()).root(&roots);
+ let window = window_from_node(abstract_self).root(&roots);
HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(abstract_self))
}
}
@@ -674,10 +684,10 @@ pub fn get_attribute_parts(name: DOMString) -> (Option<~str>, ~str) {
(prefix, local_name)
}
-impl VirtualMethods for JS<Element> {
+impl<'a> VirtualMethods for JSRef<'a, Element> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let node: JS<Node> = NodeCast::from(self);
- Some(~node as ~VirtualMethods:)
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ Some(~node.clone() as ~VirtualMethods:)
}
fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
@@ -687,20 +697,18 @@ impl VirtualMethods for JS<Element> {
_ => (),
}
- let node: JS<Node> = NodeCast::from(self);
match name.as_slice() {
"style" => {
- let doc = node.get().owner_doc();
+ let doc = document_from_node(self).root(&roots);
let base_url = doc.get().url().clone();
self.get_mut().style_attribute = Some(style::parse_style_attribute(value, &base_url))
}
- "id" if node.is_in_doc() => {
- // XXX: this dual declaration are workaround to avoid the compile error:
- // "borrowed value does not live long enough"
- let mut doc = node.get().owner_doc().clone();
- let doc = doc.get_mut();
- let elem = self.root(&roots);
- doc.register_named_element(&elem.root_ref(), value.clone());
+ "id" => {
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ if node.is_in_doc() {
+ let mut doc = document_from_node(self).root(&roots);
+ doc.register_named_element(self, value.clone());
+ }
}
_ => ()
}
@@ -715,18 +723,16 @@ impl VirtualMethods for JS<Element> {
_ => (),
}
- let node: JS<Node> = NodeCast::from(self);
match name.as_slice() {
"style" => {
self.get_mut().style_attribute = None
}
- "id" if node.is_in_doc() => {
- // XXX: this dual declaration are workaround to avoid the compile error:
- // "borrowed value does not live long enough"
- let mut doc = node.get().owner_doc().clone();
- let doc = doc.get_mut();
- let elem = self.root(&roots);
- doc.unregister_named_element(&elem.root_ref(), value);
+ "id" => {
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ if node.is_in_doc() {
+ let mut doc = document_from_node(self).root(&roots);
+ doc.unregister_named_element(self, value);
+ }
}
_ => ()
}
@@ -743,9 +749,9 @@ impl VirtualMethods for JS<Element> {
match self.get_attribute(Null, "id") {
Some(attr) => {
- let mut doc = document_from_node(self);
- let elem = self.root(&roots);
- doc.get_mut().register_named_element(&elem.root_ref(), attr.get().Value());
+ let attr = attr.root(&roots);
+ let mut doc = document_from_node(self).root(&roots);
+ doc.register_named_element(self, attr.deref().Value());
}
_ => ()
}
@@ -758,11 +764,10 @@ impl VirtualMethods for JS<Element> {
_ => (),
}
- match self.get_attribute(Null, "id") {
+ match self.get_attribute(Null, "id").root(&roots) {
Some(attr) => {
- let mut doc = document_from_node(self);
- let elem = self.root(&roots);
- doc.get_mut().unregister_named_element(&elem.root_ref(), attr.get().Value());
+ let mut doc = document_from_node(self).root(&roots);
+ doc.unregister_named_element(self, attr.deref().Value());
}
_ => ()
}
diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs
index 89c250dbc95..68f83a5d509 100644
--- a/src/components/script/dom/event.rs
+++ b/src/components/script/dom/event.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::EventBinding;
use dom::bindings::codegen::BindingDeclarations::EventBinding::EventConstants;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::eventtarget::EventTarget;
@@ -80,7 +80,7 @@ impl Event {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<Event> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<Event> {
reflect_dom_object(~Event::new_inherited(HTMLEventTypeId),
window,
EventBinding::Wrap)
@@ -94,12 +94,12 @@ impl Event {
self.type_.clone()
}
- pub fn GetTarget(&self) -> Option<JS<EventTarget>> {
- self.target.clone()
+ pub fn GetTarget(&self) -> Option<Unrooted<EventTarget>> {
+ self.target.as_ref().map(|target| Unrooted::new(target.clone()))
}
- pub fn GetCurrentTarget(&self) -> Option<JS<EventTarget>> {
- self.current_target.clone()
+ pub fn GetCurrentTarget(&self) -> Option<Unrooted<EventTarget>> {
+ self.current_target.as_ref().map(|target| Unrooted::new(target.clone()))
}
pub fn DefaultPrevented(&self) -> bool {
@@ -157,10 +157,11 @@ impl Event {
pub fn Constructor(global: &JSRef<Window>,
type_: DOMString,
- init: &EventBinding::EventInit) -> Fallible<JS<Event>> {
- let mut ev = Event::new(global);
- ev.get_mut().InitEvent(type_, init.bubbles, init.cancelable);
- Ok(ev)
+ init: &EventBinding::EventInit) -> Fallible<Unrooted<Event>> {
+ let roots = RootCollection::new();
+ let mut ev = Event::new(global).root(&roots);
+ ev.InitEvent(type_, init.bubbles, init.cancelable);
+ Ok(Unrooted::new_rooted(&*ev))
}
}
diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs
index b8fbce59974..9d45b398e02 100644
--- a/src/components/script/dom/eventdispatcher.rs
+++ b/src/components/script/dom/eventdispatcher.rs
@@ -4,35 +4,32 @@
use dom::bindings::callback::ReportExceptions;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived};
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JSRef, OptionalAssignable, RootCollection, Root};
use dom::eventtarget::{Capturing, Bubbling, EventTarget};
use dom::event::{Event, PhaseAtTarget, PhaseNone, PhaseBubbling, PhaseCapturing};
use dom::node::{Node, NodeHelpers};
// See http://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm
-pub fn dispatch_event(target: &JSRef<EventTarget>,
- pseudo_target: Option<JSRef<EventTarget>>,
- event: &mut JSRef<Event>) -> bool {
+pub fn dispatch_event<'a>(target: &JSRef<'a, EventTarget>,
+ pseudo_target: Option<JSRef<'a, EventTarget>>,
+ event: &mut JSRef<Event>) -> bool {
+ let roots = RootCollection::new();
assert!(!event.get().dispatching);
{
let event = event.get_mut();
- event.target = pseudo_target.map(|pseudo_target| {
- pseudo_target.unrooted()
- }).or_else(|| {
- Some(target.unrooted())
- });
+ event.target.assign(Some(pseudo_target.unwrap_or(target.clone())));
event.dispatching = true;
}
let type_ = event.get().type_.clone();
//TODO: no chain if not participating in a tree
- let chain: Vec<JS<EventTarget>> = if target.get().is_node() {
- let target_node: JS<Node> = NodeCast::to(&target.unrooted()).unwrap();
+ let mut chain: Vec<Root<EventTarget>> = if target.get().is_node() {
+ let target_node: &JSRef<Node> = NodeCast::to_ref(target).unwrap();
target_node.ancestors().map(|ancestor| {
- let ancestor_target: JS<EventTarget> = EventTargetCast::from(&ancestor);
- ancestor_target
+ let ancestor_target: &JSRef<EventTarget> = EventTargetCast::from_ref(&ancestor);
+ ancestor_target.unrooted().root(&roots)
}).collect()
} else {
vec!()
@@ -44,9 +41,9 @@ pub fn dispatch_event(target: &JSRef<EventTarget>,
/* capturing */
for cur_target in chain.as_slice().rev_iter() {
- let stopped = match cur_target.get().get_listeners_for(type_, Capturing) {
+ let stopped = match cur_target.get_listeners_for(type_, Capturing) {
Some(listeners) => {
- event.get_mut().current_target = Some(cur_target.clone());
+ event.current_target.assign(Some(cur_target.deref().clone()));
for listener in listeners.iter() {
//FIXME: this should have proper error handling, or explicitly
// drop the exception on the floor
@@ -72,7 +69,7 @@ pub fn dispatch_event(target: &JSRef<EventTarget>,
{
let event = event.get_mut();
event.phase = PhaseAtTarget;
- event.current_target = Some(target.unrooted());
+ event.current_target.assign(Some(target.clone()));
}
let opt_listeners = target.get().get_listeners(type_);
@@ -95,7 +92,7 @@ pub fn dispatch_event(target: &JSRef<EventTarget>,
for cur_target in chain.iter() {
let stopped = match cur_target.get().get_listeners_for(type_, Bubbling) {
Some(listeners) => {
- event.get_mut().current_target = Some(cur_target.clone());
+ event.get_mut().current_target.assign(Some(cur_target.deref().clone()));
for listener in listeners.iter() {
//FIXME: this should have proper error handling or explicitly
// drop exceptions on the floor.
@@ -116,6 +113,12 @@ pub fn dispatch_event(target: &JSRef<EventTarget>,
}
}
+ // Root ordering restrictions mean we need to unroot the chain entries
+ // in the same order they were rooted.
+ while chain.len() > 0 {
+ let _ = chain.pop();
+ }
+
let event = event.get_mut();
event.dispatching = false;
event.phase = PhaseNone;
diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs
index b77834e7cc4..67dc0ac7af9 100644
--- a/src/components/script/dom/eventtarget.rs
+++ b/src/components/script/dom/eventtarget.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::JSRef;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::bindings::error::{Fallible, InvalidState};
use dom::bindings::codegen::BindingDeclarations::EventListenerBinding;
@@ -107,10 +107,10 @@ impl EventTarget {
self.dispatch_event_with_target(abstract_self, None, event)
}
- pub fn dispatch_event_with_target(&self,
- abstract_self: &JSRef<EventTarget>,
- abstract_target: Option<JSRef<EventTarget>>,
- event: &mut JSRef<Event>) -> Fallible<bool> {
+ pub fn dispatch_event_with_target<'a>(&self,
+ abstract_self: &JSRef<'a, EventTarget>,
+ abstract_target: Option<JSRef<'a, EventTarget>>,
+ event: &mut JSRef<Event>) -> Fallible<bool> {
if event.get().dispatching || !event.get().initialized {
return Err(InvalidState);
}
@@ -128,7 +128,7 @@ impl Reflectable for EventTarget {
}
}
-impl VirtualMethods for JS<EventTarget> {
+impl<'a> VirtualMethods for JSRef<'a, EventTarget> {
fn super_type(&self) -> Option<~VirtualMethods:> {
None
}
diff --git a/src/components/script/dom/formdata.rs b/src/components/script/dom/formdata.rs
index 4b6d61c1d82..e1a7b0e7ddb 100644
--- a/src/components/script/dom/formdata.rs
+++ b/src/components/script/dom/formdata.rs
@@ -5,7 +5,7 @@
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{Fallible};
use dom::bindings::codegen::BindingDeclarations::FormDataBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::blob::Blob;
use dom::htmlformelement::HTMLFormElement;
use dom::window::Window;
@@ -37,12 +37,12 @@ impl FormData {
}
}
- pub fn new(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> JS<FormData> {
+ pub fn new(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> Unrooted<FormData> {
reflect_dom_object(~FormData::new_inherited(form, window.unrooted()), window, FormDataBinding::Wrap)
}
pub fn Constructor(window: &JSRef<Window>, form: Option<JSRef<HTMLFormElement>>)
- -> Fallible<JS<FormData>> {
+ -> Fallible<Unrooted<FormData>> {
Ok(FormData::new(form, window))
}
diff --git a/src/components/script/dom/htmlanchorelement.rs b/src/components/script/dom/htmlanchorelement.rs
index 7edd9116dea..d03723402eb 100644
--- a/src/components/script/dom/htmlanchorelement.rs
+++ b/src/components/script/dom/htmlanchorelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLAnchorElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLAnchorElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLAnchorElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLAnchorElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLAnchorElement> {
let element = HTMLAnchorElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLAnchorElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlappletelement.rs b/src/components/script/dom/htmlappletelement.rs
index d2b9fcf2e80..ea253003fd4 100644
--- a/src/components/script/dom/htmlappletelement.rs
+++ b/src/components/script/dom/htmlappletelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLAppletElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLAppletElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLAppletElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLAppletElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLAppletElement> {
let element = HTMLAppletElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLAppletElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlareaelement.rs b/src/components/script/dom/htmlareaelement.rs
index f4950d46ad7..d98f2033b77 100644
--- a/src/components/script/dom/htmlareaelement.rs
+++ b/src/components/script/dom/htmlareaelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLAreaElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAreaElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLAreaElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLAreaElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLAreaElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLAreaElement> {
let element = HTMLAreaElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLAreaElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlaudioelement.rs b/src/components/script/dom/htmlaudioelement.rs
index 2b0b86a36f1..a4ea33c7052 100644
--- a/src/components/script/dom/htmlaudioelement.rs
+++ b/src/components/script/dom/htmlaudioelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLAudioElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLAudioElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLAudioElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLAudioElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLAudioElement> {
let element = HTMLAudioElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLAudioElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlbaseelement.rs b/src/components/script/dom/htmlbaseelement.rs
index c7d206f3c65..bfaf1a74410 100644
--- a/src/components/script/dom/htmlbaseelement.rs
+++ b/src/components/script/dom/htmlbaseelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLBaseElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived;
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLBaseElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -34,7 +34,7 @@ impl HTMLBaseElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLBaseElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLBaseElement> {
let element = HTMLBaseElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLBaseElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlbodyelement.rs b/src/components/script/dom/htmlbodyelement.rs
index 466c60c6430..22b41c283ba 100644
--- a/src/components/script/dom/htmlbodyelement.rs
+++ b/src/components/script/dom/htmlbodyelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLBodyElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBodyElementDerived;
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLBodyElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -34,7 +34,7 @@ impl HTMLBodyElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLBodyElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLBodyElement> {
let element = HTMLBodyElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLBodyElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlbrelement.rs b/src/components/script/dom/htmlbrelement.rs
index e537b1b2c2a..5e23734042c 100644
--- a/src/components/script/dom/htmlbrelement.rs
+++ b/src/components/script/dom/htmlbrelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLBRElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived;
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLBRElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -34,7 +34,7 @@ impl HTMLBRElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLBRElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLBRElement> {
let element = HTMLBRElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLBRElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlbuttonelement.rs b/src/components/script/dom/htmlbuttonelement.rs
index cee5e13946c..30f031f8058 100644
--- a/src/components/script/dom/htmlbuttonelement.rs
+++ b/src/components/script/dom/htmlbuttonelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLButtonElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLButtonElementDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLButtonElementTypeId;
@@ -36,7 +36,7 @@ impl HTMLButtonElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLButtonElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLButtonElement> {
let element = HTMLButtonElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLButtonElementBinding::Wrap)
}
@@ -59,7 +59,7 @@ impl HTMLButtonElement {
Ok(())
}
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
@@ -134,11 +134,10 @@ impl HTMLButtonElement {
pub fn SetWillValidate(&mut self, _will_validate: bool) {
}
- pub fn Validity(&self) -> JS<ValidityState> {
+ pub fn Validity(&self) -> Unrooted<ValidityState> {
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- ValidityState::new(&doc.window.root(&roots).root_ref())
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ ValidityState::new(&*doc.deref().window.root(&roots))
}
pub fn SetValidity(&mut self, _validity: JS<ValidityState>) {
diff --git a/src/components/script/dom/htmlcanvaselement.rs b/src/components/script/dom/htmlcanvaselement.rs
index 4c825780216..469bb8b8643 100644
--- a/src/components/script/dom/htmlcanvaselement.rs
+++ b/src/components/script/dom/htmlcanvaselement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLCanvasElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::{ErrorResult};
use dom::document::Document;
use dom::element::HTMLCanvasElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLCanvasElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLCanvasElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLCanvasElement> {
let element = HTMLCanvasElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLCanvasElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs
index 8529d4daf64..73b4835ff2e 100644
--- a/src/components/script/dom/htmlcollection.rs
+++ b/src/components/script/dom/htmlcollection.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast};
use dom::bindings::codegen::BindingDeclarations::HTMLCollectionBinding;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::node::{Node, NodeHelpers};
@@ -46,19 +46,19 @@ impl HTMLCollection {
}
}
- pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> {
+ pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> Unrooted<HTMLCollection> {
reflect_dom_object(~HTMLCollection::new_inherited(window.unrooted(), collection),
window, HTMLCollectionBinding::Wrap)
}
}
impl HTMLCollection {
- pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> {
+ pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> Unrooted<HTMLCollection> {
HTMLCollection::new(window, Live(root.unrooted(), filter))
}
pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString)
- -> JS<HTMLCollection> {
+ -> Unrooted<HTMLCollection> {
struct TagNameFilter {
tag: DOMString
}
@@ -74,7 +74,7 @@ impl HTMLCollection {
}
pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString,
- namespace: Namespace) -> JS<HTMLCollection> {
+ namespace: Namespace) -> Unrooted<HTMLCollection> {
struct TagNameNSFilter {
tag: DOMString,
namespace: Namespace
@@ -92,13 +92,13 @@ impl HTMLCollection {
}
pub fn by_class_name(window: &JSRef<Window>, root: &JSRef<Node>, classes: DOMString)
- -> JS<HTMLCollection> {
+ -> Unrooted<HTMLCollection> {
struct ClassNameFilter {
classes: Vec<DOMString>
}
impl CollectionFilter for ClassNameFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
- self.classes.iter().all(|class| elem.unrooted().has_class(*class))
+ self.classes.iter().all(|class| elem.has_class(*class))
}
}
let filter = ClassNameFilter {
@@ -107,11 +107,11 @@ impl HTMLCollection {
HTMLCollection::create(window, root, ~filter)
}
- pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> JS<HTMLCollection> {
+ pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> Unrooted<HTMLCollection> {
struct ElementChildFilter;
impl CollectionFilter for ElementChildFilter {
fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool {
- root.unrooted().is_parent_of(NodeCast::from_ref(elem))
+ root.is_parent_of(NodeCast::from_ref(elem))
}
}
HTMLCollection::create(window, root, ~ElementChildFilter)
@@ -125,43 +125,43 @@ impl HTMLCollection {
match self.collection {
Static(ref elems) => elems.len() as u32,
Live(ref root, ref filter) => {
- let root_root = root.root(&roots);
- root.traverse_preorder()
+ let root = root.root(&roots);
+ root.deref().traverse_preorder(&roots)
.count(|child| {
- let elem: Option<JS<Element>> = ElementCast::to(&child);
- elem.map_or(false, |elem| {
- let elem = elem.root(&roots);
- filter.filter(&elem.root_ref(), &root_root.root_ref())
- })
+ let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&child);
+ elem.map_or(false, |elem| filter.filter(elem, &*root))
}) as u32
}
}
}
// http://dom.spec.whatwg.org/#dom-htmlcollection-item
- pub fn Item(&self, index: u32) -> Option<JS<Element>> {
+ pub fn Item(&self, index: u32) -> Option<Unrooted<Element>> {
let roots = RootCollection::new();
match self.collection {
Static(ref elems) => elems
.as_slice()
.get(index as uint)
- .map(|elem| elem.clone()),
+ .map(|elem| Unrooted::new(elem.clone())),
Live(ref root, ref filter) => {
- let root_root = root.root(&roots);
- root.traverse_preorder()
- .filter_map(|node| ElementCast::to(&node))
- .filter(|elem| {
- let elem = elem.root(&roots);
- filter.filter(&elem.root_ref(), &root_root.root_ref())
+ let root = root.root(&roots);
+ root.deref().traverse_preorder(&roots)
+ .filter_map(|node| {
+ let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node);
+ elem.filtered(|&elem| filter.filter(elem, &*root))
+ .and_then(|elem| Some(elem.clone()))
})
- .nth(index as uint).clone()
+ .nth(index as uint)
+ .clone()
+ .map(|elem| Unrooted::new_rooted(&elem))
}
}
}
// http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
- pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> {
+ pub fn NamedItem(&self, key: DOMString) -> Option<Unrooted<Element>> {
let roots = RootCollection::new();
+
// Step 1.
if key.is_empty() {
return None;
@@ -170,35 +170,36 @@ impl HTMLCollection {
// Step 2.
match self.collection {
Static(ref elems) => elems.iter()
+ .map(|elem| elem.root(&roots))
.find(|elem| {
elem.get_string_attribute("name") == key ||
elem.get_string_attribute("id") == key })
- .map(|maybe_elem| maybe_elem.clone()),
+ .map(|maybe_elem| Unrooted::new_rooted(&*maybe_elem)),
Live(ref root, ref filter) => {
- let root_root = root.root(&roots);
- root.traverse_preorder()
- .filter_map(|node| ElementCast::to(&node))
- .filter(|elem| {
- let elem = elem.root(&roots);
- filter.filter(&elem.root_ref(), &root_root.root_ref())
+ let root = root.root(&roots);
+ root.deref().traverse_preorder(&roots)
+ .filter_map(|node| {
+ let elem: Option<&JSRef<Element>> = ElementCast::to_ref(&node);
+ elem.filtered(|&elem| filter.filter(elem, &*root))
+ .and_then(|elem| Some(elem.clone()))
})
.find(|elem| {
elem.get_string_attribute("name") == key ||
elem.get_string_attribute("id") == key })
- .map(|maybe_elem| maybe_elem.clone())
+ .map(|maybe_elem| Unrooted::new_rooted(&maybe_elem))
}
}
}
}
impl HTMLCollection {
- pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> {
+ pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<Element>> {
let maybe_elem = self.Item(index);
*found = maybe_elem.is_some();
maybe_elem
}
- pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> {
+ pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<Unrooted<Element>> {
match maybe_name {
Some(name) => {
let maybe_elem = self.NamedItem(name);
diff --git a/src/components/script/dom/htmldataelement.rs b/src/components/script/dom/htmldataelement.rs
index b95c77acc07..767b3b18598 100644
--- a/src/components/script/dom/htmldataelement.rs
+++ b/src/components/script/dom/htmldataelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLDataElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLDataElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLDataElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDataElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLDataElement> {
let element = HTMLDataElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLDataElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmldatalistelement.rs b/src/components/script/dom/htmldatalistelement.rs
index b341a34dcb0..e4ac02bd83f 100644
--- a/src/components/script/dom/htmldatalistelement.rs
+++ b/src/components/script/dom/htmldatalistelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLDataListElementBinding;
use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, NodeCast};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::document::Document;
use dom::element::{Element, HTMLDataListElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -34,14 +34,14 @@ impl HTMLDataListElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDataListElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLDataListElement> {
let element = HTMLDataListElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLDataListElementBinding::Wrap)
}
}
impl HTMLDataListElement {
- pub fn Options(&self, abstract_self: &JSRef<HTMLDataListElement>) -> JS<HTMLCollection> {
+ pub fn Options(&self, abstract_self: &JSRef<HTMLDataListElement>) -> Unrooted<HTMLCollection> {
struct HTMLDataListOptionsFilter;
impl CollectionFilter for HTMLDataListOptionsFilter {
fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool {
@@ -51,7 +51,7 @@ impl HTMLDataListElement {
let roots = RootCollection::new();
let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let filter = ~HTMLDataListOptionsFilter;
- let window = window_from_node(&node.unrooted()).root(&roots);
- HTMLCollection::create(&window.root_ref(), node, filter)
+ let window = window_from_node(node).root(&roots);
+ HTMLCollection::create(&*window, node, filter)
}
}
diff --git a/src/components/script/dom/htmldirectoryelement.rs b/src/components/script/dom/htmldirectoryelement.rs
index 84ee0b539b6..f4b77ee5cf0 100644
--- a/src/components/script/dom/htmldirectoryelement.rs
+++ b/src/components/script/dom/htmldirectoryelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLDirectoryElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLDirectoryElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLDirectoryElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDirectoryElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLDirectoryElement> {
let element = HTMLDirectoryElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLDirectoryElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmldivelement.rs b/src/components/script/dom/htmldivelement.rs
index 723a2088307..6053582738d 100644
--- a/src/components/script/dom/htmldivelement.rs
+++ b/src/components/script/dom/htmldivelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLDivElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLDivElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLDivElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDivElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLDivElement> {
let element = HTMLDivElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLDivElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmldlistelement.rs b/src/components/script/dom/htmldlistelement.rs
index 8f3523189b7..113547af9d6 100644
--- a/src/components/script/dom/htmldlistelement.rs
+++ b/src/components/script/dom/htmldlistelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLDListElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLDListElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLDListElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDListElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLDListElement> {
let element = HTMLDListElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLDListElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlelement.rs b/src/components/script/dom/htmlelement.rs
index a7852aec276..d49ce843bd1 100644
--- a/src/components/script/dom/htmlelement.rs
+++ b/src/components/script/dom/htmlelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLElementBinding;
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::HTMLElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::{Element, ElementTypeId, HTMLElementTypeId};
@@ -39,7 +39,7 @@ impl HTMLElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLElement> {
let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.unrooted());
Node::reflect_node(~element, document, HTMLElementBinding::Wrap)
}
@@ -143,7 +143,7 @@ impl HTMLElement {
Ok(())
}
- pub fn GetOffsetParent(&self) -> Option<JS<Element>> {
+ pub fn GetOffsetParent(&self) -> Option<Unrooted<Element>> {
None
}
@@ -164,9 +164,9 @@ impl HTMLElement {
}
}
-impl VirtualMethods for JS<HTMLElement> {
+impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let element: JS<Element> = ElementCast::from(self);
- Some(~element as ~VirtualMethods:)
+ let element: &JSRef<Element> = ElementCast::from_ref(self);
+ Some(~element.clone() as ~VirtualMethods:)
}
}
diff --git a/src/components/script/dom/htmlembedelement.rs b/src/components/script/dom/htmlembedelement.rs
index 73a915c4cc7..864e1a1829c 100644
--- a/src/components/script/dom/htmlembedelement.rs
+++ b/src/components/script/dom/htmlembedelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLEmbedElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLEmbedElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLEmbedElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLEmbedElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLEmbedElement> {
let element = HTMLEmbedElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLEmbedElementBinding::Wrap)
}
@@ -89,7 +89,7 @@ impl HTMLEmbedElement {
Ok(())
}
- pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
+ pub fn GetSVGDocument(&self) -> Option<Unrooted<Document>> {
None
}
}
diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs
index 3b1141f403e..1bb9146e4e7 100644
--- a/src/components/script/dom/htmlfieldsetelement.rs
+++ b/src/components/script/dom/htmlfieldsetelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLFieldSetElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFieldSetElementDerived, NodeCast};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFieldSetElementTypeId};
@@ -37,7 +37,7 @@ impl HTMLFieldSetElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFieldSetElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLFieldSetElement> {
let element = HTMLFieldSetElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLFieldSetElementBinding::Wrap)
}
@@ -52,7 +52,7 @@ impl HTMLFieldSetElement {
Ok(())
}
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
@@ -69,33 +69,32 @@ impl HTMLFieldSetElement {
}
// http://www.whatwg.org/html/#dom-fieldset-elements
- pub fn Elements(&self, abstract_self: &JSRef<HTMLFieldSetElement>) -> JS<HTMLCollection> {
+ pub fn Elements(&self, abstract_self: &JSRef<HTMLFieldSetElement>) -> Unrooted<HTMLCollection> {
struct ElementsFilter;
impl CollectionFilter for ElementsFilter {
fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool {
static tag_names: StaticStringVec = &["button", "fieldset", "input",
"keygen", "object", "output", "select", "textarea"];
- let root: &JS<Element> = &ElementCast::to(&root.unrooted()).unwrap();
- &elem.unrooted() != root && tag_names.iter().any(|&tag_name| tag_name == elem.get().local_name)
+ let root: &JSRef<Element> = ElementCast::to_ref(root).unwrap();
+ elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.get().local_name)
}
}
let roots = RootCollection::new();
let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let filter = ~ElementsFilter;
- let window = window_from_node(&node.unrooted()).root(&roots);
- HTMLCollection::create(&window.root_ref(), node, filter)
+ let window = window_from_node(node).root(&roots);
+ HTMLCollection::create(&*window, node, filter)
}
pub fn WillValidate(&self) -> bool {
false
}
- pub fn Validity(&self) -> JS<ValidityState> {
+ pub fn Validity(&self) -> Unrooted<ValidityState> {
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- ValidityState::new(&window.root_ref())
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ ValidityState::new(&*window)
}
pub fn ValidationMessage(&self) -> DOMString {
diff --git a/src/components/script/dom/htmlfontelement.rs b/src/components/script/dom/htmlfontelement.rs
index f28971e7c43..fefc9c0f4df 100644
--- a/src/components/script/dom/htmlfontelement.rs
+++ b/src/components/script/dom/htmlfontelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLFontElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFontElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLFontElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLFontElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFontElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLFontElement> {
let element = HTMLFontElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLFontElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlformelement.rs b/src/components/script/dom/htmlformelement.rs
index 0e7159c61b9..329b9e07baf 100644
--- a/src/components/script/dom/htmlformelement.rs
+++ b/src/components/script/dom/htmlformelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLFormElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFormElementTypeId};
@@ -35,7 +35,7 @@ impl HTMLFormElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFormElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLFormElement> {
let element = HTMLFormElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLFormElementBinding::Wrap)
}
@@ -114,13 +114,12 @@ impl HTMLFormElement {
Ok(())
}
- pub fn Elements(&self) -> JS<HTMLCollection> {
+ pub fn Elements(&self) -> Unrooted<HTMLCollection> {
// FIXME: https://github.com/mozilla/servo/issues/1844
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- HTMLCollection::new(&window.root_ref(), Static(vec!()))
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ HTMLCollection::new(&*window, Static(vec!()))
}
pub fn Length(&self) -> i32 {
@@ -138,7 +137,7 @@ impl HTMLFormElement {
false
}
- pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> JS<Element> {
+ pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Unrooted<Element> {
fail!("Not implemented.")
}
}
diff --git a/src/components/script/dom/htmlframeelement.rs b/src/components/script/dom/htmlframeelement.rs
index 535c0398690..180124bf6dd 100644
--- a/src/components/script/dom/htmlframeelement.rs
+++ b/src/components/script/dom/htmlframeelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLFrameElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLFrameElementTypeId;
@@ -35,7 +35,7 @@ impl HTMLFrameElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFrameElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLFrameElement> {
let element = HTMLFrameElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLFrameElementBinding::Wrap)
}
@@ -90,11 +90,11 @@ impl HTMLFrameElement {
Ok(())
}
- pub fn GetContentDocument(&self) -> Option<JS<Document>> {
+ pub fn GetContentDocument(&self) -> Option<Unrooted<Document>> {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<Window>> {
+ pub fn GetContentWindow(&self) -> Option<Unrooted<Window>> {
None
}
diff --git a/src/components/script/dom/htmlframesetelement.rs b/src/components/script/dom/htmlframesetelement.rs
index 29691e01397..9177c197ae8 100644
--- a/src/components/script/dom/htmlframesetelement.rs
+++ b/src/components/script/dom/htmlframesetelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLFrameSetElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLFrameSetElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLFrameSetElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFrameSetElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLFrameSetElement> {
let element = HTMLFrameSetElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLFrameSetElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlheadelement.rs b/src/components/script/dom/htmlheadelement.rs
index 3f2037d7188..6b10c6078c3 100644
--- a/src/components/script/dom/htmlheadelement.rs
+++ b/src/components/script/dom/htmlheadelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLHeadElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHeadElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLHeadElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLHeadElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLHeadElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLHeadElement> {
let element = HTMLHeadElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLHeadElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlheadingelement.rs b/src/components/script/dom/htmlheadingelement.rs
index 40844eb36e5..4574189d7bf 100644
--- a/src/components/script/dom/htmlheadingelement.rs
+++ b/src/components/script/dom/htmlheadingelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLHeadingElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLHeadingElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -45,7 +45,7 @@ impl HTMLHeadingElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>, level: HeadingLevel) -> JS<HTMLHeadingElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>, level: HeadingLevel) -> Unrooted<HTMLHeadingElement> {
let element = HTMLHeadingElement::new_inherited(localName, document.unrooted(), level);
Node::reflect_node(~element, document, HTMLHeadingElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlhrelement.rs b/src/components/script/dom/htmlhrelement.rs
index 28bdd2ed3de..14098388c1d 100644
--- a/src/components/script/dom/htmlhrelement.rs
+++ b/src/components/script/dom/htmlhrelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLHRElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLHRElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLHRElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLHRElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLHRElement> {
let element = HTMLHRElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLHRElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlhtmlelement.rs b/src/components/script/dom/htmlhtmlelement.rs
index 391bf7b2465..1930ce271c2 100644
--- a/src/components/script/dom/htmlhtmlelement.rs
+++ b/src/components/script/dom/htmlhtmlelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLHtmlElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLHtmlElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLHtmlElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLHtmlElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLHtmlElement> {
let element = HTMLHtmlElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLHtmlElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs
index c037f17f9a5..c157e2ad445 100644
--- a/src/components/script/dom/htmliframeelement.rs
+++ b/src/components/script/dom/htmliframeelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLIFrameElementBinding;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived, HTMLElementCast};
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::trace::Untraceable;
use dom::document::Document;
use dom::element::{HTMLIFrameElementTypeId, Element};
@@ -74,7 +74,7 @@ impl HTMLIFrameElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLIFrameElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLIFrameElement> {
let element = HTMLIFrameElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLIFrameElementBinding::Wrap)
}
@@ -106,12 +106,12 @@ impl HTMLIFrameElement {
}
pub fn Sandbox(&self, abstract_self: &JSRef<HTMLIFrameElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("sandbox")
}
pub fn SetSandbox(&mut self, abstract_self: &mut JSRef<HTMLIFrameElement>, sandbox: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("sandbox", sandbox);
}
@@ -139,11 +139,11 @@ impl HTMLIFrameElement {
Ok(())
}
- pub fn GetContentDocument(&self) -> Option<JS<Document>> {
+ pub fn GetContentDocument(&self) -> Option<Unrooted<Document>> {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<Window>> {
+ pub fn GetContentWindow(&self) -> Option<Unrooted<Window>> {
None
}
@@ -195,15 +195,15 @@ impl HTMLIFrameElement {
Ok(())
}
- pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
+ pub fn GetSVGDocument(&self) -> Option<Unrooted<Document>> {
None
}
}
-impl VirtualMethods for JS<HTMLIFrameElement> {
+impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self);
- Some(~htmlelement as ~VirtualMethods:)
+ let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_ref(self);
+ Some(~htmlelement.clone() as ~VirtualMethods:)
}
fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs
index d986f5d07e8..04528c54283 100644
--- a/src/components/script/dom/htmlimageelement.rs
+++ b/src/components/script/dom/htmlimageelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLImageElementBinding;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived};
use dom::bindings::error::ErrorResult;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::trace::Untraceable;
use dom::document::Document;
use dom::element::{Element, HTMLImageElementTypeId};
@@ -43,7 +43,7 @@ impl HTMLImageElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLImageElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLImageElement> {
let element = HTMLImageElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLImageElementBinding::Wrap)
}
@@ -57,9 +57,10 @@ impl HTMLImageElement {
/// Makes the local `image` member match the status of the `src` attribute and starts
/// prefetching the image. This method must be called after `src` is changed.
fn update_image(&mut self, value: Option<DOMString>, url: Option<Url>) {
+ let roots = RootCollection::new();
let elem = &mut self.htmlelement.element;
- let document = elem.node.owner_doc();
- let window = document.get().window.get();
+ let document = elem.node.owner_doc().root(&roots);
+ let window = document.deref().window.root(&roots);
let image_cache = &window.image_cache_task;
match value {
None => {
@@ -80,22 +81,22 @@ impl HTMLImageElement {
}
pub fn Alt(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("alt")
}
- pub fn SetAlt(&mut self, abstract_self: &JSRef<HTMLImageElement>, alt: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ pub fn SetAlt(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, alt: DOMString) {
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("alt", alt)
}
pub fn Src(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("src")
}
pub fn SetSrc(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, src: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_url_attribute("src", src)
}
@@ -108,44 +109,44 @@ impl HTMLImageElement {
}
pub fn UseMap(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("useMap")
}
pub fn SetUseMap(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, use_map: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("useMap", use_map)
}
pub fn IsMap(&self, abstract_self: &JSRef<HTMLImageElement>) -> bool {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
from_str::<bool>(element.get_string_attribute("hspace")).unwrap()
}
pub fn SetIsMap(&self, abstract_self: &mut JSRef<HTMLImageElement>, is_map: bool) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("isMap", is_map.to_str())
}
pub fn Width(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 {
- let node: JS<Node> = NodeCast::from(&abstract_self.unrooted());
+ let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let rect = node.get_bounding_content_box();
to_px(rect.size.width) as u32
}
- pub fn SetWidth(&mut self, abstract_self: &JSRef<HTMLImageElement>, width: u32) {
- let mut elem: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ pub fn SetWidth(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, width: u32) {
+ let elem: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
elem.set_uint_attribute("width", width)
}
pub fn Height(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 {
- let node: JS<Node> = NodeCast::from(&abstract_self.unrooted());
+ let node: &JSRef<Node> = NodeCast::from_ref(abstract_self);
let rect = node.get_bounding_content_box();
to_px(rect.size.height) as u32
}
- pub fn SetHeight(&mut self, abstract_self: &JSRef<HTMLImageElement>, height: u32) {
- let mut elem: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ pub fn SetHeight(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, height: u32) {
+ let elem: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
elem.set_uint_attribute("height", height)
}
@@ -162,87 +163,88 @@ impl HTMLImageElement {
}
pub fn Name(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("name")
}
pub fn SetName(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, name: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("name", name)
}
pub fn Align(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("longdesc")
}
pub fn SetAlign(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, align: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("align", align)
}
pub fn Hspace(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
from_str::<u32>(element.get_string_attribute("hspace")).unwrap()
}
pub fn SetHspace(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, hspace: u32) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_uint_attribute("hspace", hspace)
}
pub fn Vspace(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
from_str::<u32>(element.get_string_attribute("vspace")).unwrap()
}
pub fn SetVspace(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, vspace: u32) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_uint_attribute("vspace", vspace)
}
pub fn LongDesc(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("longdesc")
}
pub fn SetLongDesc(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, longdesc: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("longdesc", longdesc)
}
pub fn Border(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_string_attribute("border")
}
pub fn SetBorder(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, border: DOMString) {
- let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &mut JSRef<Element> = ElementCast::from_mut_ref(abstract_self);
element.set_string_attribute("border", border)
}
}
-impl VirtualMethods for JS<HTMLImageElement> {
+impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self);
- Some(~htmlelement as ~VirtualMethods:)
+ let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_ref(self);
+ Some(~htmlelement.clone() as ~VirtualMethods:)
}
fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
+ let roots = RootCollection::new();
match self.super_type() {
Some(ref mut s) => s.after_set_attr(name.clone(), value.clone()),
_ => (),
}
if "src" == name {
- let window = window_from_node(self);
+ let window = window_from_node(self).root(&roots);
let url = Some(window.get().get_url());
self.get_mut().update_image(Some(value), url);
}
}
fn before_remove_attr(&mut self, name: DOMString, value: DOMString) {
- match self.super_type() {
+ match self.super_type() {
Some(ref mut s) => s.before_remove_attr(name.clone(), value.clone()),
_ => (),
}
diff --git a/src/components/script/dom/htmlinputelement.rs b/src/components/script/dom/htmlinputelement.rs
index 90914fbc7bb..55d8fc7c1a7 100644
--- a/src/components/script/dom/htmlinputelement.rs
+++ b/src/components/script/dom/htmlinputelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLInputElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLInputElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLInputElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLInputElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLInputElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLInputElement> {
let element = HTMLInputElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLInputElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmllabelelement.rs b/src/components/script/dom/htmllabelelement.rs
index 5c920fd75eb..dcd080f7f24 100644
--- a/src/components/script/dom/htmllabelelement.rs
+++ b/src/components/script/dom/htmllabelelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLLabelElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLLabelElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLLabelElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLLabelElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLLabelElement> {
let element = HTMLLabelElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLLabelElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmllegendelement.rs b/src/components/script/dom/htmllegendelement.rs
index ee6199808eb..696247f40db 100644
--- a/src/components/script/dom/htmllegendelement.rs
+++ b/src/components/script/dom/htmllegendelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLLegendElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLLegendElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLLegendElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLLegendElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLLegendElement> {
let element = HTMLLegendElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLLegendElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmllielement.rs b/src/components/script/dom/htmllielement.rs
index 2a7501b08e9..d3b625e5987 100644
--- a/src/components/script/dom/htmllielement.rs
+++ b/src/components/script/dom/htmllielement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLLIElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLLIElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLLIElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLLIElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLLIElement> {
let element = HTMLLIElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLLIElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmllinkelement.rs b/src/components/script/dom/htmllinkelement.rs
index 528ea303a2c..3d474d1af64 100644
--- a/src/components/script/dom/htmllinkelement.rs
+++ b/src/components/script/dom/htmllinkelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLLinkElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLLinkElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLLinkElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLLinkElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLLinkElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLLinkElement> {
let element = HTMLLinkElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLLinkElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlmainelement.rs b/src/components/script/dom/htmlmainelement.rs
index 74bc99c0149..ad9a2c6af1e 100644
--- a/src/components/script/dom/htmlmainelement.rs
+++ b/src/components/script/dom/htmlmainelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLMainElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMainElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLMainElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLMainElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLMainElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLMainElement> {
let element = HTMLMainElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLMainElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlmapelement.rs b/src/components/script/dom/htmlmapelement.rs
index aff393505af..18dfd17e88b 100644
--- a/src/components/script/dom/htmlmapelement.rs
+++ b/src/components/script/dom/htmlmapelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLMapElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLMapElementTypeId;
@@ -35,7 +35,7 @@ impl HTMLMapElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLMapElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLMapElement> {
let element = HTMLMapElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLMapElementBinding::Wrap)
}
@@ -50,12 +50,11 @@ impl HTMLMapElement {
Ok(())
}
- pub fn Areas(&self) -> JS<HTMLCollection> {
+ pub fn Areas(&self) -> Unrooted<HTMLCollection> {
let roots = RootCollection::new();
// FIXME: https://github.com/mozilla/servo/issues/1845
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- HTMLCollection::new(&window.root_ref(), Static(vec!()))
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ HTMLCollection::new(&*window, Static(vec!()))
}
}
diff --git a/src/components/script/dom/htmlmetaelement.rs b/src/components/script/dom/htmlmetaelement.rs
index 191a49f2444..737cc6710fc 100644
--- a/src/components/script/dom/htmlmetaelement.rs
+++ b/src/components/script/dom/htmlmetaelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLMetaElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLMetaElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLMetaElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLMetaElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLMetaElement> {
let element = HTMLMetaElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLMetaElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlmeterelement.rs b/src/components/script/dom/htmlmeterelement.rs
index 19bac1c9797..9d5f699ae14 100644
--- a/src/components/script/dom/htmlmeterelement.rs
+++ b/src/components/script/dom/htmlmeterelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLMeterElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLMeterElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLMeterElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLMeterElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLMeterElement> {
let element = HTMLMeterElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLMeterElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlmodelement.rs b/src/components/script/dom/htmlmodelement.rs
index b934ef74b86..41ed8244a9d 100644
--- a/src/components/script/dom/htmlmodelement.rs
+++ b/src/components/script/dom/htmlmodelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLModElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLModElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLModElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLModElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLModElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLModElement> {
let element = HTMLModElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLModElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlobjectelement.rs b/src/components/script/dom/htmlobjectelement.rs
index f3f48cba313..4814ac4b337 100644
--- a/src/components/script/dom/htmlobjectelement.rs
+++ b/src/components/script/dom/htmlobjectelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLObjectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLObjectElementTypeId};
@@ -47,7 +47,7 @@ impl HTMLObjectElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLObjectElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLObjectElement> {
let element = HTMLObjectElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLObjectElementBinding::Wrap)
}
@@ -57,15 +57,16 @@ trait ProcessDataURL {
fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>);
}
-impl ProcessDataURL for JS<HTMLObjectElement> {
+impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
// Makes the local `data` member match the status of the `data` attribute and starts
/// prefetching the image. This method must be called after `data` is changed.
fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>) {
- let elem: JS<Element> = ElementCast::from(self);
+ let roots = RootCollection::new();
+ let elem: &JSRef<Element> = ElementCast::from_ref(self);
// TODO: support other values
- match (elem.get_attribute(Null, "type").map(|x| x.get().Value()),
- elem.get_attribute(Null, "data").map(|x| x.get().Value())) {
+ match (elem.get_attribute(Null, "type").map(|x| x.root(&roots).Value()),
+ elem.get_attribute(Null, "data").map(|x| x.root(&roots).Value())) {
(None, Some(uri)) => {
if is_image_data(uri) {
let data_url = parse_url(uri, url);
@@ -111,7 +112,7 @@ impl HTMLObjectElement {
Ok(())
}
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
@@ -131,11 +132,11 @@ impl HTMLObjectElement {
Ok(())
}
- pub fn GetContentDocument(&self) -> Option<JS<Document>> {
+ pub fn GetContentDocument(&self) -> Option<Unrooted<Document>> {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<Window>> {
+ pub fn GetContentWindow(&self) -> Option<Unrooted<Window>> {
None
}
@@ -143,11 +144,10 @@ impl HTMLObjectElement {
false
}
- pub fn Validity(&self) -> JS<ValidityState> {
+ pub fn Validity(&self) -> Unrooted<ValidityState> {
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
ValidityState::new(&window.root_ref())
}
@@ -242,25 +242,26 @@ impl HTMLObjectElement {
Ok(())
}
- pub fn GetSVGDocument(&self) -> Option<JS<Document>> {
+ pub fn GetSVGDocument(&self) -> Option<Unrooted<Document>> {
None
}
}
-impl VirtualMethods for JS<HTMLObjectElement> {
+impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self);
- Some(~htmlelement as ~VirtualMethods:)
+ let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_ref(self);
+ Some(~htmlelement.clone() as ~VirtualMethods:)
}
fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
+ let roots = RootCollection::new();
match self.super_type() {
Some(ref mut s) => s.after_set_attr(name.clone(), value),
_ => (),
}
if "data" == name {
- let window = window_from_node(self);
+ let window = window_from_node(self).root(&roots);
let url = Some(window.get().get_url());
self.process_data_url(window.get().image_cache_task.clone(), url);
}
diff --git a/src/components/script/dom/htmlolistelement.rs b/src/components/script/dom/htmlolistelement.rs
index a62acc013c6..1330e2cbd40 100644
--- a/src/components/script/dom/htmlolistelement.rs
+++ b/src/components/script/dom/htmlolistelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLOListElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOListElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLOListElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOListElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLOListElement> {
let element = HTMLOListElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLOListElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmloptgroupelement.rs b/src/components/script/dom/htmloptgroupelement.rs
index 3ef4df88ab9..d5eab9bec46 100644
--- a/src/components/script/dom/htmloptgroupelement.rs
+++ b/src/components/script/dom/htmloptgroupelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLOptGroupElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOptGroupElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLOptGroupElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOptGroupElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLOptGroupElement> {
let element = HTMLOptGroupElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLOptGroupElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmloptionelement.rs b/src/components/script/dom/htmloptionelement.rs
index 5119ce17b73..bf1f594009e 100644
--- a/src/components/script/dom/htmloptionelement.rs
+++ b/src/components/script/dom/htmloptionelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLOptionElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOptionElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOptionElementTypeId;
@@ -35,7 +35,7 @@ impl HTMLOptionElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOptionElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLOptionElement> {
let element = HTMLOptionElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLOptionElementBinding::Wrap)
}
@@ -50,7 +50,7 @@ impl HTMLOptionElement {
Ok(())
}
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
diff --git a/src/components/script/dom/htmloutputelement.rs b/src/components/script/dom/htmloutputelement.rs
index 4f5dae6d8c0..a72d9410d20 100644
--- a/src/components/script/dom/htmloutputelement.rs
+++ b/src/components/script/dom/htmloutputelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLOutputElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLOutputElementTypeId;
@@ -36,14 +36,14 @@ impl HTMLOutputElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOutputElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLOutputElement> {
let element = HTMLOutputElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLOutputElementBinding::Wrap)
}
}
impl HTMLOutputElement {
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
@@ -82,12 +82,11 @@ impl HTMLOutputElement {
pub fn SetWillValidate(&mut self, _will_validate: bool) {
}
- pub fn Validity(&self) -> JS<ValidityState> {
+ pub fn Validity(&self) -> Unrooted<ValidityState> {
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- ValidityState::new(&window.root_ref())
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ ValidityState::new(&*window)
}
pub fn SetValidity(&mut self, _validity: JS<ValidityState>) {
diff --git a/src/components/script/dom/htmlparagraphelement.rs b/src/components/script/dom/htmlparagraphelement.rs
index b473a81613e..d5dafd6abda 100644
--- a/src/components/script/dom/htmlparagraphelement.rs
+++ b/src/components/script/dom/htmlparagraphelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLParagraphElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLParagraphElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLParagraphElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLParagraphElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLParagraphElement> {
let element = HTMLParagraphElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLParagraphElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlparamelement.rs b/src/components/script/dom/htmlparamelement.rs
index c33b68fc932..db4d9ec1b89 100644
--- a/src/components/script/dom/htmlparamelement.rs
+++ b/src/components/script/dom/htmlparamelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLParamElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLParamElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLParamElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLParamElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLParamElement> {
let element = HTMLParamElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLParamElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlpreelement.rs b/src/components/script/dom/htmlpreelement.rs
index cfbc2ddc3fe..e2c404074bd 100644
--- a/src/components/script/dom/htmlpreelement.rs
+++ b/src/components/script/dom/htmlpreelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLPreElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLPreElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLPreElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLPreElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLPreElement> {
let element = HTMLPreElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLPreElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlprogresselement.rs b/src/components/script/dom/htmlprogresselement.rs
index ec76ab7d41d..024025afa6d 100644
--- a/src/components/script/dom/htmlprogresselement.rs
+++ b/src/components/script/dom/htmlprogresselement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLProgressElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLProgressElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLProgressElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLProgressElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLProgressElement> {
let element = HTMLProgressElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLProgressElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlquoteelement.rs b/src/components/script/dom/htmlquoteelement.rs
index 0ec36d39711..9c67c2ac2f4 100644
--- a/src/components/script/dom/htmlquoteelement.rs
+++ b/src/components/script/dom/htmlquoteelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLQuoteElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLQuoteElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLQuoteElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLQuoteElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLQuoteElement> {
let element = HTMLQuoteElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLQuoteElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlscriptelement.rs b/src/components/script/dom/htmlscriptelement.rs
index 3be3739542a..808b05a12cf 100644
--- a/src/components/script/dom/htmlscriptelement.rs
+++ b/src/components/script/dom/htmlscriptelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLScriptElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLScriptElementDerived;
use dom::bindings::codegen::InheritTypes::ElementCast;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{HTMLScriptElementTypeId, Element, AttributeHandlers};
@@ -35,7 +35,7 @@ impl HTMLScriptElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLScriptElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLScriptElement> {
let element = HTMLScriptElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLScriptElementBinding::Wrap)
}
@@ -43,7 +43,7 @@ impl HTMLScriptElement {
impl HTMLScriptElement {
pub fn Src(&self, abstract_self: &JSRef<HTMLScriptElement>) -> DOMString {
- let element: JS<Element> = ElementCast::from(&abstract_self.unrooted());
+ let element: &JSRef<Element> = ElementCast::from_ref(abstract_self);
element.get_url_attribute("src")
}
diff --git a/src/components/script/dom/htmlselectelement.rs b/src/components/script/dom/htmlselectelement.rs
index 53a738e1a97..666cb529774 100644
--- a/src/components/script/dom/htmlselectelement.rs
+++ b/src/components/script/dom/htmlselectelement.rs
@@ -5,7 +5,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLSelectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLSelectElementDerived;
use dom::bindings::codegen::UnionTypes::{HTMLElementOrLong, HTMLOptionElementOrHTMLOptGroupElement};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLSelectElementTypeId};
@@ -38,7 +38,7 @@ impl HTMLSelectElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLSelectElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLSelectElement> {
let element = HTMLSelectElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLSelectElementBinding::Wrap)
}
@@ -61,7 +61,7 @@ impl HTMLSelectElement {
Ok(())
}
- pub fn GetForm(&self) -> Option<JS<HTMLFormElement>> {
+ pub fn GetForm(&self) -> Option<Unrooted<HTMLFormElement>> {
None
}
@@ -109,15 +109,15 @@ impl HTMLSelectElement {
Ok(())
}
- pub fn Item(&self, _index: u32) -> Option<JS<Element>> {
+ pub fn Item(&self, _index: u32) -> Option<Unrooted<Element>> {
None
}
- pub fn NamedItem(&self, _name: DOMString) -> Option<JS<HTMLOptionElement>> {
+ pub fn NamedItem(&self, _name: DOMString) -> Option<Unrooted<HTMLOptionElement>> {
None
}
- pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<JS<Element>> {
+ pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Unrooted<Element>> {
None
}
@@ -153,12 +153,11 @@ impl HTMLSelectElement {
pub fn SetWillValidate(&mut self, _will_validate: bool) {
}
- pub fn Validity(&self) -> JS<ValidityState> {
+ pub fn Validity(&self) -> Unrooted<ValidityState> {
let roots = RootCollection::new();
- let doc = self.htmlelement.element.node.owner_doc();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- ValidityState::new(&window.root_ref())
+ let doc = self.htmlelement.element.node.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ ValidityState::new(&*window)
}
pub fn SetValidity(&mut self, _validity: JS<ValidityState>) {
diff --git a/src/components/script/dom/htmlserializer.rs b/src/components/script/dom/htmlserializer.rs
index e99982822ed..55c1ba03d9e 100644
--- a/src/components/script/dom/htmlserializer.rs
+++ b/src/components/script/dom/htmlserializer.rs
@@ -4,15 +4,15 @@
use servo_util::namespace;
use dom::attr::Attr;
-use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast};
use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JSRef, RootCollection};
use dom::characterdata::CharacterData;
use dom::comment::Comment;
use dom::documenttype::DocumentType;
use dom::element::Element;
-use dom::node::NodeIterator;
+use dom::node::{Node, NodeIterator};
use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, CommentNodeTypeId};
use dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
use dom::node::{TextNodeTypeId, NodeHelpers};
@@ -20,7 +20,6 @@ use dom::processinginstruction::ProcessingInstruction;
use dom::text::Text;
pub fn serialize(iterator: &mut NodeIterator) -> ~str {
- let roots = RootCollection::new();
let mut html = ~"";
let mut open_elements: Vec<~str> = vec!();
@@ -31,29 +30,25 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str {
html.push_str(
match node.type_id() {
ElementNodeTypeId(..) => {
- let elem: JS<Element> = ElementCast::to(&node).unwrap();
- let elem = elem.root(&roots);
- serialize_elem(&elem.root_ref(), &mut open_elements)
+ let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap();
+ serialize_elem(elem, &mut open_elements)
}
CommentNodeTypeId => {
- let comment: JS<Comment> = CommentCast::to(&node).unwrap();
- let comment = comment.root(&roots);
- serialize_comment(&comment.root_ref())
+ let comment: &JSRef<Comment> = CommentCast::to_ref(&node).unwrap();
+ serialize_comment(comment)
}
TextNodeTypeId => {
- let text: JS<Text> = TextCast::to(&node).unwrap();
- let text = text.root(&roots);
- serialize_text(&text.root_ref())
+ let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap();
+ serialize_text(text)
}
DoctypeNodeTypeId => {
- let doctype: JS<DocumentType> = DocumentTypeCast::to(&node).unwrap();
- let doctype = doctype.root(&roots);
- serialize_doctype(&doctype.root_ref())
+ let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(&node).unwrap();
+ serialize_doctype(doctype)
}
ProcessingInstructionNodeTypeId => {
- let processing_instruction: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node).unwrap();
- let processing_instruction = processing_instruction.root(&roots);
- serialize_processing_instruction(&processing_instruction.root_ref())
+ let processing_instruction: &JSRef<ProcessingInstruction> =
+ ProcessingInstructionCast::to_ref(&node).unwrap();
+ serialize_processing_instruction(processing_instruction)
}
DocumentFragmentNodeTypeId => {
~""
@@ -75,9 +70,11 @@ fn serialize_comment(comment: &JSRef<Comment>) -> ~str {
}
fn serialize_text(text: &JSRef<Text>) -> ~str {
- match text.get().characterdata.node.parent_node {
+ let roots = RootCollection::new();
+ let text_node: &JSRef<Node> = NodeCast::from_ref(text);
+ match text_node.parent_node().map(|node| node.root(&roots)) {
Some(ref parent) if parent.is_element() => {
- let elem: JS<Element> = ElementCast::to(parent).unwrap();
+ let elem: &JSRef<Element> = ElementCast::to_ref(&**parent).unwrap();
match elem.get().local_name.as_slice() {
"style" | "script" | "xmp" | "iframe" |
"noembed" | "noframes" | "plaintext" |
@@ -104,14 +101,15 @@ fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str
let mut rv = ~"<" + elem.get().local_name;
for attr in elem.get().attrs.iter() {
let attr = attr.root(&roots);
- rv.push_str(serialize_attr(&attr.root_ref()));
+ rv.push_str(serialize_attr(&*attr));
};
rv.push_str(">");
match elem.get().local_name.as_slice() {
"pre" | "listing" | "textarea" if elem.get().namespace == namespace::HTML => {
- match elem.get().node.first_child {
+ let node: &JSRef<Node> = NodeCast::from_ref(elem);
+ match node.first_child().map(|child| child.root(&roots)) {
Some(ref child) if child.is_text() => {
- let text: JS<CharacterData> = CharacterDataCast::to(child).unwrap();
+ let text: &JSRef<CharacterData> = CharacterDataCast::to_ref(&**child).unwrap();
if text.get().data.len() > 0 && text.get().data[0] == 0x0A as u8 {
rv.push_str("\x0A");
}
diff --git a/src/components/script/dom/htmlsourceelement.rs b/src/components/script/dom/htmlsourceelement.rs
index 8db513bfbd2..ef7ec5c9108 100644
--- a/src/components/script/dom/htmlsourceelement.rs
+++ b/src/components/script/dom/htmlsourceelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLSourceElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLSourceElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLSourceElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLSourceElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLSourceElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLSourceElement> {
let element = HTMLSourceElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLSourceElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlspanelement.rs b/src/components/script/dom/htmlspanelement.rs
index 20e95ae4b8d..3867fa591de 100644
--- a/src/components/script/dom/htmlspanelement.rs
+++ b/src/components/script/dom/htmlspanelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLSpanElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLSpanElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLSpanElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLSpanElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLSpanElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLSpanElement> {
let element = HTMLSpanElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLSpanElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlstyleelement.rs b/src/components/script/dom/htmlstyleelement.rs
index be43a40f27d..ec2a997586b 100644
--- a/src/components/script/dom/htmlstyleelement.rs
+++ b/src/components/script/dom/htmlstyleelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLStyleElementBinding;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLStyleElementDerived, NodeCast};
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLStyleElementTypeId;
@@ -37,7 +37,7 @@ impl HTMLStyleElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLStyleElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLStyleElement> {
let element = HTMLStyleElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLStyleElementBinding::Wrap)
}
@@ -80,28 +80,27 @@ pub trait StyleElementHelpers {
fn parse_own_css(&self);
}
-impl StyleElementHelpers for JS<HTMLStyleElement> {
+impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> {
fn parse_own_css(&self) {
let roots = RootCollection::new();
- let node: JS<Node> = NodeCast::from(self);
- let node_root = node.root(&roots);
- let win = window_from_node(&node);
+ let node: &JSRef<Node> = NodeCast::from_ref(self);
+ let win = window_from_node(node).root(&roots);
let url = win.get().page().get_url();
- let data = node.get().GetTextContent(&node_root.root_ref()).expect("Element.textContent must be a string");
+ let data = node.get().GetTextContent(node).expect("Element.textContent must be a string");
let sheet = parse_inline_css(url, data);
let LayoutChan(ref layout_chan) = *win.get().page().layout_chan;
layout_chan.send(AddStylesheetMsg(sheet));
}
}
-impl VirtualMethods for JS<HTMLStyleElement> {
+impl<'a> VirtualMethods for JSRef<'a, HTMLStyleElement> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let htmlelement: JS<HTMLElement> = HTMLElementCast::from(self);
- Some(~htmlelement as ~VirtualMethods:)
+ let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_ref(self);
+ Some(~htmlelement.clone() as ~VirtualMethods:)
}
- fn child_inserted(&mut self, child: &JS<Node>) {
+ fn child_inserted(&mut self, child: &JSRef<Node>) {
match self.super_type() {
Some(ref mut s) => s.child_inserted(child),
_ => (),
diff --git a/src/components/script/dom/htmltablecaptionelement.rs b/src/components/script/dom/htmltablecaptionelement.rs
index 6aa88d6c05a..ba83cd93ae8 100644
--- a/src/components/script/dom/htmltablecaptionelement.rs
+++ b/src/components/script/dom/htmltablecaptionelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableCaptionElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableCaptionElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableCaptionElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTableCaptionElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableCaptionElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableCaptionElement> {
let element = HTMLTableCaptionElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableCaptionElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltablecolelement.rs b/src/components/script/dom/htmltablecolelement.rs
index cc967f14c49..c8b8c74ad6b 100644
--- a/src/components/script/dom/htmltablecolelement.rs
+++ b/src/components/script/dom/htmltablecolelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableColElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableColElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableColElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTableColElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableColElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableColElement> {
let element = HTMLTableColElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableColElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltabledatacellelement.rs b/src/components/script/dom/htmltabledatacellelement.rs
index 7a6185d6ec2..830740127f0 100644
--- a/src/components/script/dom/htmltabledatacellelement.rs
+++ b/src/components/script/dom/htmltabledatacellelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableDataCellElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableDataCellElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLTableDataCellElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLTableDataCellElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableDataCellElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableDataCellElement> {
let element = HTMLTableDataCellElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableDataCellElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltableelement.rs b/src/components/script/dom/htmltableelement.rs
index 20948ff1d67..8150c68d3a6 100644
--- a/src/components/script/dom/htmltableelement.rs
+++ b/src/components/script/dom/htmltableelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTableElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableElement> {
let element = HTMLTableElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltableheadercellelement.rs b/src/components/script/dom/htmltableheadercellelement.rs
index 47057fd0fa2..90dba152b44 100644
--- a/src/components/script/dom/htmltableheadercellelement.rs
+++ b/src/components/script/dom/htmltableheadercellelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableHeaderCellElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableHeaderCellElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLTableHeaderCellElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLTableHeaderCellElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableHeaderCellElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableHeaderCellElement> {
let element = HTMLTableHeaderCellElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableHeaderCellElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltablerowelement.rs b/src/components/script/dom/htmltablerowelement.rs
index 1256dbfdabc..2b77faeadab 100644
--- a/src/components/script/dom/htmltablerowelement.rs
+++ b/src/components/script/dom/htmltablerowelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableRowElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableRowElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableRowElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTableRowElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableRowElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableRowElement> {
let element = HTMLTableRowElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableRowElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltablesectionelement.rs b/src/components/script/dom/htmltablesectionelement.rs
index 3689bba1f48..b44aba6e9dc 100644
--- a/src/components/script/dom/htmltablesectionelement.rs
+++ b/src/components/script/dom/htmltablesectionelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTableSectionElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTableSectionElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTableSectionElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTableSectionElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTableSectionElement> {
let element = HTMLTableSectionElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTableSectionElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltemplateelement.rs b/src/components/script/dom/htmltemplateelement.rs
index 9880dc0b34d..f645e1815d3 100644
--- a/src/components/script/dom/htmltemplateelement.rs
+++ b/src/components/script/dom/htmltemplateelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTemplateElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTemplateElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLTemplateElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLTemplateElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTemplateElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTemplateElement> {
let element = HTMLTemplateElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTemplateElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltextareaelement.rs b/src/components/script/dom/htmltextareaelement.rs
index 4f4c7b55c9d..4955085c751 100644
--- a/src/components/script/dom/htmltextareaelement.rs
+++ b/src/components/script/dom/htmltextareaelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTextAreaElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::{ErrorResult, Fallible};
use dom::document::Document;
use dom::element::HTMLTextAreaElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTextAreaElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTextAreaElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTextAreaElement> {
let element = HTMLTextAreaElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTextAreaElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltimeelement.rs b/src/components/script/dom/htmltimeelement.rs
index 938a1013876..df74323fc01 100644
--- a/src/components/script/dom/htmltimeelement.rs
+++ b/src/components/script/dom/htmltimeelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTimeElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTimeElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTimeElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTimeElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTimeElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTimeElement> {
let element = HTMLTimeElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTimeElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltitleelement.rs b/src/components/script/dom/htmltitleelement.rs
index 3fe46fe1b81..2c1af9b5291 100644
--- a/src/components/script/dom/htmltitleelement.rs
+++ b/src/components/script/dom/htmltitleelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTitleElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTitleElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTitleElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTitleElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTitleElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTitleElement> {
let element = HTMLTitleElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTitleElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmltrackelement.rs b/src/components/script/dom/htmltrackelement.rs
index 19a58090dcf..408da82d53b 100644
--- a/src/components/script/dom/htmltrackelement.rs
+++ b/src/components/script/dom/htmltrackelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLTrackElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLTrackElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLTrackElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLTrackElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLTrackElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLTrackElement> {
let element = HTMLTrackElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLTrackElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlulistelement.rs b/src/components/script/dom/htmlulistelement.rs
index 1fe1be79af1..c2661a5ee46 100644
--- a/src/components/script/dom/htmlulistelement.rs
+++ b/src/components/script/dom/htmlulistelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLUListElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLUListElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLUListElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLUListElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLUListElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLUListElement> {
let element = HTMLUListElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLUListElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlunknownelement.rs b/src/components/script/dom/htmlunknownelement.rs
index aa472bb04fc..da68e0c51bf 100644
--- a/src/components/script/dom/htmlunknownelement.rs
+++ b/src/components/script/dom/htmlunknownelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLUnknownElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLUnknownElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::document::Document;
use dom::element::HTMLUnknownElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -33,7 +33,7 @@ impl HTMLUnknownElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLUnknownElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLUnknownElement> {
let element = HTMLUnknownElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLUnknownElementBinding::Wrap)
}
diff --git a/src/components/script/dom/htmlvideoelement.rs b/src/components/script/dom/htmlvideoelement.rs
index 3587ab4931a..aba9c3c3436 100644
--- a/src/components/script/dom/htmlvideoelement.rs
+++ b/src/components/script/dom/htmlvideoelement.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::HTMLVideoElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLVideoElementDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::HTMLVideoElementTypeId;
@@ -34,7 +34,7 @@ impl HTMLVideoElement {
}
}
- pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLVideoElement> {
+ pub fn new(localName: DOMString, document: &JSRef<Document>) -> Unrooted<HTMLVideoElement> {
let element = HTMLVideoElement::new_inherited(localName, document.unrooted());
Node::reflect_node(~element, document, HTMLVideoElementBinding::Wrap)
}
diff --git a/src/components/script/dom/location.rs b/src/components/script/dom/location.rs
index fa0aaf103d7..762da0a383b 100644
--- a/src/components/script/dom/location.rs
+++ b/src/components/script/dom/location.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::LocationBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::window::Window;
@@ -29,7 +29,7 @@ impl Location {
}
}
- pub fn new(window: &JSRef<Window>, page: Rc<Page>) -> JS<Location> {
+ pub fn new(window: &JSRef<Window>, page: Rc<Page>) -> Unrooted<Location> {
reflect_dom_object(~Location::new_inherited(page),
window,
LocationBinding::Wrap)
diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs
index a1f08aa72e0..b771b1b091c 100644
--- a/src/components/script/dom/mouseevent.rs
+++ b/src/components/script/dom/mouseevent.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::MouseEventBinding;
use dom::bindings::codegen::InheritTypes::MouseEventDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference};
+use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted};
use dom::bindings::error::Fallible;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, MouseEventTypeId};
@@ -51,7 +51,7 @@ impl MouseEvent {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<MouseEvent> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<MouseEvent> {
reflect_dom_object(~MouseEvent::new_inherited(),
window,
MouseEventBinding::Wrap)
@@ -59,9 +59,9 @@ impl MouseEvent {
pub fn Constructor(owner: &JSRef<Window>,
type_: DOMString,
- init: &MouseEventBinding::MouseEventInit) -> Fallible<JS<MouseEvent>> {
+ init: &MouseEventBinding::MouseEventInit) -> Fallible<Unrooted<MouseEvent>> {
let roots = RootCollection::new();
- let mut ev = MouseEvent::new(owner);
+ let mut ev = MouseEvent::new(owner).root(&roots);
let view = init.view.as_ref().map(|view| view.root(&roots));
let related_target = init.relatedTarget.as_ref().map(|relatedTarget| relatedTarget.root(&roots));
ev.get_mut().InitMouseEvent(type_, init.bubbles, init.cancelable, view.root_ref(),
@@ -69,7 +69,7 @@ impl MouseEvent {
init.clientX, init.clientY, init.ctrlKey,
init.altKey, init.shiftKey, init.metaKey,
init.button, related_target.root_ref());
- Ok(ev)
+ Ok(Unrooted::new_rooted(&*ev))
}
pub fn ScreenX(&self) -> i32 {
@@ -113,8 +113,8 @@ impl MouseEvent {
0
}
- pub fn GetRelatedTarget(&self) -> Option<JS<EventTarget>> {
- self.related_target.clone()
+ pub fn GetRelatedTarget(&self) -> Option<Unrooted<EventTarget>> {
+ self.related_target.clone().map(|target| Unrooted::new(target))
}
pub fn GetModifierState(&self, _keyArg: DOMString) -> bool {
diff --git a/src/components/script/dom/navigator.rs b/src/components/script/dom/navigator.rs
index 63779428d94..494175cb6b8 100644
--- a/src/components/script/dom/navigator.rs
+++ b/src/components/script/dom/navigator.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::NavigatorBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::Fallible;
use dom::window::Window;
@@ -21,7 +21,7 @@ impl Navigator {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<Navigator> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<Navigator> {
reflect_dom_object(~Navigator::new_inherited(),
window,
NavigatorBinding::Wrap)
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index 4d40d8daeb7..6758efeb65d 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -10,7 +10,9 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived};
use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast};
use dom::bindings::codegen::BindingDeclarations::NodeBinding::NodeConstants;
-use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference};
+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::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::error::{ErrorResult, Fallible, NotFound, HierarchyRequest};
use dom::bindings::utils;
@@ -222,30 +224,19 @@ pub enum NodeTypeId {
ProcessingInstructionNodeTypeId,
}
-pub trait INode {
- fn AppendChild(&mut self, node: &mut JSRef<Node>) -> Fallible<JS<Node>>;
- fn ReplaceChild(&mut self, node: &mut JSRef<Node>, child: &mut JSRef<Node>) -> Fallible<JS<Node>>;
- fn RemoveChild(&mut self, node: &mut JSRef<Node>) -> Fallible<JS<Node>>;
+pub fn AppendChild<'a>(self_: &mut JSRef<'a, Node>, node: &mut JSRef<Node>) -> Fallible<Unrooted<Node>> {
+ let mut self_alias = self_.clone();
+ self_.get_mut().AppendChild(&mut self_alias, node)
}
-impl INode for JS<Node> {
- fn AppendChild(&mut self, node: &mut JSRef<Node>) -> Fallible<JS<Node>> {
- let roots = RootCollection::new();
- let self_node = self.root(&roots);
- self.get_mut().AppendChild(&mut self_node.root_ref(), node)
- }
-
- fn ReplaceChild(&mut self, node: &mut JSRef<Node>, child: &mut JSRef<Node>) -> Fallible<JS<Node>> {
- let roots = RootCollection::new();
- let self_node = self.root(&roots);
- self.get_mut().ReplaceChild(&mut self_node.root_ref(), node, child)
- }
+pub fn ReplaceChild<'a>(self_: &mut JSRef<'a, Node>, node: &mut JSRef<Node>, child: &mut JSRef<Node>) -> Fallible<Unrooted<Node>> {
+ let mut self_alias = self_.clone();
+ self_.get_mut().ReplaceChild(&mut self_alias, node, child)
+}
- fn RemoveChild(&mut self, node: &mut JSRef<Node>) -> Fallible<JS<Node>> {
- let roots = RootCollection::new();
- let self_node = self.root(&roots);
- self.get_mut().RemoveChild(&mut self_node.root_ref(), node)
- }
+pub fn RemoveChild<'a>(self_: &mut JSRef<'a, Node>, node: &mut JSRef<Node>) -> Fallible<Unrooted<Node>> {
+ let mut self_alias = self_.clone();
+ self_.get_mut().RemoveChild(&mut self_alias, node)
}
pub trait NodeHelpers {
@@ -259,11 +250,11 @@ pub trait NodeHelpers {
fn type_id(&self) -> NodeTypeId;
- fn parent_node(&self) -> Option<JS<Node>>;
- fn first_child(&self) -> Option<JS<Node>>;
- fn last_child(&self) -> Option<JS<Node>>;
- fn prev_sibling(&self) -> Option<JS<Node>>;
- fn next_sibling(&self) -> Option<JS<Node>>;
+ fn parent_node(&self) -> Option<Unrooted<Node>>;
+ fn first_child(&self) -> Option<Unrooted<Node>>;
+ fn last_child(&self) -> Option<Unrooted<Node>>;
+ fn prev_sibling(&self) -> Option<Unrooted<Node>>;
+ fn next_sibling(&self) -> Option<Unrooted<Node>>;
fn is_element(&self) -> bool;
fn is_document(&self) -> bool;
@@ -283,18 +274,17 @@ pub trait NodeHelpers {
fn dump_indent(&self, indent: uint);
fn debug_str(&self) -> ~str;
- fn traverse_preorder(&self) -> TreeIterator;
- fn sequential_traverse_postorder(&self) -> TreeIterator;
+ fn traverse_preorder<'a>(&self, roots: &'a RootCollection) -> TreeIterator<'a>;
+ fn sequential_traverse_postorder<'a>(&self, roots: &'a RootCollection) -> TreeIterator<'a>;
fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator;
- fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress) -> Self;
fn to_trusted_node_address(&self) -> TrustedNodeAddress;
fn get_bounding_content_box(&self) -> Rect<Au>;
fn get_content_boxes(&self) -> Vec<Rect<Au>>;
}
-impl NodeHelpers for JS<Node> {
+impl<'a> NodeHelpers for JSRef<'a, Node> {
/// Dumps the subtree rooted at this node, for debugging.
fn dump(&self) {
self.dump_indent(0);
@@ -343,26 +333,26 @@ impl NodeHelpers for JS<Node> {
self.get().type_id
}
- fn parent_node(&self) -> Option<JS<Node>> {
- self.get().parent_node.clone()
+ fn parent_node(&self) -> Option<Unrooted<Node>> {
+ self.get().parent_node.clone().map(|node| Unrooted::new(node))
}
- fn first_child(&self) -> Option<JS<Node>> {
- self.get().first_child.clone()
+ fn first_child(&self) -> Option<Unrooted<Node>> {
+ self.get().first_child.clone().map(|node| Unrooted::new(node))
}
- fn last_child(&self) -> Option<JS<Node>> {
- self.get().last_child.clone()
+ fn last_child(&self) -> Option<Unrooted<Node>> {
+ self.get().last_child.clone().map(|node| Unrooted::new(node))
}
/// Returns the previous sibling of this node. Fails if this node is borrowed mutably.
- fn prev_sibling(&self) -> Option<JS<Node>> {
- self.get().prev_sibling.clone()
+ fn prev_sibling(&self) -> Option<Unrooted<Node>> {
+ self.get().prev_sibling.clone().map(|node| Unrooted::new(node))
}
/// Returns the next sibling of this node. Fails if this node is borrowed mutably.
- fn next_sibling(&self) -> Option<JS<Node>> {
- self.get().next_sibling.clone()
+ fn next_sibling(&self) -> Option<Unrooted<Node>> {
+ self.get().next_sibling.clone().map(|node| Unrooted::new(node))
}
#[inline]
@@ -388,10 +378,7 @@ impl NodeHelpers for JS<Node> {
#[inline]
fn is_doctype(&self) -> bool {
- match self.type_id() {
- DoctypeNodeTypeId => true,
- _ => false
- }
+ self.get().is_doctype()
}
#[inline]
@@ -406,25 +393,28 @@ impl NodeHelpers for JS<Node> {
// http://dom.spec.whatwg.org/#node-is-inserted
fn node_inserted(&self) {
+ let roots = RootCollection::new();
assert!(self.parent_node().is_some());
- let document = document_from_node(self);
+ let document = document_from_node(self).root(&roots);
if self.is_in_doc() {
- for node in self.traverse_preorder() {
+ for node in self.traverse_preorder(&roots) {
vtable_for(&node).bind_to_tree();
}
}
- self.parent_node().map(|parent| vtable_for(&parent).child_inserted(self));
+ self.parent_node().root(&roots)
+ .map(|parent| vtable_for(&*parent).child_inserted(self));
document.get().content_changed();
}
// http://dom.spec.whatwg.org/#node-is-removed
fn node_removed(&self) {
+ let roots = RootCollection::new();
assert!(self.parent_node().is_none());
- let document = document_from_node(self);
+ let document = document_from_node(self).root(&roots);
- for node in self.traverse_preorder() {
+ for node in self.traverse_preorder(&roots) {
// XXX how about if the node wasn't in the tree in the first place?
vtable_for(&node).unbind_from_tree();
}
@@ -439,49 +429,45 @@ impl NodeHelpers for JS<Node> {
/// Adds a new child to the end of this node's list of children.
///
/// Fails unless `new_child` is disconnected from the tree.
- fn add_child(&mut self, new_child_root: &mut JSRef<Node>, before: Option<JSRef<Node>>) {
+ fn add_child(&mut self, new_child: &mut JSRef<Node>, mut before: Option<JSRef<Node>>) {
let roots = RootCollection::new();
- let mut new_child = new_child_root.unrooted();
assert!(new_child.parent_node().is_none());
assert!(new_child.prev_sibling().is_none());
assert!(new_child.next_sibling().is_none());
match before {
- Some(before_root) => {
- let mut before = before_root.unrooted();
+ Some(ref mut before) => {
// XXX Should assert that parent is self.
assert!(before.parent_node().is_some());
match before.prev_sibling() {
None => {
// XXX Should assert that before is the first child of
// self.
- self.get_mut().set_first_child(Some(new_child_root.clone()));
+ self.get_mut().set_first_child(Some(new_child.clone()));
},
- Some(mut prev_sibling) => {
- let prev_sibling_root = prev_sibling.root(&roots);
- prev_sibling.get_mut().set_next_sibling(Some(new_child_root.clone()));
- new_child.get_mut().set_prev_sibling(Some(prev_sibling_root.root_ref()));
+ Some(prev_sibling) => {
+ let mut prev_sibling = prev_sibling.root(&roots);
+ prev_sibling.get_mut().set_next_sibling(Some(new_child.clone()));
+ new_child.get_mut().set_prev_sibling(Some((*prev_sibling).clone()));
},
}
- before.get_mut().set_prev_sibling(Some(new_child_root.clone()));
- new_child.get_mut().set_next_sibling(Some(before_root.clone()));
+ before.get_mut().set_prev_sibling(Some(new_child.clone()));
+ new_child.get_mut().set_next_sibling(Some(before.clone()));
},
None => {
- match self.last_child() {
- None => self.get_mut().set_first_child(Some(new_child_root.clone())),
+ match self.last_child().map(|child| child.root(&roots)) {
+ None => self.get_mut().set_first_child(Some(new_child.clone())),
Some(mut last_child) => {
- let last_child_root = last_child.root(&roots);
assert!(last_child.next_sibling().is_none());
- last_child.get_mut().set_next_sibling(Some(new_child_root.clone()));
- new_child.get_mut().set_prev_sibling(Some(last_child_root.root_ref()));
+ last_child.get_mut().set_next_sibling(Some(new_child.clone()));
+ new_child.get_mut().set_prev_sibling(Some((*last_child).clone()));
}
}
- self.get_mut().set_last_child(Some(new_child_root.clone()));
+ self.get_mut().set_last_child(Some(new_child.clone()));
},
}
- let self_root = self.root(&roots);
- new_child.get_mut().set_parent_node(Some(self_root.root_ref()));
+ new_child.get_mut().set_parent_node(Some(self.clone()));
}
/// Removes the given child from this node's list of children.
@@ -531,69 +517,53 @@ impl NodeHelpers for JS<Node> {
}
/// Iterates over this node and all its descendants, in preorder.
- fn traverse_preorder(&self) -> TreeIterator {
- let roots = RootCollection::new();
+ fn traverse_preorder<'a>(&self, roots: &'a RootCollection) -> TreeIterator<'a> {
let mut nodes = vec!();
- let self_root = self.root(&roots);
- gather_abstract_nodes(&self_root.root_ref(), &mut nodes, false);
+ gather_abstract_nodes(self, roots, &mut nodes, false);
TreeIterator::new(nodes)
}
/// Iterates over this node and all its descendants, in postorder.
- fn sequential_traverse_postorder(&self) -> TreeIterator {
- let roots = RootCollection::new();
+ fn sequential_traverse_postorder<'a>(&self, roots: &'a RootCollection) -> TreeIterator<'a> {
let mut nodes = vec!();
- let self_root = self.root(&roots);
- gather_abstract_nodes(&self_root.root_ref(), &mut nodes, true);
+ gather_abstract_nodes(self, roots, &mut nodes, true);
TreeIterator::new(nodes)
}
fn inclusively_following_siblings(&self) -> AbstractNodeChildrenIterator {
+ let roots = RootCollection::new();
AbstractNodeChildrenIterator {
- current_node: Some(self.clone()),
+ current_node: Some((*self.unrooted().root(&roots)).clone()),
+ roots: roots,
}
}
fn is_inclusive_ancestor_of(&self, parent: &JSRef<Node>) -> bool {
- let parent = &parent.unrooted();
- self == parent || parent.ancestors().any(|ancestor| ancestor == *self)
+ self == parent || parent.ancestors().any(|ancestor| &ancestor == self)
}
fn following_siblings(&self) -> AbstractNodeChildrenIterator {
+ let roots = RootCollection::new();
AbstractNodeChildrenIterator {
- current_node: self.next_sibling(),
+ current_node: self.next_sibling().map(|node| (*node.root(&roots)).clone()),
+ roots: roots,
}
}
fn is_parent_of(&self, child: &JSRef<Node>) -> bool {
- match child.unrooted().parent_node() {
- Some(ref parent) if parent == self => true,
+ match child.parent_node() {
+ Some(ref parent) if *parent == Unrooted::new_rooted(self) => true,
_ => false
}
}
- /// If the given untrusted node address represents a valid DOM node in the given runtime,
- /// returns it.
- fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress)
- -> JS<Node> {
- unsafe {
- let candidate: uintptr_t = cast::transmute(candidate);
- let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime,
- candidate);
- if object.is_null() {
- fail!("Attempted to create a `JS<Node>` from an invalid pointer!")
- }
- let boxed_node: *mut Node = utils::unwrap(object);
- JS::from_raw(boxed_node)
- }
- }
-
fn to_trusted_node_address(&self) -> TrustedNodeAddress {
TrustedNodeAddress(self.get() as *Node as *libc::c_void)
}
fn get_bounding_content_box(&self) -> Rect<Au> {
- let window = window_from_node(self);
+ let roots = RootCollection::new();
+ let window = window_from_node(self).root(&roots);
let page = window.get().page();
let (chan, port) = channel();
let addr = self.to_trusted_node_address();
@@ -602,7 +572,8 @@ impl NodeHelpers for JS<Node> {
}
fn get_content_boxes(&self) -> Vec<Rect<Au>> {
- let window = window_from_node(self);
+ let roots = RootCollection::new();
+ let window = window_from_node(self).root(&roots);
let page = window.get().page();
let (chan, port) = channel();
let addr = self.to_trusted_node_address();
@@ -611,54 +582,86 @@ impl NodeHelpers for JS<Node> {
}
}
+/// If the given untrusted node address represents a valid DOM node in the given runtime,
+/// returns it.
+pub fn from_untrusted_node_address(runtime: *JSRuntime, candidate: UntrustedNodeAddress)
+ -> Unrooted<Node> {
+ unsafe {
+ let candidate: uintptr_t = cast::transmute(candidate);
+ let object: *JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime,
+ candidate);
+ if object.is_null() {
+ fail!("Attempted to create a `JS<Node>` from an invalid pointer!")
+ }
+ let boxed_node: *mut Node = utils::unwrap(object);
+ Unrooted::new(JS::from_raw(boxed_node))
+ }
+}
+
+pub trait LayoutNodeHelpers {
+ fn type_id_for_layout(&self) -> NodeTypeId;
+}
+
+impl LayoutNodeHelpers for JS<Node> {
+ fn type_id_for_layout(&self) -> NodeTypeId {
+ unsafe {
+ let node: **Node = cast::transmute::<*JS<Node>,
+ **Node>(self);
+ (**node).type_id
+ }
+ }
+}
+
//
// Iteration and traversal
//
-pub type ChildElementIterator<'a> = Map<'a, JS<Node>,
- JS<Element>,
- Filter<'a, JS<Node>, AbstractNodeChildrenIterator>>;
+pub type ChildElementIterator<'a, 'b> = Map<'a, JSRef<'b, Node>,
+ JSRef<'b, Element>,
+ Filter<'a, JSRef<'b, Node>, AbstractNodeChildrenIterator<'b>>>;
-pub struct AbstractNodeChildrenIterator {
- current_node: Option<JS<Node>>,
+pub struct AbstractNodeChildrenIterator<'a> {
+ current_node: Option<JSRef<'a, Node>>,
+ roots: RootCollection,
}
-impl Iterator<JS<Node>> for AbstractNodeChildrenIterator {
- fn next(&mut self) -> Option<JS<Node>> {
+impl<'a> Iterator<JSRef<'a, Node>> for AbstractNodeChildrenIterator<'a> {
+ fn next(&mut self) -> Option<JSRef<'a, Node>> {
let node = self.current_node.clone();
self.current_node = node.clone().and_then(|node| {
- node.next_sibling()
+ node.next_sibling().map(|node| (*node.root(&self.roots)).clone())
});
node
}
}
-pub struct AncestorIterator {
- current: Option<JS<Node>>,
+pub struct AncestorIterator<'a> {
+ current: Option<JSRef<'a, Node>>,
+ roots: RootCollection,
}
-impl Iterator<JS<Node>> for AncestorIterator {
- fn next(&mut self) -> Option<JS<Node>> {
+impl<'a> Iterator<JSRef<'a, Node>> for AncestorIterator<'a> {
+ fn next(&mut self) -> Option<JSRef<'a, Node>> {
if self.current.is_none() {
return None;
}
// FIXME: Do we need two clones here?
let x = self.current.get_ref().clone();
- self.current = x.parent_node();
- Some(x.clone())
+ self.current = x.parent_node().map(|node| (*node.root(&self.roots)).clone());
+ Some(x)
}
}
// FIXME: Do this without precomputing a vector of refs.
// Easy for preorder; harder for postorder.
-pub struct TreeIterator {
- nodes: Vec<JS<Node>>,
+pub struct TreeIterator<'a> {
+ nodes: Vec<JSRef<'a, Node>>,
index: uint,
}
-impl TreeIterator {
- fn new(nodes: Vec<JS<Node>>) -> TreeIterator {
+impl<'a> TreeIterator<'a> {
+ fn new(nodes: Vec<JSRef<'a, Node>>) -> TreeIterator<'a> {
TreeIterator {
nodes: nodes,
index: 0,
@@ -666,8 +669,8 @@ impl TreeIterator {
}
}
-impl Iterator<JS<Node>> for TreeIterator {
- fn next(&mut self) -> Option<JS<Node>> {
+impl<'a> Iterator<JSRef<'a, Node>> for TreeIterator<'a> {
+ fn next(&mut self) -> Option<JSRef<'a, Node>> {
if self.index >= self.nodes.len() {
None
} else {
@@ -678,7 +681,8 @@ impl Iterator<JS<Node>> for TreeIterator {
}
}
-pub struct NodeIterator {
+pub struct NodeIterator<'a> {
+ roots: &'a RootCollection,
pub start_node: JS<Node>,
pub current_node: Option<JS<Node>>,
pub depth: uint,
@@ -686,10 +690,14 @@ pub struct NodeIterator {
include_descendants_of_void: bool
}
-impl NodeIterator {
- pub fn new(start_node: JS<Node>, include_start: bool, include_descendants_of_void: bool) -> NodeIterator {
+impl<'a> NodeIterator<'a> {
+ pub fn new<'a, 'b>(roots: &'a RootCollection,
+ start_node: &JSRef<'b, Node>,
+ include_start: bool,
+ include_descendants_of_void: bool) -> NodeIterator<'a> {
NodeIterator {
- start_node: start_node,
+ roots: roots,
+ start_node: start_node.unrooted(),
current_node: None,
depth: 0,
include_start: include_start,
@@ -697,54 +705,54 @@ impl NodeIterator {
}
}
- fn next_child(&self, node: &JSRef<Node>) -> Option<JS<Node>> {
+ fn next_child<'b>(&self, node: &JSRef<'b, Node>) -> Option<JSRef<Node>> {
if !self.include_descendants_of_void && node.get().is_element() {
- let elem: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
+ let elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
if elem.get().is_void() {
None
} else {
- node.get().first_child.clone()
+ node.first_child().map(|child| (*child.root(self.roots)).clone())
}
} else {
- node.get().first_child.clone()
+ node.first_child().map(|child| (*child.root(self.roots)).clone())
}
}
}
-impl Iterator<JS<Node>> for NodeIterator {
- fn next(&mut self) -> Option<JS<Node>> {
- let roots = RootCollection::new();
- self.current_node = match self.current_node {
+impl<'a, 'b> Iterator<JSRef<'b, Node>> for NodeIterator<'a> {
+ fn next(&mut self) -> Option<JSRef<Node>> {
+ self.current_node = match self.current_node.as_ref().map(|node| node.root(self.roots)) {
None => {
if self.include_start {
Some(self.start_node.clone())
} else {
- let start_node = self.start_node.root(&roots);
- self.next_child(&start_node.root_ref())
+ self.next_child(&*self.start_node.root(self.roots))
+ .map(|child| child.unrooted())
}
},
- Some(ref node) => {
- let node_root = node.root(&roots);
- match self.next_child(&node_root.root_ref()) {
+ Some(node) => {
+ match self.next_child(&*node) {
Some(child) => {
self.depth += 1;
- Some(child.clone())
+ Some(child.unrooted())
},
- None if node == &self.start_node => None,
+ None if node.deref().unrooted() == self.start_node => None,
None => {
- match node.next_sibling() {
- Some(sibling) => Some(sibling),
+ match node.deref().next_sibling().root(self.roots) {
+ Some(sibling) => Some(sibling.deref().unrooted()),
None => {
- let mut candidate = node.clone();
+ let mut candidate = node.deref().clone();
while candidate.next_sibling().is_none() {
- candidate = candidate.parent_node().expect("Got to root without reaching start node");
+ candidate = (*candidate.parent_node()
+ .expect("Got to root without reaching start node")
+ .root(self.roots)).clone();
self.depth -= 1;
- if candidate == self.start_node {
+ if candidate.unrooted() == self.start_node {
break;
}
}
- if candidate != self.start_node {
- candidate.next_sibling()
+ if candidate.unrooted() != self.start_node {
+ candidate.next_sibling().map(|node| node.root(self.roots).unrooted())
} else {
None
}
@@ -754,21 +762,19 @@ impl Iterator<JS<Node>> for NodeIterator {
}
}
};
- self.current_node.clone()
+ self.current_node.clone().map(|node| (*node.root(self.roots)).clone())
}
}
-fn gather_abstract_nodes(cur: &JSRef<Node>, refs: &mut Vec<JS<Node>>, postorder: bool) {
- let roots = RootCollection::new();
+fn gather_abstract_nodes<'a>(cur: &JSRef<Node>, roots: &'a RootCollection, refs: &mut Vec<JSRef<Node>>, postorder: bool) {
if !postorder {
- refs.push(cur.unrooted());
+ refs.push((*cur.unrooted().root(roots)).clone());
}
- for kid in cur.unrooted().children() {
- let kid = kid.root(&roots);
- gather_abstract_nodes(&kid.root_ref(), refs, postorder)
+ for kid in cur.children() {
+ gather_abstract_nodes(&kid, roots, refs, postorder)
}
if postorder {
- refs.push(cur.unrooted());
+ refs.push((*cur.unrooted().root(roots)).clone());
}
}
@@ -783,8 +789,10 @@ fn as_uintptr<T>(t: &T) -> uintptr_t { t as *T as uintptr_t }
impl Node {
pub fn ancestors(&self) -> AncestorIterator {
+ let roots = RootCollection::new();
AncestorIterator {
- current: self.parent_node.clone(),
+ current: self.parent_node.clone().map(|node| (*node.root(&roots)).clone()),
+ roots: roots,
}
}
@@ -795,7 +803,18 @@ impl Node {
}
}
- pub fn owner_doc<'a>(&'a self) -> &'a JS<Document> {
+ pub fn is_doctype(&self) -> bool {
+ match self.type_id {
+ DoctypeNodeTypeId => true,
+ _ => false
+ }
+ }
+
+ pub fn owner_doc(&self) -> Unrooted<Document> {
+ Unrooted::new(self.owner_doc.get_ref().clone())
+ }
+
+ pub fn owner_doc_for_layout<'a>(&'a self) -> &'a JS<Document> {
self.owner_doc.get_ref()
}
@@ -804,17 +823,21 @@ impl Node {
}
pub fn children(&self) -> AbstractNodeChildrenIterator {
+ let roots = RootCollection::new();
AbstractNodeChildrenIterator {
- current_node: self.first_child.clone(),
+ current_node: self.first_child.clone().map(|node| (*node.root(&roots)).clone()),
+ roots: roots,
}
}
pub fn child_elements(&self) -> ChildElementIterator {
self.children()
- .filter(|node| node.is_element())
+ .filter(|node| {
+ node.is_element()
+ })
.map(|node| {
- let elem: JS<Element> = ElementCast::to(&node).unwrap();
- elem
+ let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap();
+ elem.clone()
})
}
@@ -822,13 +845,13 @@ impl Node {
(node: ~N,
document: &JSRef<Document>,
wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~N) -> JS<N>)
- -> JS<N> {
+ -> Unrooted<N> {
let roots = RootCollection::new();
assert!(node.reflector().get_jsobject().is_null());
let window = document.get().window.root(&roots);
- let node = reflect_dom_object(node, &window.root_ref(), wrap_fn);
+ let node = reflect_dom_object(node, &window.root_ref(), wrap_fn).root(&roots);
assert!(node.reflector().get_jsobject().is_not_null());
- node
+ Unrooted::new_rooted(&*node)
}
pub fn new_inherited(type_id: NodeTypeId, doc: JS<Document>) -> Node {
@@ -919,26 +942,33 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-ownerdocument
- pub fn GetOwnerDocument(&self) -> Option<JS<Document>> {
+ pub fn GetOwnerDocument(&self) -> Option<Unrooted<Document>> {
match self.type_id {
ElementNodeTypeId(..) |
CommentNodeTypeId |
TextNodeTypeId |
ProcessingInstructionNodeTypeId |
DoctypeNodeTypeId |
- DocumentFragmentNodeTypeId => Some(self.owner_doc().clone()),
+ DocumentFragmentNodeTypeId => Some(self.owner_doc()),
DocumentNodeTypeId => None
}
}
// http://dom.spec.whatwg.org/#dom-node-parentnode
- pub fn GetParentNode(&self) -> Option<JS<Node>> {
- self.parent_node.clone()
+ pub fn GetParentNode(&self) -> Option<Unrooted<Node>> {
+ self.parent_node.clone().map(|node| Unrooted::new(node))
}
// http://dom.spec.whatwg.org/#dom-node-parentelement
- pub fn GetParentElement(&self) -> Option<JS<Element>> {
- self.parent_node.clone().and_then(|parent| ElementCast::to(&parent))
+ pub fn GetParentElement(&self) -> Option<Unrooted<Element>> {
+ let roots = RootCollection::new();
+ self.parent_node.clone()
+ .and_then(|parent| {
+ let parent = parent.root(&roots);
+ ElementCast::to_ref(&*parent).map(|elem| {
+ Unrooted::new_rooted(elem)
+ })
+ })
}
// http://dom.spec.whatwg.org/#dom-node-haschildnodes
@@ -947,39 +977,37 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-childnodes
- pub fn ChildNodes(&mut self, abstract_self: &JSRef<Node>) -> JS<NodeList> {
+ pub fn ChildNodes(&mut self, abstract_self: &JSRef<Node>) -> Unrooted<NodeList> {
let roots = RootCollection::new();
match self.child_list {
None => {
- let doc = self.owner_doc().clone();
- let doc = doc.get();
- let window = doc.window.root(&roots);
- let list = NodeList::new_child_list(&window.root_ref(), abstract_self);
- self.child_list = Some(list.clone());
- list
+ let doc = self.owner_doc().root(&roots);
+ let window = doc.deref().window.root(&roots);
+ self.child_list.assign(Some(NodeList::new_child_list(&*window, abstract_self)));
+ Unrooted::new(self.child_list.get_ref().clone())
}
- Some(ref list) => list.clone()
+ Some(ref list) => Unrooted::new(list.clone())
}
}
// http://dom.spec.whatwg.org/#dom-node-firstchild
- pub fn GetFirstChild(&self) -> Option<JS<Node>> {
- self.first_child.clone()
+ pub fn GetFirstChild(&self) -> Option<Unrooted<Node>> {
+ self.first_child.clone().map(|node| Unrooted::new(node))
}
// http://dom.spec.whatwg.org/#dom-node-lastchild
- pub fn GetLastChild(&self) -> Option<JS<Node>> {
- self.last_child.clone()
+ pub fn GetLastChild(&self) -> Option<Unrooted<Node>> {
+ self.last_child.clone().map(|node| Unrooted::new(node))
}
// http://dom.spec.whatwg.org/#dom-node-previoussibling
- pub fn GetPreviousSibling(&self) -> Option<JS<Node>> {
- self.prev_sibling.clone()
+ pub fn GetPreviousSibling(&self) -> Option<Unrooted<Node>> {
+ self.prev_sibling.clone().map(|node| Unrooted::new(node))
}
// http://dom.spec.whatwg.org/#dom-node-nextsibling
- pub fn GetNextSibling(&self) -> Option<JS<Node>> {
- self.next_sibling.clone()
+ pub fn GetNextSibling(&self) -> Option<Unrooted<Node>> {
+ self.next_sibling.clone().map(|node| Unrooted::new(node))
}
// http://dom.spec.whatwg.org/#dom-node-nodevalue
@@ -1012,13 +1040,14 @@ impl Node {
// http://dom.spec.whatwg.org/#dom-node-textcontent
pub fn GetTextContent(&self, abstract_self: &JSRef<Node>) -> Option<DOMString> {
+ let roots = RootCollection::new();
match self.type_id {
DocumentFragmentNodeTypeId |
ElementNodeTypeId(..) => {
let mut content = ~"";
- for node in abstract_self.unrooted().traverse_preorder() {
+ for node in abstract_self.traverse_preorder(&roots) {
if node.is_text() {
- let text: JS<Text> = TextCast::to(&node).unwrap();
+ let text: &JSRef<Text> = TextCast::to_ref(&node).unwrap();
content.push_str(text.get().characterdata.data.as_slice());
}
}
@@ -1027,7 +1056,7 @@ impl Node {
CommentNodeTypeId |
TextNodeTypeId |
ProcessingInstructionNodeTypeId => {
- let characterdata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap();
+ let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(abstract_self).unwrap();
Some(characterdata.get().Data())
}
DoctypeNodeTypeId |
@@ -1051,9 +1080,8 @@ impl Node {
} else {
let document = self.owner_doc();
let document = document.root(&roots);
- Some(NodeCast::from(&document.get().CreateTextNode(&document.root_ref(), value)))
- };
- let node = node.map(|node| node.root(&roots));
+ Some(NodeCast::from_unrooted(document.deref().CreateTextNode(&*document, value)))
+ }.root(&roots);
// Step 3.
Node::replace_all(node.root_ref(), abstract_self);
@@ -1067,7 +1095,7 @@ impl Node {
characterdata.get_mut().data = value.clone();
// Notify the document that the content of this node is different
- let document = self.owner_doc();
+ let document = self.owner_doc().root(&roots);
document.get().content_changed();
}
DoctypeNodeTypeId |
@@ -1077,21 +1105,20 @@ impl Node {
}
// http://dom.spec.whatwg.org/#concept-node-adopt
- pub fn adopt(node_root: &mut JSRef<Node>, document: &JSRef<Document>) {
+ pub fn adopt(node: &mut JSRef<Node>, document: &JSRef<Document>) {
let roots = RootCollection::new();
- let node = node_root.unrooted();
// Step 1.
- match node.parent_node() {
- Some(ref mut parent) => {
- let parent = parent.root(&roots);
- Node::remove(node_root, &mut parent.root_ref(), Unsuppressed);
+ match node.parent_node().root(&roots) {
+ Some(mut parent) => {
+ Node::remove(node, &mut *parent, Unsuppressed);
}
None => (),
}
// Step 2.
- if document_from_node(&node) != document.unrooted() {
- for mut descendant in node.traverse_preorder() {
+ let node_doc = document_from_node(node).root(&roots);
+ if &*node_doc != document {
+ for mut descendant in node.traverse_preorder(&roots) {
descendant.get_mut().set_owner_doc(document);
}
}
@@ -1101,11 +1128,9 @@ impl Node {
}
// http://dom.spec.whatwg.org/#concept-node-pre-insert
- fn pre_insert(node_root: &mut JSRef<Node>, parent_root: &mut JSRef<Node>, child: Option<JSRef<Node>>)
- -> Fallible<JS<Node>> {
+ fn pre_insert(node: &mut JSRef<Node>, parent: &mut JSRef<Node>, child: Option<JSRef<Node>>)
+ -> Fallible<Unrooted<Node>> {
let roots = RootCollection::new();
- let node = node_root.unrooted();
- let parent = parent_root.unrooted();
// Step 1.
match parent.type_id() {
DocumentNodeTypeId |
@@ -1115,7 +1140,7 @@ impl Node {
}
// Step 2.
- if node.is_inclusive_ancestor_of(parent_root) {
+ if node.is_inclusive_ancestor_of(parent) {
return Err(HierarchyRequest);
}
@@ -1128,13 +1153,13 @@ impl Node {
// Step 4-5.
match node.type_id() {
TextNodeTypeId => {
- match node.parent_node() {
+ match node.parent_node().root(&roots) {
Some(ref parent) if parent.is_document() => return Err(HierarchyRequest),
_ => ()
}
}
DoctypeNodeTypeId => {
- match node.parent_node() {
+ match node.parent_node().root(&roots) {
Some(ref parent) if !parent.is_document() => return Err(HierarchyRequest),
_ => ()
}
@@ -1147,7 +1172,6 @@ impl Node {
}
// Step 6.
- let child = child.map(|child| child.unrooted());
match parent.type_id() {
DocumentNodeTypeId => {
match node.type_id() {
@@ -1168,7 +1192,7 @@ impl Node {
}
match child {
Some(ref child) if child.inclusively_following_siblings()
- .any(|child| child.is_doctype()) => {
+ .any(|child| child.deref().is_doctype()) => {
return Err(HierarchyRequest);
}
_ => (),
@@ -1187,7 +1211,7 @@ impl Node {
}
match child {
Some(ref child) if child.inclusively_following_siblings()
- .any(|child| child.is_doctype()) => {
+ .any(|child| child.deref().is_doctype()) => {
return Err(HierarchyRequest);
}
_ => (),
@@ -1195,14 +1219,14 @@ impl Node {
},
// Step 6.3
DoctypeNodeTypeId => {
- if parent.children().any(|c| c.is_doctype()) {
+ if parent.children().any(|c| c.deref().is_doctype()) {
return Err(HierarchyRequest);
}
match child {
Some(ref child) => {
if parent.children()
.take_while(|c| c != child)
- .any(|c| c.is_element()) {
+ .any(|c| c.deref().is_element()) {
return Err(HierarchyRequest);
}
},
@@ -1226,31 +1250,26 @@ impl Node {
// Step 7-8.
let referenceChild = match child {
- Some(ref child) if child == &node => node.next_sibling(),
+ Some(ref child) if child == node => node.next_sibling().map(|node| (*node.root(&roots)).clone()),
_ => child
};
- let referenceChild = referenceChild.map(|child| child.root(&roots));
// Step 9.
- let document = document_from_node(&parent);
- let document = document.root(&roots);
- Node::adopt(node_root, &document.root_ref());
+ let document = document_from_node(parent).root(&roots);
+ Node::adopt(node, &*document);
// Step 10.
- Node::insert(node_root, parent_root, referenceChild.root_ref(), Unsuppressed);
+ Node::insert(node, parent, referenceChild, Unsuppressed);
// Step 11.
- return Ok(node)
+ return Ok(Unrooted::new_rooted(node))
}
// http://dom.spec.whatwg.org/#concept-node-insert
- fn insert(node_root: &mut JSRef<Node>,
- parent_root: &mut JSRef<Node>,
+ fn insert(node: &mut JSRef<Node>,
+ parent: &mut JSRef<Node>,
child: Option<JSRef<Node>>,
suppress_observers: SuppressObserver) {
- let roots = RootCollection::new();
- let node = node_root.unrooted();
- let mut parent = parent_root.unrooted();
// XXX assert owner_doc
// Step 1-3: ranges.
// Step 4.
@@ -1263,9 +1282,8 @@ impl Node {
// Step 6: DocumentFragment.
match node.type_id() {
DocumentFragmentNodeTypeId => {
- for c in node.children() {
- let c = c.root(&roots);
- Node::remove(&mut c.root_ref(), node_root, Suppressed);
+ for mut c in node.children() {
+ Node::remove(&mut c, node, Suppressed);
}
},
_ => (),
@@ -1274,7 +1292,7 @@ impl Node {
// Step 7: mutation records.
// Step 8.
for node in nodes.mut_iter() {
- parent.add_child(node_root, child.clone());
+ parent.add_child(node, child.clone());
node.get_mut().flags.set_is_in_doc(parent.is_in_doc());
}
@@ -1290,23 +1308,20 @@ impl Node {
}
// http://dom.spec.whatwg.org/#concept-node-replace-all
- pub fn replace_all(mut node_root: Option<JSRef<Node>>, parent_root: &mut JSRef<Node>) {
+ pub fn replace_all(mut node: Option<JSRef<Node>>, parent: &mut JSRef<Node>) {
let roots = RootCollection::new();
- let node = node_root.as_ref().map(|node| node.unrooted());
- let parent = parent_root.unrooted();
// Step 1.
- match node_root {
+ match node {
Some(ref mut node) => {
- let document = document_from_node(&parent);
- let document = document.root(&roots);
- Node::adopt(node, &document.root_ref());
+ let document = document_from_node(parent).root(&roots);
+ Node::adopt(node, &*document);
}
None => (),
}
// Step 2.
- let removedNodes: Vec<JS<Node>> = parent.children().collect();
+ let removedNodes: Vec<JSRef<Node>> = parent.children().collect();
// Step 3.
let addedNodes = match node {
@@ -1318,14 +1333,13 @@ impl Node {
};
// Step 4.
- for child in parent.children() {
- let child = child.root(&roots);
- Node::remove(&mut child.root_ref(), parent_root, Suppressed);
+ for mut child in parent.children() {
+ Node::remove(&mut child, parent, Suppressed);
}
// Step 5.
- match node_root {
- Some(ref mut node) => Node::insert(node, parent_root, None, Suppressed),
+ match node {
+ Some(ref mut node) => Node::insert(node, parent, None, Suppressed),
None => (),
}
@@ -1341,10 +1355,10 @@ impl Node {
}
// http://dom.spec.whatwg.org/#concept-node-pre-remove
- fn pre_remove(child: &mut JSRef<Node>, parent: &mut JSRef<Node>) -> Fallible<JS<Node>> {
+ fn pre_remove(child: &mut JSRef<Node>, parent: &mut JSRef<Node>) -> Fallible<Unrooted<Node>> {
// Step 1.
- match child.unrooted().parent_node() {
- Some(ref node) if node != &parent.unrooted() => return Err(NotFound),
+ match child.parent_node() {
+ Some(ref node) if *node != Unrooted::new_rooted(parent) => return Err(NotFound),
_ => ()
}
@@ -1352,19 +1366,17 @@ impl Node {
Node::remove(child, parent, Unsuppressed);
// Step 3.
- Ok(child.unrooted())
+ Ok(Unrooted::new_rooted(child))
}
// http://dom.spec.whatwg.org/#concept-node-remove
- fn remove(node_root: &mut JSRef<Node>, parent: &mut JSRef<Node>, suppress_observers: SuppressObserver) {
- let mut parent = parent.unrooted();
- let mut node = node_root.unrooted();
- assert!(node.parent_node().map_or(false, |ref node_parent| node_parent == &parent));
+ fn remove(node: &mut JSRef<Node>, parent: &mut JSRef<Node>, suppress_observers: SuppressObserver) {
+ assert!(node.parent_node().map_or(false, |node_parent| node_parent == Unrooted::new_rooted(parent)));
// Step 1-5: ranges.
// Step 6-7: mutation observers.
// Step 8.
- parent.remove_child(node_root);
+ parent.remove_child(node);
node.get_mut().flags.set_is_in_doc(false);
// Step 9.
@@ -1376,94 +1388,95 @@ impl Node {
// http://dom.spec.whatwg.org/#concept-node-clone
pub fn clone(node: &JSRef<Node>, maybe_doc: Option<&JSRef<Document>>,
- clone_children: CloneChildrenFlag) -> JS<Node> {
+ clone_children: CloneChildrenFlag) -> Unrooted<Node> {
let roots = RootCollection::new();
// Step 1.
let mut document = match maybe_doc {
- Some(doc) => doc.unrooted(),
- None => node.get().owner_doc().clone()
+ Some(doc) => doc.unrooted().root(&roots),
+ None => node.get().owner_doc().root(&roots)
};
- let document_root = document.root(&roots);
// Step 2.
// XXXabinader: clone() for each node as trait?
- let copy: JS<Node> = match node.get().type_id {
+ let mut copy: Root<Node> = match node.type_id() {
DoctypeNodeTypeId => {
- let doctype: JS<DocumentType> = DocumentTypeCast::to(&node.unrooted()).unwrap();
+ let doctype: &JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap();
let doctype = doctype.get();
let doctype = DocumentType::new(doctype.name.clone(),
Some(doctype.public_id.clone()),
- Some(doctype.system_id.clone()), &document_root.root_ref());
- NodeCast::from(&doctype)
+ Some(doctype.system_id.clone()), &*document);
+ NodeCast::from_unrooted(doctype)
},
DocumentFragmentNodeTypeId => {
- let doc_fragment = DocumentFragment::new(&document_root.root_ref());
- NodeCast::from(&doc_fragment)
+ let doc_fragment = DocumentFragment::new(&*document);
+ NodeCast::from_unrooted(doc_fragment)
},
CommentNodeTypeId => {
- let comment: JS<Comment> = CommentCast::to(&node.unrooted()).unwrap();
+ let comment: &JSRef<Comment> = CommentCast::to_ref(node).unwrap();
let comment = comment.get();
- let comment = Comment::new(comment.characterdata.data.clone(), &document_root.root_ref());
- NodeCast::from(&comment)
+ let comment = Comment::new(comment.characterdata.data.clone(), &*document);
+ NodeCast::from_unrooted(comment)
},
DocumentNodeTypeId => {
- let document: JS<Document> = DocumentCast::to(&node.unrooted()).unwrap();
+ let document: &JSRef<Document> = DocumentCast::to_ref(node).unwrap();
let document = document.get();
let is_html_doc = match document.is_html_document {
true => HTMLDocument,
false => NonHTMLDocument
};
let window = document.window.root(&roots);
- let document = Document::new(&window.root_ref(), Some(document.url().clone()),
+ let document = Document::new(&*window, Some(document.url().clone()),
is_html_doc, None);
- NodeCast::from(&document)
+ NodeCast::from_unrooted(document)
},
ElementNodeTypeId(..) => {
- let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
+ let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
let element = element.get();
- let element = build_element_from_tag(element.local_name.clone(), &document_root.root_ref());
- NodeCast::from(&element)
+ let element = build_element_from_tag(element.local_name.clone(), &*document);
+ NodeCast::from_unrooted(element)
},
TextNodeTypeId => {
- let text: JS<Text> = TextCast::to(&node.unrooted()).unwrap();
+ let text: &JSRef<Text> = TextCast::to_ref(node).unwrap();
let text = text.get();
- let text = Text::new(text.characterdata.data.clone(), &document_root.root_ref());
- NodeCast::from(&text)
+ let text = Text::new(text.characterdata.data.clone(), &*document);
+ NodeCast::from_unrooted(text)
},
ProcessingInstructionNodeTypeId => {
- let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node.unrooted()).unwrap();
+ let pi: &JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap();
let pi = pi.get();
let pi = ProcessingInstruction::new(pi.target.clone(),
- pi.characterdata.data.clone(), &document_root.root_ref());
- NodeCast::from(&pi)
+ pi.characterdata.data.clone(), &*document);
+ NodeCast::from_unrooted(pi)
},
- };
+ }.root(&roots);
// Step 3.
- if copy.is_document() {
- document = DocumentCast::to(&copy).unwrap();
- }
- let document_root = document.root(&roots);
- assert!(copy.get().owner_doc() == &document);
+ let document = if copy.is_document() {
+ let doc: &JSRef<Document> = DocumentCast::to_ref(&*copy).unwrap();
+ doc.unrooted().root(&roots)
+ } else {
+ document.unrooted().root(&roots)
+ };
+ assert!(&*copy.get().owner_doc().root(&roots) == &*document);
// Step 4 (some data already copied in step 2).
match node.get().type_id {
DocumentNodeTypeId => {
- let node_doc: JS<Document> = DocumentCast::to(&node.unrooted()).unwrap();
+ let node_doc: &JSRef<Document> = DocumentCast::to_ref(node).unwrap();
let node_doc = node_doc.get();
- let mut copy_doc: JS<Document> = DocumentCast::to(&copy).unwrap();
+ let copy_doc: &mut JSRef<Document> = DocumentCast::to_mut_ref(&mut *copy).unwrap();
let copy_doc = copy_doc.get_mut();
copy_doc.set_encoding_name(node_doc.encoding_name.clone());
copy_doc.set_quirks_mode(node_doc.quirks_mode());
},
ElementNodeTypeId(..) => {
- let node_elem: JS<Element> = ElementCast::to(&node.unrooted()).unwrap();
+ let node_elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
let node_elem = node_elem.get();
- let mut copy_elem: JS<Element> = ElementCast::to(&copy).unwrap();
+ let copy_elem: &mut JSRef<Element> = ElementCast::to_mut_ref(&mut *copy).unwrap();
// XXX: to avoid double borrowing compile error. we might be able to fix this after #1854
- let copy_elem_alias: JS<Element> = copy_elem.clone();
+ let copy_elem_alias = copy_elem.clone();
let copy_elem = copy_elem.get_mut();
// FIXME: https://github.com/mozilla/servo/issues/1737
@@ -1471,10 +1484,11 @@ impl Node {
let window = document.get().window.root(&roots);
for attr in node_elem.attrs.iter() {
let attr = attr.get();
- copy_elem.attrs.push(Attr::new(&window.root_ref(),
- attr.local_name.clone(), attr.value.clone(),
- attr.name.clone(), attr.namespace.clone(),
- attr.prefix.clone(), copy_elem_alias.clone()));
+ 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));
}
},
_ => ()
@@ -1485,41 +1499,37 @@ impl Node {
// Step 6.
if clone_children == CloneChildren {
for ref child in node.get().children() {
- let child = child.root(&roots);
- let child_copy = Node::clone(&child.root_ref(), Some(&document_root.root_ref()), clone_children).root(&roots);
- let copy = copy.root(&roots);
- let _inserted_node = Node::pre_insert(&mut child_copy.root_ref(), &mut copy.root_ref(), None);
+ let mut child_copy = Node::clone(&*child, Some(&*document), clone_children).root(&roots);
+ let _inserted_node = Node::pre_insert(&mut *child_copy, &mut *copy, None);
}
}
// Step 7.
- copy
+ Unrooted::new_rooted(&*copy)
}
// http://dom.spec.whatwg.org/#dom-node-insertbefore
pub fn InsertBefore(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>, child: Option<JSRef<Node>>)
- -> Fallible<JS<Node>> {
+ -> Fallible<Unrooted<Node>> {
Node::pre_insert(node, abstract_self, child)
}
pub fn wait_until_safe_to_modify_dom(&self) {
- let document = self.owner_doc();
+ let roots = RootCollection::new();
+ let document = self.owner_doc().root(&roots);
document.get().wait_until_safe_to_modify_dom();
}
// http://dom.spec.whatwg.org/#dom-node-appendchild
pub fn AppendChild(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>)
- -> Fallible<JS<Node>> {
+ -> Fallible<Unrooted<Node>> {
Node::pre_insert(node, abstract_self, None)
}
// http://dom.spec.whatwg.org/#concept-node-replace
- pub fn ReplaceChild(&self, parent_root: &mut JSRef<Node>, node_root: &mut JSRef<Node>, child_root: &mut JSRef<Node>)
- -> Fallible<JS<Node>> {
+ pub fn ReplaceChild(&self, parent: &mut JSRef<Node>, node: &mut JSRef<Node>, child: &mut JSRef<Node>)
+ -> Fallible<Unrooted<Node>> {
let roots = RootCollection::new();
- let parent = parent_root.unrooted();
- let node = node_root.unrooted();
- let child = child_root.unrooted();
// Step 1.
match parent.type_id() {
@@ -1530,12 +1540,12 @@ impl Node {
}
// Step 2.
- if node.is_inclusive_ancestor_of(parent_root) {
+ if node.is_inclusive_ancestor_of(parent) {
return Err(HierarchyRequest);
}
// Step 3.
- if !parent.is_parent_of(child_root) {
+ if !parent.is_parent_of(child) {
return Err(NotFound);
}
@@ -1566,11 +1576,11 @@ impl Node {
0 => (),
// Step 6.1.2
1 => {
- if parent.child_elements().any(|c| NodeCast::from(&c) != child) {
+ if parent.child_elements().any(|c| NodeCast::from_ref(&c) != child) {
return Err(HierarchyRequest);
}
if child.following_siblings()
- .any(|child| child.is_doctype()) {
+ .any(|child| child.deref().is_doctype()) {
return Err(HierarchyRequest);
}
},
@@ -1580,22 +1590,22 @@ impl Node {
},
// Step 6.2
ElementNodeTypeId(..) => {
- if parent.child_elements().any(|c| NodeCast::from(&c) != child) {
+ if parent.child_elements().any(|c| NodeCast::from_ref(&c) != child) {
return Err(HierarchyRequest);
}
if child.following_siblings()
- .any(|child| child.is_doctype()) {
+ .any(|child| child.deref().is_doctype()) {
return Err(HierarchyRequest);
}
},
// Step 6.3
DoctypeNodeTypeId => {
- if parent.children().any(|c| c.is_doctype() && c != child) {
+ if parent.children().any(|c| c.deref().is_doctype() && &c != child) {
return Err(HierarchyRequest);
}
if parent.children()
- .take_while(|c| c != &child)
- .any(|c| c.is_element()) {
+ .take_while(|c| c != child)
+ .any(|c| c.deref().is_element()) {
return Err(HierarchyRequest);
}
},
@@ -1609,29 +1619,27 @@ impl Node {
}
// Ok if not caught by previous error checks.
- if node == child {
- return Ok(child);
+ if node.unrooted() == child.unrooted() {
+ return Ok(Unrooted::new_rooted(child));
}
// Step 7-8.
- let next_sibling = child.next_sibling();
+ let next_sibling = child.next_sibling().map(|node| (*node.root(&roots)).clone());
let reference_child = match next_sibling {
- Some(ref sibling) if sibling == &node => node.next_sibling(),
+ Some(ref sibling) if sibling == node => node.next_sibling().map(|node| (*node.root(&roots)).clone()),
_ => next_sibling
};
- let reference_child = reference_child.map(|child| child.root(&roots));
// Step 9.
- let document = document_from_node(&parent);
- let document = document.root(&roots);
- Node::adopt(node_root, &document.root_ref());
+ let document = document_from_node(parent).root(&roots);
+ Node::adopt(node, &*document);
{
// Step 10.
- Node::remove(child_root, parent_root, Suppressed);
+ Node::remove(child, parent, Suppressed);
// Step 11.
- Node::insert(node_root, parent_root, reference_child.root_ref(), Suppressed);
+ Node::insert(node, parent, reference_child, Suppressed);
}
// Step 12-14.
@@ -1646,40 +1654,38 @@ impl Node {
}
// Step 15.
- Ok(child)
+ Ok(Unrooted::new_rooted(child))
}
// http://dom.spec.whatwg.org/#dom-node-removechild
pub fn RemoveChild(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>)
- -> Fallible<JS<Node>> {
+ -> Fallible<Unrooted<Node>> {
Node::pre_remove(node, abstract_self)
}
// http://dom.spec.whatwg.org/#dom-node-normalize
pub fn Normalize(&mut self, abstract_self: &mut JSRef<Node>) {
let roots = RootCollection::new();
- let mut abstract_self = abstract_self.unrooted();
let mut prev_text = None;
for mut child in self.children() {
if child.is_text() {
- let characterdata: JS<CharacterData> = CharacterDataCast::to(&child).unwrap();
+ let mut child_alias = child.clone();
+ let characterdata: &JSRef<CharacterData> = CharacterDataCast::to_ref(&child).unwrap();
if characterdata.get().Length() == 0 {
- let child = child.root(&roots);
- abstract_self.remove_child(&mut child.root_ref());
+ abstract_self.remove_child(&mut child_alias);
} else {
match prev_text {
- Some(ref text_node) => {
- let mut prev_characterdata: JS<CharacterData> = CharacterDataCast::to(text_node).unwrap();
+ Some(ref mut text_node) => {
+ let prev_characterdata: &mut JSRef<CharacterData> = CharacterDataCast::to_mut_ref(text_node).unwrap();
let _ = prev_characterdata.get_mut().AppendData(characterdata.get().Data());
- let child = child.root(&roots);
- abstract_self.remove_child(&mut child.root_ref());
+ abstract_self.remove_child(&mut child_alias);
},
- None => prev_text = Some(child)
+ None => prev_text = Some(child_alias)
}
}
} else {
- let c = child.root(&roots);
- child.get_mut().Normalize(&mut c.root_ref());
+ let mut c = child.clone();
+ child.get_mut().Normalize(&mut c);
prev_text = None;
}
@@ -1687,7 +1693,7 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-clonenode
- pub fn CloneNode(&self, abstract_self: &mut JSRef<Node>, deep: bool) -> JS<Node> {
+ pub fn CloneNode(&self, abstract_self: &mut JSRef<Node>, deep: bool) -> Unrooted<Node> {
match deep {
true => Node::clone(abstract_self, None, CloneChildren),
false => Node::clone(abstract_self, None, DoNotCloneChildren)
@@ -1735,16 +1741,12 @@ impl Node {
})
}
fn is_equal_node(this: &JSRef<Node>, node: &JSRef<Node>) -> bool {
- let roots = RootCollection::new();
- let this_node = this.unrooted();
- let other = node.unrooted();
-
// Step 2.
- if this_node.type_id() != other.type_id() {
+ if this.type_id() != node.type_id() {
return false;
}
- match other.type_id() {
+ match node.type_id() {
// Step 3.
DoctypeNodeTypeId if !is_equal_doctype(this, node) => return false,
ElementNodeTypeId(..) if !is_equal_element(this, node) => return false,
@@ -1757,15 +1759,13 @@ impl Node {
}
// Step 5.
- if this_node.children().len() != other.children().len() {
+ if this.children().len() != node.children().len() {
return false;
}
// Step 6.
- this_node.children().zip(other.children()).all(|(ref child, ref other_child)| {
- let child = child.root(&roots);
- let other_child = other_child.root(&roots);
- is_equal_node(&child.root_ref(), &other_child.root_ref())
+ this.children().zip(node.children()).all(|(ref child, ref other_child)| {
+ is_equal_node(child, other_child)
})
}
match maybe_node {
@@ -1777,9 +1777,8 @@ impl Node {
}
// http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
- pub fn CompareDocumentPosition(&self, abstract_self_root: &JSRef<Node>, other_root: &JSRef<Node>) -> u16 {
- let other = other_root.unrooted();
- let abstract_self = abstract_self_root.unrooted();
+ pub fn CompareDocumentPosition(&self, abstract_self: &JSRef<Node>, other: &JSRef<Node>) -> u16 {
+ let roots = RootCollection::new();
if abstract_self == other {
// step 2.
0
@@ -1787,25 +1786,25 @@ impl Node {
let mut lastself = abstract_self.clone();
let mut lastother = other.clone();
for ancestor in abstract_self.ancestors() {
- if ancestor == other {
+ if &ancestor == other {
// step 4.
return NodeConstants::DOCUMENT_POSITION_CONTAINS +
NodeConstants::DOCUMENT_POSITION_PRECEDING;
}
- lastself = ancestor;
+ lastself = ancestor.clone();
}
for ancestor in other.ancestors() {
- if ancestor == abstract_self {
+ if &ancestor == abstract_self {
// step 5.
return NodeConstants::DOCUMENT_POSITION_CONTAINED_BY +
NodeConstants::DOCUMENT_POSITION_FOLLOWING;
}
- lastother = ancestor;
+ lastother = ancestor.clone();
}
if lastself != lastother {
- let abstract_uint: uintptr_t = as_uintptr(&abstract_self.get());
- let other_uint: uintptr_t = as_uintptr(&other.get());
+ let abstract_uint: uintptr_t = as_uintptr(&*abstract_self);
+ let other_uint: uintptr_t = as_uintptr(&*other);
let random = if abstract_uint < other_uint {
NodeConstants::DOCUMENT_POSITION_FOLLOWING
@@ -1818,12 +1817,12 @@ impl Node {
NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
}
- for child in lastself.traverse_preorder() {
- if child == other {
+ for child in lastself.traverse_preorder(&roots) {
+ if &child == other {
// step 6.
return NodeConstants::DOCUMENT_POSITION_PRECEDING;
}
- if child == abstract_self {
+ if &child == abstract_self {
// step 7.
return NodeConstants::DOCUMENT_POSITION_FOLLOWING;
}
@@ -1836,7 +1835,7 @@ impl Node {
pub fn Contains(&self, abstract_self: &JSRef<Node>, maybe_other: Option<JSRef<Node>>) -> bool {
match maybe_other {
None => false,
- Some(ref other) => abstract_self.unrooted().is_inclusive_ancestor_of(other)
+ Some(ref other) => abstract_self.is_inclusive_ancestor_of(other)
}
}
@@ -1863,33 +1862,38 @@ impl Node {
//
pub fn set_parent_node(&mut self, new_parent_node: Option<JSRef<Node>>) {
- let doc = self.owner_doc().clone();
+ let roots = RootCollection::new();
+ let doc = self.owner_doc().root(&roots);
doc.get().wait_until_safe_to_modify_dom();
- self.parent_node = new_parent_node.map(|node| node.unrooted())
+ self.parent_node.assign(new_parent_node);
}
pub fn set_first_child(&mut self, new_first_child: Option<JSRef<Node>>) {
- let doc = self.owner_doc().clone();
+ let roots = RootCollection::new();
+ let doc = self.owner_doc().root(&roots);
doc.get().wait_until_safe_to_modify_dom();
- self.first_child = new_first_child.map(|node| node.unrooted())
+ self.first_child.assign(new_first_child);
}
pub fn set_last_child(&mut self, new_last_child: Option<JSRef<Node>>) {
- let doc = self.owner_doc().clone();
+ let roots = RootCollection::new();
+ let doc = self.owner_doc().root(&roots);
doc.get().wait_until_safe_to_modify_dom();
- self.last_child = new_last_child.map(|node| node.unrooted())
+ self.last_child.assign(new_last_child);
}
pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<JSRef<Node>>) {
- let doc = self.owner_doc().clone();
+ let roots = RootCollection::new();
+ let doc = self.owner_doc().root(&roots);
doc.get().wait_until_safe_to_modify_dom();
- self.prev_sibling = new_prev_sibling.map(|node| node.unrooted())
+ self.prev_sibling.assign(new_prev_sibling);
}
pub fn set_next_sibling(&mut self, new_next_sibling: Option<JSRef<Node>>) {
- let doc = self.owner_doc().clone();
+ let roots = RootCollection::new();
+ let doc = self.owner_doc().root(&roots);
doc.get().wait_until_safe_to_modify_dom();
- self.next_sibling = new_next_sibling.map(|node| node.unrooted())
+ self.next_sibling.assign(new_next_sibling);
}
pub fn get_hover_state(&self) -> bool {
@@ -1940,19 +1944,20 @@ impl Reflectable for Node {
}
}
-pub fn document_from_node<T: NodeBase>(derived: &JS<T>) -> JS<Document> {
- let node: JS<Node> = NodeCast::from(derived);
- node.get().owner_doc().clone()
+pub fn document_from_node<T: NodeBase>(derived: &JSRef<T>) -> Unrooted<Document> {
+ let node: &JSRef<Node> = NodeCast::from_ref(derived);
+ node.owner_doc()
}
-pub fn window_from_node<T: NodeBase>(derived: &JS<T>) -> JS<Window> {
- let document: JS<Document> = document_from_node(derived);
- document.get().window.clone()
+pub fn window_from_node<T: NodeBase>(derived: &JSRef<T>) -> Unrooted<Window> {
+ let roots = RootCollection::new();
+ let document = document_from_node(derived).root(&roots);
+ Unrooted::new(document.deref().window.clone())
}
-impl VirtualMethods for JS<Node> {
+impl<'a> VirtualMethods for JSRef<'a, Node> {
fn super_type(&self) -> Option<~VirtualMethods:> {
- let eventtarget: JS<EventTarget> = EventTargetCast::from(self);
- Some(~eventtarget as ~VirtualMethods:)
+ let eventtarget: &JSRef<EventTarget> = EventTargetCast::from_ref(self);
+ Some(~eventtarget.clone() as ~VirtualMethods:)
}
}
diff --git a/src/components/script/dom/nodelist.rs b/src/components/script/dom/nodelist.rs
index 751c15ab098..219731034f1 100644
--- a/src/components/script/dom/nodelist.rs
+++ b/src/components/script/dom/nodelist.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::NodeListBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, RootCollection};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::node::{Node, NodeHelpers};
use dom::window::Window;
@@ -32,35 +32,44 @@ impl NodeList {
}
pub fn new(window: &JSRef<Window>,
- list_type: NodeListType) -> JS<NodeList> {
+ list_type: NodeListType) -> Unrooted<NodeList> {
reflect_dom_object(~NodeList::new_inherited(window.unrooted(), list_type),
window, NodeListBinding::Wrap)
}
- pub fn new_simple_list(window: &JSRef<Window>, elements: Vec<JS<Node>>) -> JS<NodeList> {
- NodeList::new(window, Simple(elements))
+ pub fn new_simple_list(window: &JSRef<Window>, elements: Vec<JSRef<Node>>) -> Unrooted<NodeList> {
+ NodeList::new(window, Simple(elements.iter().map(|element| element.unrooted()).collect()))
}
- pub fn new_child_list(window: &JSRef<Window>, node: &JSRef<Node>) -> JS<NodeList> {
+ pub fn new_child_list(window: &JSRef<Window>, node: &JSRef<Node>) -> Unrooted<NodeList> {
NodeList::new(window, Children(node.unrooted()))
}
pub fn Length(&self) -> u32 {
+ let roots = RootCollection::new();
match self.list_type {
Simple(ref elems) => elems.len() as u32,
- Children(ref node) => node.children().len() as u32
+ Children(ref node) => {
+ let node = node.root(&roots);
+ node.deref().children().len() as u32
+ }
}
}
- pub fn Item(&self, index: u32) -> Option<JS<Node>> {
+ pub fn Item(&self, index: u32) -> Option<Unrooted<Node>> {
+ let roots = RootCollection::new();
match self.list_type {
_ if index >= self.Length() => None,
- Simple(ref elems) => Some(elems.get(index as uint).clone()),
- Children(ref node) => node.children().nth(index as uint)
+ Simple(ref elems) => Some(Unrooted::new(elems.get(index as uint).clone())),
+ Children(ref node) => {
+ let node = node.root(&roots);
+ node.deref().children().nth(index as uint)
+ .map(|child| Unrooted::new_rooted(&child))
+ }
}
}
- pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Node>> {
+ pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<Unrooted<Node>> {
let item = self.Item(index);
*found = item.is_some();
item
diff --git a/src/components/script/dom/processinginstruction.rs b/src/components/script/dom/processinginstruction.rs
index 7064f8d3ca7..c094e4ae654 100644
--- a/src/components/script/dom/processinginstruction.rs
+++ b/src/components/script/dom/processinginstruction.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::ProcessingInstructionBinding;
use dom::bindings::codegen::InheritTypes::ProcessingInstructionDerived;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::characterdata::CharacterData;
use dom::document::Document;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
@@ -35,7 +35,7 @@ impl ProcessingInstruction {
}
}
- pub fn new(target: DOMString, data: DOMString, document: &JSRef<Document>) -> JS<ProcessingInstruction> {
+ pub fn new(target: DOMString, data: DOMString, document: &JSRef<Document>) -> Unrooted<ProcessingInstruction> {
let node = ProcessingInstruction::new_inherited(target, data, document.unrooted());
Node::reflect_node(~node, document, ProcessingInstructionBinding::Wrap)
}
diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs
index e05cec800bb..76bb587b134 100644
--- a/src/components/script/dom/testbinding.rs
+++ b/src/components/script/dom/testbinding.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, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::codegen::BindingDeclarations::TestBindingBinding;
use dom::bindings::codegen::UnionTypes::HTMLElementOrLong;
use self::TestBindingBinding::TestEnum;
@@ -51,10 +51,10 @@ impl TestBinding {
pub fn SetByteStringAttribute(&self, _: ByteString) {}
pub fn EnumAttribute(&self) -> TestEnum { _empty }
pub fn SetEnumAttribute(&self, _: TestEnum) {}
- pub fn InterfaceAttribute(&self) -> JS<Blob> {
+ pub fn InterfaceAttribute(&self) -> Unrooted<Blob> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- Blob::new(&window.root_ref())
+ Blob::new(&*window)
}
pub fn SetInterfaceAttribute(&self, _: &JSRef<Blob>) {}
pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() }
@@ -87,10 +87,10 @@ impl TestBinding {
pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") }
pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {}
pub fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(_empty) }
- pub fn GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> {
+ pub fn GetInterfaceAttributeNullable(&self) -> Option<Unrooted<Blob>> {
let roots = RootCollection::new();
let window = self.window.root(&roots);
- Some(Blob::new(&window.root_ref()))
+ Some(Blob::new(&(*window)))
}
pub fn SetInterfaceAttributeNullable(&self, _: Option<JSRef<Blob>>) {}
diff --git a/src/components/script/dom/text.rs b/src/components/script/dom/text.rs
index 61c37d2ad52..cdcfdac6af3 100644
--- a/src/components/script/dom/text.rs
+++ b/src/components/script/dom/text.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::TextBinding;
use dom::bindings::codegen::InheritTypes::TextDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted};
use dom::bindings::error::Fallible;
use dom::characterdata::CharacterData;
use dom::document::Document;
@@ -35,19 +35,19 @@ impl Text {
}
}
- pub fn new(text: DOMString, document: &JSRef<Document>) -> JS<Text> {
+ pub fn new(text: DOMString, document: &JSRef<Document>) -> Unrooted<Text> {
let node = Text::new_inherited(text, document.unrooted());
Node::reflect_node(~node, document, TextBinding::Wrap)
}
- pub fn Constructor(owner: &JSRef<Window>, text: DOMString) -> Fallible<JS<Text>> {
+ pub fn Constructor(owner: &JSRef<Window>, text: DOMString) -> Fallible<Unrooted<Text>> {
let roots = RootCollection::new();
let document = owner.get().Document();
let document = document.root(&roots);
Ok(Text::new(text.clone(), &document.root_ref()))
}
- pub fn SplitText(&self, _offset: u32) -> Fallible<JS<Text>> {
+ pub fn SplitText(&self, _offset: u32) -> Fallible<Unrooted<Text>> {
fail!("unimplemented")
}
diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs
index 50c97ee8373..f42edeb42bf 100644
--- a/src/components/script/dom/uievent.rs
+++ b/src/components/script/dom/uievent.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::BindingDeclarations::UIEventBinding;
use dom::bindings::codegen::InheritTypes::UIEventDerived;
-use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference};
+use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference, Unrooted};
use dom::bindings::error::Fallible;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, EventTypeId, UIEventTypeId};
@@ -36,7 +36,7 @@ impl UIEvent {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<UIEvent> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<UIEvent> {
reflect_dom_object(~UIEvent::new_inherited(UIEventTypeId),
window,
UIEventBinding::Wrap)
@@ -44,17 +44,17 @@ impl UIEvent {
pub fn Constructor(owner: &JSRef<Window>,
type_: DOMString,
- init: &UIEventBinding::UIEventInit) -> Fallible<JS<UIEvent>> {
+ init: &UIEventBinding::UIEventInit) -> Fallible<Unrooted<UIEvent>> {
let roots = RootCollection::new();
- let mut ev = UIEvent::new(owner);
+ let mut ev = UIEvent::new(owner).root(&roots);
let view = init.view.as_ref().map(|view| view.root(&roots));
ev.get_mut().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable,
view.root_ref(), init.detail);
- Ok(ev)
+ Ok(Unrooted::new_rooted(&*ev))
}
- pub fn GetView(&self) -> Option<JS<Window>> {
- self.view.clone()
+ pub fn GetView(&self) -> Option<Unrooted<Window>> {
+ self.view.clone().map(|view| Unrooted::new(view))
}
pub fn Detail(&self) -> i32 {
@@ -97,7 +97,7 @@ impl UIEvent {
0
}
- pub fn GetRangeParent(&self) -> Option<JS<Node>> {
+ pub fn GetRangeParent(&self) -> Option<Unrooted<Node>> {
//TODO
None
}
diff --git a/src/components/script/dom/validitystate.rs b/src/components/script/dom/validitystate.rs
index 9a03134169f..02b0b9a7a11 100644
--- a/src/components/script/dom/validitystate.rs
+++ b/src/components/script/dom/validitystate.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::ValidityStateBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::window::Window;
@@ -23,7 +23,7 @@ impl ValidityState {
}
}
- pub fn new(window: &JSRef<Window>) -> JS<ValidityState> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<ValidityState> {
reflect_dom_object(~ValidityState::new_inherited(window.unrooted()),
window,
ValidityStateBinding::Wrap)
diff --git a/src/components/script/dom/virtualmethods.rs b/src/components/script/dom/virtualmethods.rs
index 85ae37cb032..bf4681fab3b 100644
--- a/src/components/script/dom/virtualmethods.rs
+++ b/src/components/script/dom/virtualmethods.rs
@@ -8,7 +8,7 @@ use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast;
use dom::bindings::codegen::InheritTypes::HTMLImageElementCast;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast;
use dom::bindings::codegen::InheritTypes::HTMLStyleElementCast;
-use dom::bindings::js::JS;
+use dom::bindings::js::JSRef;
use dom::element::Element;
use dom::element::{ElementTypeId, HTMLImageElementTypeId};
use dom::element::{HTMLIFrameElementTypeId, HTMLObjectElementTypeId, HTMLStyleElementTypeId};
@@ -62,7 +62,7 @@ pub trait VirtualMethods {
}
/// Called on the parent when a node is added to its child list.
- fn child_inserted(&mut self, child: &JS<Node>) {
+ fn child_inserted(&mut self, child: &JSRef<Node>) {
match self.super_type() {
Some(ref mut s) => s.child_inserted(child),
_ => (),
@@ -74,31 +74,31 @@ pub trait VirtualMethods {
/// method call on the trait object will invoke the corresponding method on the
/// concrete type, propagating up the parent hierarchy unless otherwise
/// interrupted.
-pub fn vtable_for<'a>(node: &JS<Node>) -> ~VirtualMethods: {
+pub fn vtable_for<'a>(node: &JSRef<Node>) -> ~VirtualMethods: {
match node.get().type_id {
ElementNodeTypeId(HTMLImageElementTypeId) => {
- let element: JS<HTMLImageElement> = HTMLImageElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<HTMLImageElement> = HTMLImageElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
ElementNodeTypeId(HTMLIFrameElementTypeId) => {
- let element: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<HTMLIFrameElement> = HTMLIFrameElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
ElementNodeTypeId(HTMLObjectElementTypeId) => {
- let element: JS<HTMLObjectElement> = HTMLObjectElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<HTMLObjectElement> = HTMLObjectElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
ElementNodeTypeId(HTMLStyleElementTypeId) => {
- let element: JS<HTMLStyleElement> = HTMLStyleElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<HTMLStyleElement> = HTMLStyleElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
ElementNodeTypeId(ElementTypeId) => {
- let element: JS<Element> = ElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
ElementNodeTypeId(_) => {
- let element: JS<HTMLElement> = HTMLElementCast::to(node).unwrap();
- ~element as ~VirtualMethods:
+ let element: &JSRef<HTMLElement> = HTMLElementCast::to_ref(node).unwrap();
+ ~element.clone() as ~VirtualMethods:
}
_ => {
~node.clone() as ~VirtualMethods:
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index a1155434d89..ff46c27ed79 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::BindingDeclarations::WindowBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, OptionalAssignable};
use dom::bindings::trace::{Traceable, Untraceable};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::browsercontext::BrowserContext;
@@ -116,9 +116,9 @@ impl Window {
chan.send(ExitWindowMsg(self.page.id.clone()));
}
- pub fn Document(&self) -> JS<Document> {
+ pub fn Document(&self) -> Unrooted<Document> {
let frame = self.page().frame();
- frame.get_ref().document.clone()
+ Unrooted::new(frame.get_ref().document.clone())
}
pub fn Name(&self) -> DOMString {
@@ -148,29 +148,29 @@ impl Window {
pub fn Blur(&self) {
}
- pub fn GetFrameElement(&self) -> Option<JS<Element>> {
+ pub fn GetFrameElement(&self) -> Option<Unrooted<Element>> {
None
}
- pub fn Location(&mut self, abstract_self: &JSRef<Window>) -> JS<Location> {
+ pub fn Location(&mut self, abstract_self: &JSRef<Window>) -> Unrooted<Location> {
if self.location.is_none() {
- self.location = Some(Location::new(abstract_self, self.page.clone()));
+ self.location.assign(Some(Location::new(abstract_self, self.page.clone())));
}
- self.location.get_ref().clone()
+ Unrooted::new(self.location.get_ref().clone())
}
- pub fn Console(&mut self, abstract_self: &JSRef<Window>) -> JS<Console> {
+ pub fn Console(&mut self, abstract_self: &JSRef<Window>) -> Unrooted<Console> {
if self.console.is_none() {
- self.console = Some(Console::new(abstract_self));
+ self.console.assign(Some(Console::new(abstract_self)));
}
- self.console.get_ref().clone()
+ Unrooted::new(self.console.get_ref().clone())
}
- pub fn Navigator(&mut self, abstract_self: &JSRef<Window>) -> JS<Navigator> {
+ pub fn Navigator(&mut self, abstract_self: &JSRef<Window>) -> Unrooted<Navigator> {
if self.navigator.is_none() {
- self.navigator = Some(Navigator::new(abstract_self));
+ self.navigator.assign(Some(Navigator::new(abstract_self)));
}
- self.navigator.get_ref().clone()
+ Unrooted::new(self.navigator.get_ref().clone())
}
pub fn Confirm(&self, _message: DOMString) -> bool {
@@ -279,11 +279,11 @@ impl Window {
self.ClearTimeout(handle);
}
- pub fn Window(&self, abstract_self: &JSRef<Window>) -> JS<Window> {
- abstract_self.unrooted()
+ pub fn Window(&self, abstract_self: &JSRef<Window>) -> Unrooted<Window> {
+ Unrooted::new_rooted(abstract_self)
}
- pub fn Self(&self, abstract_self: &JSRef<Window>) -> JS<Window> {
+ pub fn Self(&self, abstract_self: &JSRef<Window>) -> Unrooted<Window> {
self.Window(abstract_self)
}
@@ -301,7 +301,7 @@ impl Window {
self.page().join_layout();
}
- pub fn init_browser_context(&mut self, doc: &JS<Document>) {
+ pub fn init_browser_context(&mut self, doc: &JSRef<Document>) {
self.browser_context = Some(BrowserContext::new(doc));
}
@@ -310,7 +310,7 @@ impl Window {
script_chan: ScriptChan,
compositor: ~ScriptListener,
image_cache_task: ImageCacheTask)
- -> JS<Window> {
+ -> Unrooted<Window> {
let win = ~Window {
eventtarget: EventTarget::new_inherited(WindowTypeId),
script_chan: script_chan,
@@ -325,6 +325,6 @@ impl Window {
browser_context: None,
};
- WindowBinding::Wrap(cx, win)
+ Unrooted::new(WindowBinding::Wrap(cx, win))
}
}
diff --git a/src/components/script/dom/xmlhttprequest.rs b/src/components/script/dom/xmlhttprequest.rs
index 9f2bbf180b5..8327135d566 100644
--- a/src/components/script/dom/xmlhttprequest.rs
+++ b/src/components/script/dom/xmlhttprequest.rs
@@ -10,7 +10,7 @@ use dom::bindings::codegen::InheritTypes::XMLHttpRequestDerived;
use dom::document::Document;
use dom::eventtarget::{EventTarget, XMLHttpRequestTargetTypeId};
use dom::bindings::error::Fallible;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{JS, JSRef, Unrooted, OptionalAssignable};
use js::jsapi::JSContext;
use js::jsval::{JSVal, NullValue};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
@@ -31,7 +31,7 @@ pub struct XMLHttpRequest {
ready_state: u16,
timeout: u32,
with_credentials: bool,
- upload: JS<XMLHttpRequestUpload>,
+ upload: Option<JS<XMLHttpRequestUpload>>,
response_url: DOMString,
status: u16,
status_text: ByteString,
@@ -42,26 +42,28 @@ pub struct XMLHttpRequest {
impl XMLHttpRequest {
pub fn new_inherited(owner: &JSRef<Window>) -> XMLHttpRequest {
- XMLHttpRequest {
+ let mut xhr = XMLHttpRequest {
eventtarget: XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestTypeId),
ready_state: 0,
timeout: 0u32,
with_credentials: false,
- upload: XMLHttpRequestUpload::new(owner),
+ upload: None,
response_url: ~"",
status: 0,
status_text: ByteString::new(vec!()),
response_type: _empty,
response_text: ~"",
response_xml: None
- }
+ };
+ xhr.upload.assign(Some(XMLHttpRequestUpload::new(owner)));
+ xhr
}
- pub fn new(window: &JSRef<Window>) -> JS<XMLHttpRequest> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<XMLHttpRequest> {
reflect_dom_object(~XMLHttpRequest::new_inherited(window),
window,
XMLHttpRequestBinding::Wrap)
}
- pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<XMLHttpRequest>> {
+ pub fn Constructor(owner: &JSRef<Window>) -> Fallible<Unrooted<XMLHttpRequest>> {
Ok(XMLHttpRequest::new(owner))
}
pub fn ReadyState(&self) -> u16 {
@@ -89,8 +91,8 @@ impl XMLHttpRequest {
pub fn SetWithCredentials(&mut self, with_credentials: bool) {
self.with_credentials = with_credentials
}
- pub fn Upload(&self) -> JS<XMLHttpRequestUpload> {
- self.upload.clone()
+ pub fn Upload(&self) -> Unrooted<XMLHttpRequestUpload> {
+ Unrooted::new(self.upload.get_ref().clone())
}
pub fn Send(&self, _data: Option<DOMString>) {
@@ -128,8 +130,8 @@ impl XMLHttpRequest {
pub fn ResponseText(&self) -> DOMString {
self.response_text.clone()
}
- pub fn GetResponseXML(&self) -> Option<JS<Document>> {
- self.response_xml.clone()
+ pub fn GetResponseXML(&self) -> Option<Unrooted<Document>> {
+ self.response_xml.clone().map(|response| Unrooted::new(response))
}
}
diff --git a/src/components/script/dom/xmlhttprequestupload.rs b/src/components/script/dom/xmlhttprequestupload.rs
index 5e06d51b1d3..8e251dd4e8f 100644
--- a/src/components/script/dom/xmlhttprequestupload.rs
+++ b/src/components/script/dom/xmlhttprequestupload.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::XMLHttpRequestUploadDerived;
use dom::bindings::codegen::BindingDeclarations::XMLHttpRequestUploadBinding;
-use dom::bindings::js::{JS, JSRef};
+use dom::bindings::js::{Unrooted, JSRef};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::eventtarget::{EventTarget, XMLHttpRequestTargetTypeId};
use dom::window::Window;
@@ -22,7 +22,7 @@ impl XMLHttpRequestUpload {
eventtarget:XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestUploadTypeId)
}
}
- pub fn new(window: &JSRef<Window>) -> JS<XMLHttpRequestUpload> {
+ pub fn new(window: &JSRef<Window>) -> Unrooted<XMLHttpRequestUpload> {
reflect_dom_object(~XMLHttpRequestUpload::new_inherited(),
window,
XMLHttpRequestUploadBinding::Wrap)
diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs
index 771b75f3e9c..a90a696063c 100644
--- a/src/components/script/html/hubbub_html_parser.rs
+++ b/src/components/script/html/hubbub_html_parser.rs
@@ -4,7 +4,7 @@
use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, TextCast, ElementCast};
use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast;
-use dom::bindings::js::{JS, JSRef, RootCollection};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, OptionalRootable};
use dom::bindings::utils::Reflectable;
use dom::document::Document;
use dom::element::{AttributeHandlers, HTMLLinkElementTypeId, HTMLIFrameElementTypeId};
@@ -12,7 +12,7 @@ use dom::htmlelement::HTMLElement;
use dom::htmlheadingelement::{Heading1, Heading2, Heading3, Heading4, Heading5, Heading6};
use dom::htmliframeelement::IFrameSize;
use dom::htmlformelement::HTMLFormElement;
-use dom::node::{ElementNodeTypeId, INode, NodeHelpers};
+use dom::node::{ElementNodeTypeId, NodeHelpers, AppendChild};
use dom::types::*;
use html::cssparse::{StylesheetProvenance, UrlProvenance, spawn_css_parser};
use script_task::Page;
@@ -39,7 +39,7 @@ macro_rules! handle_element(
$ctor: ident
$(, $arg:expr )*) => (
if $string == $localName {
- return ElementCast::from(&$ctor::new($localName, $document $(, $arg)*));
+ return ElementCast::from_unrooted($ctor::new($localName, $document $(, $arg)*));
}
)
)
@@ -74,21 +74,22 @@ pub struct HtmlParserResult {
pub discovery_port: Receiver<HtmlDiscoveryMessage>,
}
-trait NodeWrapping {
+trait NodeWrapping<T> {
unsafe fn to_hubbub_node(&self, roots: &RootCollection) -> hubbub::NodeDataPtr;
- unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr, roots: Option<&RootCollection>) -> Self;
}
-impl<T: NodeBase+Reflectable> NodeWrapping for JS<T> {
+impl<'a, T: NodeBase+Reflectable> NodeWrapping<T> for JSRef<'a, T> {
unsafe fn to_hubbub_node(&self, roots: &RootCollection) -> hubbub::NodeDataPtr {
roots.root_raw(self.reflector().get_jsobject());
cast::transmute(self.get())
}
- unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr, roots: Option<&RootCollection>) -> JS<T> {
- let js = JS::from_raw(cast::transmute(n));
- let _ = roots.map(|roots| roots.unroot_raw(js.reflector().get_jsobject()));
- js
- }
+}
+
+unsafe fn from_hubbub_node<T: Reflectable>(n: hubbub::NodeDataPtr,
+ roots: Option<&RootCollection>) -> Unrooted<T> {
+ let js = JS::from_raw(cast::transmute(n));
+ let _ = roots.map(|roots| roots.unroot_raw(js.reflector().get_jsobject()));
+ Unrooted::new(js)
}
/**
@@ -163,7 +164,7 @@ fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>,
// Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized
// via atomization (issue #85).
-pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> JS<Element> {
+pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> Unrooted<Element> {
// TODO (Issue #85): use atoms
handle_element!(document, tag, "a", HTMLAnchorElement);
handle_element!(document, tag, "applet", HTMLAppletElement);
@@ -245,7 +246,7 @@ pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> JS<
handle_element!(document, tag, "ul", HTMLUListElement);
handle_element!(document, tag, "video", HTMLVideoElement);
- return ElementCast::from(&HTMLUnknownElement::new(tag, document));
+ return ElementCast::from_unrooted(HTMLUnknownElement::new(tag, document));
}
pub fn parse_html(page: &Page,
@@ -297,7 +298,7 @@ pub fn parse_html(page: &Page,
let roots = RootCollection::new();
- parser.set_document_node(unsafe { document.unrooted().to_hubbub_node(&roots) });
+ parser.set_document_node(unsafe { document.to_hubbub_node(&roots) });
parser.enable_scripting(true);
parser.enable_styling(true);
@@ -313,7 +314,8 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
+ let comment = Comment::new(data, *tmp).root(&roots);
+ let comment: &JSRef<Node> = NodeCast::from_ref(&*comment);
unsafe { comment.to_hubbub_node(&roots) }
},
create_doctype: |doctype: ~hubbub::Doctype| {
@@ -325,9 +327,9 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
+ let doctype_node = DocumentType::new(name, public_id, system_id, *tmp).root(&roots);
unsafe {
- doctype_node.to_hubbub_node(&roots)
+ doctype_node.deref().to_hubbub_node(&roots)
}
},
create_element: |tag: ~hubbub::Tag| {
@@ -335,8 +337,7 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let mut element = build_element_from_tag(tag.name.clone(), *tmp);
- let _element_root = element.root(&roots);
+ let mut element = build_element_from_tag(tag.name.clone(), *tmp).root(&roots);
debug!("-- attach attrs");
for attr in tag.attributes.iter() {
@@ -346,21 +347,32 @@ pub fn parse_html(page: &Page,
attr.value.clone()).is_ok());
}
+ //FIXME: workaround for https://github.com/mozilla/rust/issues/13246;
+ // we get unrooting order failures if these are inside the match.
+ let rel = {
+ let rel = element.get_attribute(Null, "rel").root(&roots);
+ rel.map(|a| a.deref().Value())
+ };
+ let href = {
+ let href= element.get_attribute(Null, "href").root(&roots);
+ href.map(|a| a.deref().Value())
+ };
+ let src_opt = {
+ let src_opt = element.get_attribute(Null, "src").root(&roots);
+ src_opt.map(|a| a.deref().Value())
+ };
+
// Spawn additional parsing, network loads, etc. from tag and attrs
match element.get().node.type_id {
// Handle CSS style sheets from <link> elements
ElementNodeTypeId(HTMLLinkElementTypeId) => {
- match (element.get_attribute(Null, "rel"),
- element.get_attribute(Null, "href")) {
- (Some(ref rel), Some(ref href)) if rel.get()
- .value_ref()
- .split(HTML_SPACE_CHARACTERS.
- as_slice())
+ match (rel, href) {
+ (Some(ref rel), Some(ref href)) if rel.split(HTML_SPACE_CHARACTERS.as_slice())
.any(|s| {
s.eq_ignore_ascii_case("stylesheet")
}) => {
- debug!("found CSS stylesheet: {:s}", href.get().value_ref());
- let url = parse_url(href.get().value_ref(), Some(url2.clone()));
+ debug!("found CSS stylesheet: {:s}", *href);
+ let url = parse_url(href.as_slice(), Some(url2.clone()));
css_chan2.send(CSSTaskNewFile(UrlProvenance(url, resource_task.clone())));
}
_ => {}
@@ -369,11 +381,9 @@ pub fn parse_html(page: &Page,
ElementNodeTypeId(HTMLIFrameElementTypeId) => {
let iframe_chan = discovery_chan.clone();
- let mut iframe_element: JS<HTMLIFrameElement> =
- HTMLIFrameElementCast::to(&element).unwrap();
+ let iframe_element: &mut JSRef<HTMLIFrameElement> =
+ HTMLIFrameElementCast::to_mut_ref(&mut *element).unwrap();
let sandboxed = iframe_element.get().is_sandboxed();
- let elem: JS<Element> = ElementCast::from(&iframe_element);
- let src_opt = elem.get_attribute(Null, "src").map(|x| x.get().Value());
for src in src_opt.iter() {
let iframe_url = parse_url(*src, Some(url2.clone()));
iframe_element.get_mut().set_frame(iframe_url.clone());
@@ -402,18 +412,17 @@ pub fn parse_html(page: &Page,
// NOTE: tmp vars are workaround for lifetime issues. Both required.
let tmp_borrow = doc_cell.borrow();
let tmp = &*tmp_borrow;
- let text = Text::new(data, *tmp);
- unsafe { text.to_hubbub_node(&roots) }
+ let text = Text::new(data, *tmp).root(&roots);
+ unsafe { text.deref().to_hubbub_node(&roots) }
},
ref_node: |_| {},
unref_node: |_| {},
append_child: |parent: hubbub::NodeDataPtr, child: hubbub::NodeDataPtr| {
unsafe {
debug!("append child {:x} {:x}", parent, child);
- let mut parent: JS<Node> = NodeWrapping::from_hubbub_node(parent, None);
- let child: JS<Node> = NodeWrapping::from_hubbub_node(child, Some(&roots));
- let child = child.root(&roots);
- assert!(parent.AppendChild(&mut child.root_ref()).is_ok());
+ let mut child = from_hubbub_node(child, Some(&roots)).root(&roots);
+ let mut parent = from_hubbub_node(parent, None).root(&roots);
+ assert!(AppendChild(&mut *parent, &mut *child).is_ok());
}
child
},
@@ -464,8 +473,8 @@ pub fn parse_html(page: &Page,
},
complete_script: |script| {
unsafe {
- let script: JS<Element> = NodeWrapping::from_hubbub_node(script, None);
- match script.get_attribute(Null, "src") {
+ let script: &JSRef<Element> = &*from_hubbub_node(script, None).root(&roots);
+ match script.get_attribute(Null, "src").root(&roots) {
Some(src) => {
debug!("found script: {:s}", src.get().Value());
let new_url = parse_url(src.get().value_ref(), Some(url3.clone()));
@@ -473,11 +482,11 @@ pub fn parse_html(page: &Page,
}
None => {
let mut data = vec!();
- let scriptnode: JS<Node> = NodeCast::from(&script);
+ let scriptnode: &JSRef<Node> = NodeCast::from_ref(script);
debug!("iterating over children {:?}", scriptnode.first_child());
for child in scriptnode.children() {
debug!("child = {:?}", child);
- let text: JS<Text> = TextCast::to(&child).unwrap();
+ let text: &JSRef<Text> = TextCast::to_ref(&child).unwrap();
data.push(text.get().characterdata.data.to_str()); // FIXME: Bad copy.
}
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index f442ddae7c1..f29a18b850a 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -7,7 +7,8 @@
use dom::bindings::codegen::RegisterBindings;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, ElementCast, EventCast};
-use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference};
+use dom::bindings::js::{JS, JSRef, RootCollection, Unrooted, OptionalAssignable};
+use dom::bindings::js::OptionalRootable;
use dom::bindings::trace::{Traceable, Untraceable};
use dom::bindings::utils::{Reflectable, GlobalStaticData, wrap_for_same_compartment};
use dom::document::{Document, HTMLDocument};
@@ -16,6 +17,7 @@ use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, M
use dom::event::Event;
use dom::uievent::UIEvent;
use dom::eventtarget::EventTarget;
+use dom::node;
use dom::node::{Node, NodeHelpers};
use dom::window::{TimerId, Window};
use html::hubbub_html_parser::HtmlParserResult;
@@ -272,14 +274,15 @@ impl Page {
/// Adds the given damage.
pub fn damage(&self, level: DocumentDamageLevel) {
+ let roots = RootCollection::new();
let root = match *self.frame() {
None => return,
Some(ref frame) => frame.document.get().GetDocumentElement()
};
- match root {
+ match root.root(&roots) {
None => {},
Some(root) => {
- let root: JS<Node> = NodeCast::from(&root);
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
let mut damage = *self.damage.deref().borrow_mut();
match damage {
None => {}
@@ -351,6 +354,8 @@ impl Page {
goal: ReflowGoal,
script_chan: ScriptChan,
compositor: &ScriptListener) {
+ let roots = RootCollection::new();
+
let root = match *self.frame() {
None => return,
Some(ref frame) => {
@@ -358,7 +363,7 @@ impl Page {
}
};
- match root {
+ match root.root(&roots) {
None => {},
Some(root) => {
debug!("script: performing reflow for goal {:?}", goal);
@@ -377,7 +382,7 @@ impl Page {
let mut last_reflow_id = self.last_reflow_id.deref().borrow_mut();
*last_reflow_id += 1;
- let root: JS<Node> = NodeCast::from(&root);
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
let mut damage = self.damage.deref().borrow_mut();
let window_size = self.window_size.deref().borrow();
@@ -401,19 +406,21 @@ impl Page {
}
}
- fn find_fragment_node(&self, fragid: ~str) -> Option<JS<Element>> {
- let document = self.frame().get_ref().document.clone();
+ fn find_fragment_node(&self, fragid: ~str) -> Option<Unrooted<Element>> {
+ let roots = RootCollection::new();
+ let document = self.frame().get_ref().document.root(&roots);
match document.get().GetElementById(fragid.to_owned()) {
Some(node) => Some(node),
None => {
- let doc_node: JS<Node> = NodeCast::from(&document);
- let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element());
+ let doc_node: &JSRef<Node> = NodeCast::from_ref(&*document);
+ let mut anchors = doc_node.traverse_preorder(&roots)
+ .filter(|node| node.is_anchor_element());
anchors.find(|node| {
- let elem: JS<Element> = ElementCast::to(node).unwrap();
- elem.get_attribute(Null, "name").map_or(false, |attr| {
+ let elem: &JSRef<Element> = ElementCast::to_ref(node).unwrap();
+ elem.get_attribute(Null, "name").root(&roots).map_or(false, |attr| {
attr.get().value_ref() == fragid
})
- }).map(|node| ElementCast::to(&node).unwrap())
+ }).map(|node| Unrooted::new_rooted(ElementCast::to_ref(&node).unwrap()))
}
}
}
@@ -435,13 +442,15 @@ 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 root = document.get().GetDocumentElement();
+ let root = document.get().GetDocumentElement().root(&roots);
if root.is_none() {
return None;
}
- let root: JS<Node> = NodeCast::from(&root.unwrap());
+ let root = root.unwrap();
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
let (chan, port) = channel();
let address = match self.query_layout(HitTestQuery(root.to_trusted_node_address(), *point, chan), port) {
Ok(HitTestResponse(node_address)) => {
@@ -456,13 +465,15 @@ 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 root = document.get().GetDocumentElement();
+ let root = document.get().GetDocumentElement().root(&roots);
if root.is_none() {
return None;
}
- let root: JS<Node> = NodeCast::from(&root.unwrap());
+ let root = root.unwrap();
+ let root: &JSRef<Node> = NodeCast::from_ref(&*root);
let (chan, port) = channel();
let address = match self.query_layout(MouseOverQuery(root.to_trusted_node_address(), *point, chan), port) {
Ok(MouseOverResponse(node_address)) => {
@@ -868,16 +879,14 @@ impl ScriptTask {
page_tree.page.clone(),
self.chan.clone(),
self.compositor.dup(),
- self.image_cache_task.clone());
- let window_root = window.root(&roots);
+ self.image_cache_task.clone()).root(&roots);
page.initialize_js_info(cx.clone(), window.reflector().get_jsobject());
- let mut document = Document::new(&window_root.root_ref(), Some(url.clone()), HTMLDocument, None);
- let doc_root = document.root(&roots);
- window.get_mut().init_browser_context(&document);
+ let mut document = Document::new(&*window, Some(url.clone()), HTMLDocument, None).root(&roots);
+ window.get_mut().init_browser_context(&*document);
{
let mut js_info = page.mut_js_info();
- RegisterBindings::Register(&window_root.root_ref(), js_info.get_mut_ref());
+ RegisterBindings::Register(&*window, js_info.get_mut_ref());
}
self.compositor.set_ready_state(Loading);
@@ -885,7 +894,7 @@ impl ScriptTask {
//
// Note: We can parse the next document in parallel with any previous documents.
let html_parsing_result = hubbub_html_parser::parse_html(page,
- &mut doc_root.root_ref(),
+ &mut *document,
url.clone(),
self.resource_task.clone());
@@ -897,8 +906,8 @@ impl ScriptTask {
// Create the root frame.
let mut frame = page.mut_frame();
*frame = Some(Frame {
- document: document.clone(),
- window: window.clone(),
+ document: document.deref().unrooted(),
+ window: window.deref().unrooted(),
});
}
@@ -973,26 +982,24 @@ impl ScriptTask {
// We have no concept of a document loader right now, so just dispatch the
// "load" event as soon as we've finished executing all scripts parsed during
// the initial load.
- let mut event = Event::new(&window_root.root_ref());
+ let mut event = Event::new(&*window).root(&roots);
event.get_mut().InitEvent(~"load", false, false);
- let event = event.root(&roots);
- let doctarget = EventTargetCast::from(&document);
- let doctarget = doctarget.root(&roots);
- let mut wintarget: JS<EventTarget> = EventTargetCast::from(&window);
- let wintarget_root = wintarget.root(&roots);
- let _ = wintarget.get_mut().dispatch_event_with_target(&wintarget_root.root_ref(),
- Some(doctarget.root_ref()),
- &mut event.root_ref());
+ let doctarget: &JSRef<EventTarget> = EventTargetCast::from_ref(&*document);
+ let wintarget: &mut JSRef<EventTarget> = EventTargetCast::from_mut_ref(&mut *window);
+ let wintarget_alias = wintarget.clone();
+ let _ = wintarget.get_mut().dispatch_event_with_target(&wintarget_alias,
+ Some((*doctarget).clone()),
+ &mut *event);
let mut fragment_node = page.fragment_node.deref().borrow_mut();
- *fragment_node = fragment.map_or(None, |fragid| page.find_fragment_node(fragid));
+ (*fragment_node).assign(fragment.map_or(None, |fragid| page.find_fragment_node(fragid)));
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(LoadCompleteMsg(page.id, url));
}
- fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: JS<Element>) {
- let node: JS<Node> = NodeCast::from(&node);
+ fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: &JSRef<Element>) {
+ let node: &JSRef<Node> = NodeCast::from_ref(node);
let rect = node.get_bounding_content_box();
let point = Point2D(to_frac_px(rect.origin.x).to_f32().unwrap(),
to_frac_px(rect.origin.y).to_f32().unwrap());
@@ -1015,6 +1022,7 @@ impl ScriptTask {
match event {
ResizeEvent(new_width, new_height) => {
+ let roots = RootCollection::new();
debug!("script got resize event: {:u}, {:u}", new_width, new_height);
let window = {
@@ -1032,31 +1040,28 @@ impl ScriptTask {
}
let mut fragment_node = page.fragment_node.deref().borrow_mut();
- match fragment_node.take() {
- Some(node) => self.scroll_fragment_point(pipeline_id, node),
+ match fragment_node.take().map(|node| node.root(&roots)) {
+ Some(node) => self.scroll_fragment_point(pipeline_id, &*node),
None => {}
}
- frame.as_ref().map(|frame| frame.window.clone())
+ frame.as_ref().map(|frame| Unrooted::new(frame.window.clone()))
};
- match window {
- Some(ref window) => {
+ match window.root(&roots) {
+ Some(mut window) => {
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
- let roots = RootCollection::new();
- let window_root = window.root(&roots);
-
- let mut uievent = UIEvent::new(&window_root.root_ref());
- uievent.get_mut().InitUIEvent(~"resize", false, false, Some(window_root).root_ref(), 0i32);
- let event: JS<Event> = EventCast::from(&uievent);
- let event = event.root(&roots);
-
- let mut wintarget: JS<EventTarget> = EventTargetCast::from(window);
- let targetroot = wintarget.root(&roots);
- let _ = wintarget.get_mut().dispatch_event_with_target(&targetroot.root_ref(),
+ let mut uievent = UIEvent::new(&*window).root(&roots);
+ uievent.get_mut().InitUIEvent(~"resize", false, false,
+ Some((*window).clone()), 0i32);
+ let event: &mut JSRef<Event> = EventCast::from_mut_ref(&mut *uievent);
+
+ let wintarget: &mut JSRef<EventTarget> = EventTargetCast::from_mut_ref(&mut *window);
+ let wintarget_alias = wintarget.clone();
+ let _ = wintarget.get_mut().dispatch_event_with_target(&wintarget_alias,
None,
- &mut event.root_ref());
+ &mut *event);
}
None => ()
}
@@ -1076,32 +1081,31 @@ impl ScriptTask {
}
ClickEvent(_button, point) => {
+ let roots = RootCollection::new();
debug!("ClickEvent: clicked at {:?}", point);
let mut page_tree = self.page_tree.borrow_mut();
let page = get_page(&mut *page_tree, pipeline_id);
match page.hit_test(&point) {
Some(node_address) => {
debug!("node address is {:?}", node_address);
- let mut node: JS<Node> =
- NodeHelpers::from_untrusted_node_address(self.js_runtime.deref().ptr,
- node_address);
- debug!("clicked on {:s}", node.debug_str());
+ let mut node =
+ node::from_untrusted_node_address(self.js_runtime.deref().ptr,
+ node_address).root(&roots);
+ debug!("clicked on {:s}", node.deref().debug_str());
// Traverse node generations until a node that is an element is
// found.
- while !node.is_element() {
- match node.parent_node() {
- Some(parent) => node = parent,
+ while !node.deref().is_element() {
+ match node.deref().parent_node() {
+ Some(parent) => node = parent.root(&roots),
None => break,
}
}
- if node.is_element() {
- let element: JS<Element> = ElementCast::to(&node).unwrap();
+ if node.deref().is_element() {
+ let element: &JSRef<Element> = ElementCast::to_ref(&*node).unwrap();
if "a" == element.get().local_name {
- let roots = RootCollection::new();
- let element = element.root(&roots);
- self.load_url_from_element(page, &element.root_ref())
+ self.load_url_from_element(page, element)
}
}
}
@@ -1112,6 +1116,7 @@ impl ScriptTask {
MouseDownEvent(..) => {}
MouseUpEvent(..) => {}
MouseMoveEvent(point) => {
+ let roots = RootCollection::new();
let mut page_tree = self.page_tree.borrow_mut();
let page = get_page(&mut *page_tree, pipeline_id);
match page.get_nodes_under_mouse(&point) {
@@ -1124,6 +1129,7 @@ impl ScriptTask {
match *mouse_over_targets {
Some(ref mut mouse_over_targets) => {
for node in mouse_over_targets.mut_iter() {
+ let mut node = node.root(&roots);
node.set_hover_state(false);
}
}
@@ -1131,14 +1137,14 @@ impl ScriptTask {
}
for node_address in node_address.iter() {
- let mut node: JS<Node> =
- NodeHelpers::from_untrusted_node_address(
- self.js_runtime.deref().ptr, *node_address);
+ let mut node =
+ node::from_untrusted_node_address(
+ self.js_runtime.deref().ptr, *node_address).root(&roots);
// Traverse node generations until a node that is an element is
// found.
while !node.is_element() {
match node.parent_node() {
- Some(parent) => node = parent,
+ Some(parent) => node = parent.root(&roots),
None => break,
}
}
@@ -1149,12 +1155,12 @@ impl ScriptTask {
match *mouse_over_targets {
Some(ref mouse_over_targets) => {
if !target_compare {
- target_compare = !mouse_over_targets.contains(&node);
+ target_compare = !mouse_over_targets.contains(&node.unrooted());
}
}
None => {}
}
- target_list.push(node);
+ target_list.push(node.unrooted());
}
}
match *mouse_over_targets {
@@ -1182,9 +1188,10 @@ impl ScriptTask {
}
fn load_url_from_element(&self, page: &Page, element: &JSRef<Element>) {
+ let roots = RootCollection::new();
// if the node's element is "a," load url from href attr
- let attr = element.unrooted().get_attribute(Null, "href");
- for href in attr.iter() {
+ let attr = element.get_attribute(Null, "href");
+ for href in attr.root(&roots).iter() {
debug!("ScriptTask: clicked on link to {:s}", href.get().Value());
let click_frag = href.get().value_ref().starts_with("#");
let base_url = Some(page.get_url());
@@ -1192,8 +1199,8 @@ impl ScriptTask {
let url = parse_url(href.get().value_ref(), base_url);
if click_frag {
- match page.find_fragment_node(url.fragment.unwrap()) {
- Some(node) => self.scroll_fragment_point(page.id, node),
+ match page.find_fragment_node(url.fragment.unwrap()).root(&roots) {
+ Some(node) => self.scroll_fragment_point(page.id, &*node),
None => {}
}
} else {