diff options
Diffstat (limited to 'src')
108 files changed, 1567 insertions, 997 deletions
diff --git a/src/components/script/dom/attr.rs b/src/components/script/dom/attr.rs index 0ca2fb2889e..5b5fc39d1c9 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::Element; use dom::node::Node; @@ -57,7 +57,7 @@ impl Attr { } } - pub fn new(window: &JS<Window>, local_name: DOMString, value: DOMString, + pub fn new(window: &JSRef<Window>, local_name: DOMString, value: DOMString, name: DOMString, namespace: Namespace, prefix: Option<DOMString>, owner: JS<Element>) -> JS<Attr> { let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner); diff --git a/src/components/script/dom/attrlist.rs b/src/components/script/dom/attrlist.rs index cfa6c2c083f..ed476897c82 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::Element; use dom::window::Window; @@ -25,8 +25,8 @@ impl AttrList { } } - pub fn new(window: &JS<Window>, elem: &JS<Element>) -> JS<AttrList> { - reflect_dom_object(~AttrList::new_inherited(window.clone(), elem.clone()), + pub fn new(window: &JSRef<Window>, elem: &JSRef<Element>) -> JS<AttrList> { + reflect_dom_object(~AttrList::new_inherited(window.unrooted(), elem.unrooted()), window, AttrListBinding::Wrap) } diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index cb3fc862c64..5d4f6cc9bf4 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -281,6 +281,7 @@ class CGMethodCall(CGThing): isDefinitelyObject=True), { "declName" : "arg%d" % distinguishingIndex, + "simpleDeclName" : "arg%d" % distinguishingIndex, "holderName" : ("arg%d" % distinguishingIndex) + "_holder", "val" : distinguishingArg }) @@ -551,12 +552,21 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, templateBody += ( "} else {\n" + CGIndenter(onFailureNotAnObject(failureCode)).define() + - "}") + "}\n") if type.nullable(): templateBody = handleDefaultNull(templateBody, "None") else: assert(defaultValue is None) + #if type.isGeckoInterface() and not type.unroll().inner.isCallback(): + # if type.nullable() or isOptional: + # + # else: + # + # templateBody = CGList([CGGeneric(templateBody), + # CGGeneric("\n"), + # CGGeneric(rootBody)]).define() + return templateBody assert not (isEnforceRange and isClamp) # These are mutually exclusive @@ -888,6 +898,18 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements, # Add an empty CGGeneric to get an extra newline after the argument # conversion. result.append(CGGeneric("")) + + type = declType.define() if declType else None + if type and 'JS<' in type: + if dealWithOptional or 'Option<' in type: + rootBody = """let ${simpleDeclName} = ${declName}.as_ref().map(|inner| { + inner.root(&roots) //second root code +});""" + else: + rootBody = "let ${simpleDeclName} = ${declName}.root(&roots); //third root code" + result.append(CGGeneric(string.Template(rootBody).substitute(replacements))) + result.append(CGGeneric("")) + return result; def convertConstIDLValueToJSVal(value): @@ -929,6 +951,7 @@ class CGArgumentConverter(CGThing): } self.replacementVariables = { "declName" : "arg%d" % index, + "simpleDeclName" : "arg%d" % index, "holderName" : ("arg%d" % index) + "_holder" } self.replacementVariables["val"] = string.Template( @@ -1691,6 +1714,8 @@ class Argument(): A class for outputting the type and name of an argument """ def __init__(self, argType, name, default=None, mutable=False): + if argType and 'JS<' in argType: + argType = argType.replace('JS<', 'JSRef<') self.argType = argType self.name = name self.default = default @@ -1763,7 +1788,7 @@ class CGAbstractMethod(CGThing): def _returnType(self): return (" -> %s" % self.returnType) if self.returnType != "void" else "" def _unsafe_open(self): - return "\n unsafe {" if self.unsafe else "" + return "\n unsafe {\n let roots = RootCollection::new();\n" if self.unsafe else "" def _unsafe_close(self): return "\n }\n" if self.unsafe else "" @@ -1809,7 +1834,7 @@ class CGWrapMethod(CGAbstractMethod): def __init__(self, descriptor): assert descriptor.interface.hasInterfacePrototypeObject() if not descriptor.createGlobal: - args = [Argument('*JSContext', 'aCx'), Argument('&JS<Window>', 'aScope'), + args = [Argument('*JSContext', 'aCx'), Argument('&JSRef<Window>', 'aScope'), Argument("~" + descriptor.concreteType, 'aObject', mutable=True)] else: args = [Argument('*JSContext', 'aCx'), @@ -2277,7 +2302,12 @@ class CGPerSignatureCall(CGThing): def getArgc(self): return "argc" def getArguments(self): - return [(a, "arg" + str(i)) for (i, a) in enumerate(self.arguments)] + def process(arg, i): + argVal = "arg" + str(i) + if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback(): + argVal += ".root_ref()" + return argVal + return [(a, process(a, i)) for (i, a) in enumerate(self.arguments)] def isFallible(self): return not 'infallible' in self.extendedAttributes @@ -2452,8 +2482,10 @@ class CGSpecializedMethod(CGAbstractExternMethod): argsPre = [] if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] + extraPre = """ let mut abstract_this = %s::from_raw(this); + let abstract_this = abstract_this.root(&roots); +""" % abstractName + argsPre = ['&mut abstract_this.root_ref()'] return CGWrapper(CGMethodCall(argsPre, nativeName, self.method.isStatic(), self.descriptor, self.method), pre=extraPre + @@ -2480,10 +2512,8 @@ class CGGenericGetter(CGAbstractBindingMethod): def generate_code(self): return CGIndenter(CGGeneric( - "return with_gc_disabled(cx, || {\n" - " let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" - " CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp)\n" - "});\n")) + "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, &*vp));\n" + "return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, &*vp);\n")) class CGSpecializedGetter(CGAbstractExternMethod): """ @@ -2509,8 +2539,10 @@ class CGSpecializedGetter(CGAbstractExternMethod): getter=True)) if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] + extraPre = """ let mut abstract_this = %s::from_raw(this); + let abstract_this = abstract_this.root(&roots); +""" % abstractName + argsPre = ['&mut abstract_this.root_ref()'] if self.attr.type.nullable() or not infallible: nativeName = "Get" + nativeName return CGWrapper(CGIndenter(CGGetterCall(argsPre, self.attr.type, nativeName, @@ -2541,10 +2573,7 @@ class CGGenericSetter(CGAbstractBindingMethod): "let undef = UndefinedValue();\n" "let argv: *JSVal = if argc != 0 { JS_ARGV(cx, vp as *JSVal) } else { &undef as *JSVal };\n" "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp as *JSVal));\n" - "let ok = with_gc_disabled(cx, || {\n" - " CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv)\n" - "});\n" - "if ok == 0 {\n" + "if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *libc::c_void, argv) == 0 {\n" " return 0;\n" "}\n" "*vp = UndefinedValue();\n" @@ -2571,8 +2600,10 @@ class CGSpecializedSetter(CGAbstractExternMethod): extraPre = '' if name in self.descriptor.needsAbstract: abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType) - extraPre = ' let mut abstract_this = %s::from_raw(this);\n' % abstractName - argsPre = ['&mut abstract_this'] + extraPre = """ let mut abstract_this = %s::from_raw(this); + let abstract_this = abstract_this.root(&roots); +""" % abstractName + argsPre = ['&mut abstract_this.root_ref()'] return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName, self.descriptor, self.attr)), pre=extraPre + @@ -3402,6 +3433,7 @@ class CGProxySpecialOperation(CGPerSignatureCall): treatNullAs=argument.treatNullAs) templateValues = { "declName": argument.identifier.name, + "simpleDeclName": argument.identifier.name, "holderName": argument.identifier.name + "_holder", "val": "(*desc).value", "valPtr": "&(*desc).value" @@ -3411,7 +3443,12 @@ class CGProxySpecialOperation(CGPerSignatureCall): self.cgRoot.prepend(CGGeneric("let mut found = false;")) def getArguments(self): - args = [(a, a.identifier.name) for a in self.arguments] + def process(arg): + argVal = arg.identifier.name + if arg.type.isGeckoInterface() and not arg.type.unroll().inner.isCallback(): + argVal += ".root_ref()" + return argVal + args = [(a, process(a)) for a in self.arguments] if self.idlNode.isGetter(): args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean], self.idlNode), @@ -3825,11 +3862,13 @@ class CGClassConstructHook(CGAbstractExternMethod): def generate_code(self): preamble = """ + let roots = RootCollection::new(); let global = global_object_for_js_object(JS_CALLEE(cx, &*vp).to_object()); + let global = global.root(&roots); let obj = global.reflector().get_jsobject(); """ nativeName = MakeNativeName(self._ctor.identifier.name) - callGenerator = CGMethodCall(["&global"], nativeName, True, + callGenerator = CGMethodCall(["&global.root_ref()"], nativeName, True, self.descriptor, self._ctor) return preamble + callGenerator.define(); @@ -4067,6 +4106,7 @@ class CGDictionary(CGThing): return string.Template( "impl ${selfName} {\n" " pub fn new(cx: *JSContext, val: JSVal) -> Result<${selfName}, ()> {\n" + " let roots = RootCollection::new();\n" # XXXjdm need to root dict members outside of Init " let object = if val.is_null_or_undefined() {\n" " ptr::null()\n" " } else if val.is_object() {\n" @@ -4266,7 +4306,7 @@ class CGBindingRoot(CGThing): 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}', 'dom::types::*', 'dom::bindings', - 'dom::bindings::js::JS', + 'dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}', 'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}', 'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}', 'dom::bindings::utils::{dom_object_slot, DOM_OBJECT_SLOT, DOMClass}', @@ -4279,8 +4319,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{Reflectable}', 'dom::bindings::utils::{squirrel_away_unique}', 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', - 'dom::bindings::utils::{VoidVal, with_gc_disabled}', - 'dom::bindings::utils::{with_gc_enabled}', + 'dom::bindings::utils::VoidVal', 'dom::bindings::utils::get_dictionary_property', 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface}', @@ -5057,11 +5096,8 @@ class CallbackMethod(CallbackMember): replacements["argc"] = "0" return string.Template("${getCallable}" "let ok = unsafe {\n" - " //JS_AllowGC(cx); // It's unsafe to enable GC at arbitrary points during Rust execution; leave it disabled\n" - " let ok = JS_CallFunctionValue(cx, ${thisObj}, callable,\n" - " ${argc}, ${argv}, &rval);\n" - " //JS_InhibitGC(cx);\n" - " ok\n" + " JS_CallFunctionValue(cx, ${thisObj}, callable,\n" + " ${argc}, ${argv}, &rval)\n" "};\n" "if ok == 0 {\n" " return${errorReturn};\n" @@ -5209,7 +5245,7 @@ class GlobalGenRoots(): # TODO - Generate the methods we want return CGImports(CGRegisterProtos(config), [ 'dom::bindings::codegen', - 'dom::bindings::js::JS', + 'dom::bindings::js::{JS, JSRef}', 'dom::window::Window', 'script_task::JSPageInfo', ]) @@ -5241,7 +5277,7 @@ 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;\n"), + CGGeneric("use dom::bindings::js::{JS, JSRef};\n"), CGGeneric("use dom::bindings::trace::JSTraceable;\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"), CGGeneric("use js::jsapi::JSTracer;\n\n")] @@ -5286,6 +5322,14 @@ class GlobalGenRoots(): assert!(base.get().${checkFn}()); base.clone().transmute() } + + fn from_ref<'a, 'b, T: ${fromBound}>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, Self> { + unsafe { derived.transmute() } + } + + fn from_mut_ref<'a, 'b, T: ${fromBound}>(derived: &'a mut JSRef<'b, T>) -> &'a mut JSRef<'b, Self> { + unsafe { derived.transmute_mut() } + } } ''').substitute({'checkFn': 'is_' + name.lower(), 'castTraitName': name + 'Cast', diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index 6721f3f5dde..90c0251ba2f 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -2,9 +2,9 @@ * 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::str::ByteString; -use dom::bindings::utils::Reflectable; +use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::utils::jsstring_to_str; use dom::bindings::utils::unwrap_jsmanaged; use servo_util::str::DOMString; @@ -293,9 +293,9 @@ impl FromJSValConvertible<()> for ByteString { } } -impl<T: Reflectable> ToJSValConvertible for JS<T> { +impl ToJSValConvertible for Reflector { fn to_jsval(&self, cx: *JSContext) -> JSVal { - let obj = self.reflector().get_jsobject(); + let obj = self.get_jsobject(); assert!(obj.is_not_null()); let mut value = ObjectValue(unsafe { &*obj }); if unsafe { JS_WrapValue(cx, &mut value as *mut JSVal as *JSVal) } == 0 { @@ -316,6 +316,18 @@ impl<T: Reflectable+IDLInterface> FromJSValConvertible<()> for JS<T> { } } +impl<T: Reflectable> ToJSValConvertible for JS<T> { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + self.reflector().to_jsval(cx) + } +} + +impl<'a, T: Reflectable> ToJSValConvertible for JSRef<'a, T> { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + self.reflector().to_jsval(cx) + } +} + impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> { fn to_jsval(&self, cx: *JSContext) -> JSVal { match self { diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 10aec5424bc..dac459f9c03 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -4,11 +4,13 @@ use dom::bindings::utils::{Reflector, Reflectable}; use dom::window::Window; -use js::jsapi::JSContext; +use js::jsapi::{JSObject, JSContext}; use layout_interface::TrustedNodeAddress; use std::cast; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; +use std::ptr; +//use std::ops::{Deref, DerefMut}; pub struct JS<T> { ptr: RefCell<*mut T> @@ -31,8 +33,8 @@ impl <T> Clone for JS<T> { impl<T: Reflectable> JS<T> { pub fn new(obj: ~T, - window: &JS<Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~T) -> JS<T>) -> JS<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) } @@ -49,6 +51,10 @@ impl<T: Reflectable> JS<T> { ptr: RefCell::new(addr as *mut T) } } + + pub fn root<'a>(&self, collection: &'a RootCollection) -> Root<'a, T> { + collection.new_root(self) + } } impl<T: Reflectable> Reflectable for JS<T> { @@ -94,3 +100,213 @@ impl<From, To> JS<From> { cast::transmute_copy(self) } } + +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>> { + fn root_ref<'a>(&'a self) -> Option<JSRef<'a, T>> { + self.as_ref().map(|root| root.root_ref()) + } +} + +#[deriving(Eq, Clone)] +struct RootReference(*JSObject); + +impl RootReference { + fn new<'a, T: Reflectable>(unrooted: &Root<'a, T>) -> RootReference { + RootReference(unrooted.rooted()) + } + + fn null() -> RootReference { + RootReference(ptr::null()) + } +} + +static MAX_STACK_ROOTS: uint = 10; + +pub struct RootCollection { + roots: [Cell<RootReference>, ..MAX_STACK_ROOTS], + current: Cell<uint>, +} + +impl RootCollection { + pub fn new() -> RootCollection { + RootCollection { + roots: [Cell::new(RootReference::null()), ..MAX_STACK_ROOTS], + current: Cell::new(0), + } + } + + fn new_root<'a, T: Reflectable>(&'a self, unrooted: &JS<T>) -> Root<'a, T> { + Root::new(self, unrooted) + } + + fn root_impl(&self, unrooted: RootReference) { + let current = self.current.get(); + assert!(current < MAX_STACK_ROOTS); + self.roots[current].set(unrooted); + self.current.set(current + 1); + } + + fn root<'a, T: Reflectable>(&self, unrooted: &Root<'a, T>) { + self.root_impl(RootReference::new(unrooted)); + } + + pub fn root_raw(&self, unrooted: *JSObject) { + self.root_impl(RootReference(unrooted)); + } + + fn unroot_impl(&self, rooted: RootReference) { + let mut current = self.current.get(); + assert!(current != 0); + current -= 1; + 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>) { + self.unroot_impl(RootReference::new(rooted)); + } + + pub fn unroot_raw(&self, rooted: *JSObject) { + self.unroot_impl(RootReference(rooted)); + } +} + +pub struct Root<'a, T> { + root_list: &'a RootCollection, + ptr: RefCell<*mut T>, +} + +impl<'a, T: Reflectable> Root<'a, T> { + fn new(roots: &'a RootCollection, unrooted: &JS<T>) -> Root<'a, T> { + let root = Root { + root_list: roots, + ptr: unrooted.ptr.clone() + }; + roots.root(&root); + root + } + + pub fn get<'a>(&'a self) -> &'a T { + unsafe { + let borrow = self.ptr.borrow(); + &**borrow + } + } + + pub fn get_mut<'a>(&'a mut self) -> &'a mut T { + unsafe { + let mut borrow = self.ptr.borrow_mut(); + &mut **borrow + } + } + + fn rooted(&self) -> *JSObject { + self.reflector().get_jsobject() + } + + pub fn root_ref<'b>(&'b self) -> JSRef<'b,T> { + unsafe { + JSRef { + ptr: self.ptr.clone(), + chain: ::std::cast::transmute_region(&()), + } + } + } +} + +#[unsafe_destructor] +impl<'a, T: Reflectable> Drop for Root<'a, T> { + fn drop(&mut self) { + self.root_list.unroot(self); + } +} + +impl<'a, T: Reflectable> Reflectable for Root<'a, T> { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.get().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.get_mut().mut_reflector() + } +} + +/*impl<'a, T> Deref for Root<'a, T> { + fn deref<'a>(&'a self) -> &'a T { + self.get() + } +} + +impl<'a, T> DerefMut for Root<'a, T> { + fn deref_mut<'a>(&'a mut self) -> &'a 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> { + ptr: RefCell<*mut T>, + chain: &'a (), +} + +impl<'a, T> Clone for JSRef<'a, T> { + fn clone(&self) -> JSRef<'a, T> { + JSRef { + ptr: self.ptr.clone(), + chain: self.chain + } + } +} + +impl<'a, T> Eq for JSRef<'a, T> { + fn eq(&self, other: &JSRef<T>) -> bool { + self.ptr == other.ptr + } +} + +impl<'a,T> JSRef<'a,T> { + pub fn get<'a>(&'a self) -> &'a T { + unsafe { + let borrow = self.ptr.borrow(); + &**borrow + } + } + + pub fn get_mut<'a>(&'a mut self) -> &'a mut T { + let mut borrowed = self.ptr.borrow_mut(); + unsafe { + &mut **borrowed + } + } + + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute<'b, To>(&'b self) -> &'b JSRef<'a, To> { + cast::transmute(self) + } + + //XXXjdm It would be lovely if this could be private. + pub unsafe fn transmute_mut<'b, To>(&'b mut self) -> &'b mut JSRef<'a, To> { + cast::transmute(self) + } + + pub fn unrooted(&self) -> JS<T> { + JS { + ptr: self.ptr.clone() + } + } +} + +impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> { + fn reflector<'a>(&'a self) -> &'a Reflector { + self.get().reflector() + } + + fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { + self.get_mut().mut_reflector() + } +} diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 554c67e8dc6..cbbeddb8594 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -6,6 +6,7 @@ use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSTRACE_OBJECT}; +use js::jsval::JSVal; use libc; use std::cast; @@ -42,6 +43,22 @@ pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } +pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { + if !val.is_gcthing() { + return; + } + + unsafe { + description.to_c_str().with_ref(|name| { + (*tracer).debugPrinter = ptr::null(); + (*tracer).debugPrintIndex = -1; + (*tracer).debugPrintArg = name as *libc::c_void; + debug!("tracing value {:s}", description); + JS_CallTracer(tracer as *JSTracer, val.to_gcthing(), val.trace_kind()); + }); + } +} + pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) { trace_object(tracer, description, reflector.get_jsobject()) } @@ -132,3 +149,10 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<*JSObject> { Ok(()) } } + +impl<S: Encoder<E>, E> Encodable<S, E> for Traceable<JSVal> { + fn encode(&self, s: &mut S) -> Result<(), E> { + trace_jsval(get_jstracer(s), "val", **self); + Ok(()) + } +} diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 417d4c434c2..7f240070ea1 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::trace::Untraceable; use dom::browsercontext; use dom::window; @@ -37,7 +37,6 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString}; -use js::jsapi::{JS_AllowGC, JS_InhibitGC}; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsval::JSVal; use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue}; @@ -390,8 +389,8 @@ pub trait Reflectable { pub fn reflect_dom_object<T: Reflectable> (obj: ~T, - window: &JS<window::Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<window::Window>, ~T) -> JS<T>) + window: &JSRef<window::Window>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<window::Window>, ~T) -> JS<T>) -> JS<T> { JS::new(obj, window, wrap_fn) } @@ -637,26 +636,6 @@ pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext { cx_for_dom_reflector(obj.reflector().get_jsobject()) } -/// Execute arbitrary code with the JS GC enabled, then disable it afterwards. -pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_AllowGC(cx); - let rv = f(); - JS_InhibitGC(cx); - rv - } -} - -/// Execute arbitrary code with the JS GC disabled, then enable it afterwards. -pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_InhibitGC(cx); - let rv = f(); - JS_AllowGC(cx); - rv - } -} - /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name /// for details. #[deriving(Eq)] diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs index 04964af092e..8dba1775ff6 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::bindings::codegen::BindingDeclarations::BlobBinding; @@ -23,15 +23,15 @@ impl Blob { } } - pub fn new(window: &JS<Window>) -> JS<Blob> { - reflect_dom_object(~Blob::new_inherited(window.clone()), + pub fn new(window: &JSRef<Window>) -> JS<Blob> { + reflect_dom_object(~Blob::new_inherited(window.unrooted()), window, BlobBinding::Wrap) } } impl Blob { - pub fn Constructor(window: &JS<Window>) -> Fallible<JS<Blob>> { + pub fn Constructor(window: &JSRef<Window>) -> Fallible<JS<Blob>> { Ok(Blob::new(window)) } @@ -44,7 +44,9 @@ impl Blob { } pub fn Slice(&self, _start: Option<i64>, _end: Option<i64>, _contentType: Option<DOMString>) -> JS<Blob> { - Blob::new(&self.window) + let roots = RootCollection::new(); + let window = self.window.root(&roots); + Blob::new(&window.root_ref()) } pub fn Close(&self) {} diff --git a/src/components/script/dom/clientrect.rs b/src/components/script/dom/clientrect.rs index 3d84944dfaa..977c4569bf5 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; use servo_util::geometry::Au; @@ -32,10 +32,10 @@ impl ClientRect { } } - pub fn new(window: &JS<Window>, + pub fn new(window: &JSRef<Window>, top: Au, bottom: Au, left: Au, right: Au) -> JS<ClientRect> { - let rect = ClientRect::new_inherited(window.clone(), top, bottom, left, right); + 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 906cfaa65e9..abd87c47455 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::clientrect::ClientRect; use dom::window::Window; @@ -25,9 +25,9 @@ impl ClientRectList { } } - pub fn new(window: &JS<Window>, + pub fn new(window: &JSRef<Window>, rects: Vec<JS<ClientRect>>) -> JS<ClientRectList> { - reflect_dom_object(~ClientRectList::new_inherited(window.clone(), rects), + reflect_dom_object(~ClientRectList::new_inherited(window.unrooted(), rects), window, ClientRectListBinding::Wrap) } diff --git a/src/components/script/dom/comment.rs b/src/components/script/dom/comment.rs index d6681c6ba2a..a0786441fe6 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::Fallible; use dom::characterdata::CharacterData; use dom::document::Document; @@ -35,12 +35,16 @@ impl Comment { } } - pub fn new(text: DOMString, document: &JS<Document>) -> JS<Comment> { - let node = Comment::new_inherited(text, document.clone()); + pub fn new(text: DOMString, document: &JSRef<Document>) -> JS<Comment> { + let node = Comment::new_inherited(text, document.unrooted()); Node::reflect_node(~node, document, CommentBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, data: DOMString) -> Fallible<JS<Comment>> { - Ok(Comment::new(data, &owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>, data: DOMString) -> Fallible<JS<Comment>> { + let roots = RootCollection::new(); + let document = owner.get().Document(); + let document = document.root(&roots); + + Ok(Comment::new(data, &document.root_ref())) } } diff --git a/src/components/script/dom/console.rs b/src/components/script/dom/console.rs index 8e8081dcd83..a7908c6bc4f 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; +use dom::bindings::js::{JS, JSRef}; 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: &JS<Window>) -> JS<Console> { + pub fn new(window: &JSRef<Window>) -> JS<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 fdf47a5467d..44b141dcea5 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -7,7 +7,7 @@ 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::BindingDeclarations::DocumentBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::trace::Untraceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError}; @@ -79,16 +79,18 @@ impl DocumentDerived for EventTarget { impl Document { pub fn reflect_document<D: Reflectable+DocumentBase> (document: ~D, - window: &JS<Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~D) -> JS<D>) + window: &JSRef<Window>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~D) -> JS<D>) -> JS<D> { + let roots = RootCollection::new(); assert!(document.reflector().get_jsobject().is_null()); let raw_doc = reflect_dom_object(document, window, wrap_fn); 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); + node.get_mut().set_owner_doc(&document_root.root_ref()); raw_doc } @@ -122,8 +124,8 @@ impl Document { } } - pub fn new(window: &JS<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> JS<Document> { - let document = Document::new_inherited(window.clone(), url, doctype, content_type); + pub fn new(window: &JSRef<Window>, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>) -> JS<Document> { + let document = Document::new_inherited(window.unrooted(), url, doctype, content_type); Document::reflect_document(~document, window, DocumentBinding::Wrap) } } @@ -136,7 +138,7 @@ impl Document { impl Document { // http://dom.spec.whatwg.org/#dom-document - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<Document>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<Document>> { Ok(Document::new(owner, None, NonHTMLDocument, None)) } } @@ -155,7 +157,9 @@ impl Document { // http://dom.spec.whatwg.org/#dom-document-implementation pub fn Implementation(&mut self) -> JS<DOMImplementation> { if self.implementation.is_none() { - self.implementation = Some(DOMImplementation::new(&self.window)); + let roots = RootCollection::new(); + let window = self.window.root(&roots); + self.implementation = Some(DOMImplementation::new(&window.root_ref())); } self.implementation.get_ref().clone() } @@ -212,22 +216,30 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagname - pub fn GetElementsByTagName(&self, abstract_self: &JS<Document>, tag_name: DOMString) -> JS<HTMLCollection> { - HTMLCollection::by_tag_name(&self.window, &NodeCast::from(abstract_self), tag_name) + pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Document>, tag_name: DOMString) -> JS<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) } // http://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens - pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<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) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + let namespace = match maybe_ns { Some(namespace) => Namespace::from_str(namespace), None => Null }; - HTMLCollection::by_tag_name_ns(&self.window, &NodeCast::from(abstract_self), tag_name, namespace) + HTMLCollection::by_tag_name_ns(&window.root_ref(), NodeCast::from_ref(abstract_self), tag_name, namespace) } // http://dom.spec.whatwg.org/#dom-document-getelementsbyclassname - pub fn GetElementsByClassName(&self, abstract_self: &JS<Document>, classes: DOMString) -> JS<HTMLCollection> { - HTMLCollection::by_class_name(&self.window, &NodeCast::from(abstract_self), classes) + pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Document>, classes: DOMString) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + + HTMLCollection::by_class_name(&window.root_ref(), NodeCast::from_ref(abstract_self), classes) } // http://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid @@ -239,7 +251,7 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-createelement - pub fn CreateElement(&self, abstract_self: &JS<Document>, local_name: DOMString) + pub fn CreateElement(&self, abstract_self: &JSRef<Document>, local_name: DOMString) -> Fallible<JS<Element>> { if xml_name_type(local_name) == InvalidXMLName { debug!("Not a valid element name"); @@ -250,7 +262,7 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-createelementns - pub fn CreateElementNS(&self, abstract_self: &JS<Document>, + pub fn CreateElementNS(&self, abstract_self: &JSRef<Document>, namespace: Option<DOMString>, qualified_name: DOMString) -> Fallible<JS<Element>> { let ns = Namespace::from_str(null_str_as_empty_ref(&namespace)); @@ -296,23 +308,23 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-createdocumentfragment - pub fn CreateDocumentFragment(&self, abstract_self: &JS<Document>) -> JS<DocumentFragment> { + pub fn CreateDocumentFragment(&self, abstract_self: &JSRef<Document>) -> JS<DocumentFragment> { DocumentFragment::new(abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createtextnode - pub fn CreateTextNode(&self, abstract_self: &JS<Document>, data: DOMString) + pub fn CreateTextNode(&self, abstract_self: &JSRef<Document>, data: DOMString) -> JS<Text> { Text::new(data, abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createcomment - pub fn CreateComment(&self, abstract_self: &JS<Document>, data: DOMString) -> JS<Comment> { + pub fn CreateComment(&self, abstract_self: &JSRef<Document>, data: DOMString) -> JS<Comment> { Comment::new(data, abstract_self) } // http://dom.spec.whatwg.org/#dom-document-createprocessinginstruction - pub fn CreateProcessingInstruction(&self, abstract_self: &JS<Document>, target: DOMString, + pub fn CreateProcessingInstruction(&self, abstract_self: &JSRef<Document>, target: DOMString, data: DOMString) -> Fallible<JS<ProcessingInstruction>> { // Step 1. if xml_name_type(target) == InvalidXMLName { @@ -329,9 +341,9 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-importnode - pub fn ImportNode(&self, abstract_self: &JS<Document>, node: &JS<Node>, deep: bool) -> Fallible<JS<Node>> { + pub fn ImportNode(&self, abstract_self: &JSRef<Document>, node: &JSRef<Node>, deep: bool) -> Fallible<JS<Node>> { // Step 1. - if node.is_document() { + if node.unrooted().is_document() { return Err(NotSupported); } @@ -345,9 +357,9 @@ impl Document { } // http://dom.spec.whatwg.org/#dom-document-adoptnode - pub fn AdoptNode(&self, abstract_self: &JS<Document>, node: &JS<Node>) -> Fallible<JS<Node>> { + pub fn AdoptNode(&self, abstract_self: &JSRef<Document>, node: &JSRef<Node>) -> Fallible<JS<Node>> { // Step 1. - if node.is_document() { + if node.unrooted().is_document() { return Err(NotSupported); } @@ -356,22 +368,25 @@ impl Document { Node::adopt(&mut adoptee, abstract_self); // Step 3. - Ok(adoptee) + Ok(adoptee.unrooted()) } // http://dom.spec.whatwg.org/#dom-document-createevent pub fn CreateEvent(&self, interface: DOMString) -> Fallible<JS<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(&self.window))), - "mouseevents" | "mouseevent" => Ok(EventCast::from(&MouseEvent::new(&self.window))), - "htmlevents" | "events" | "event" => Ok(Event::new(&self.window)), + "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())), _ => Err(NotSupported) } } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn Title(&self, _: &JS<Document>) -> DOMString { + pub fn Title(&self, _: &JSRef<Document>) -> DOMString { let mut title = ~""; self.GetDocumentElement().map(|root| { let root: JS<Node> = NodeCast::from(&root); @@ -392,7 +407,9 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#document.title - pub fn SetTitle(&self, abstract_self: &JS<Document>, title: DOMString) -> ErrorResult { + 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| { @@ -405,18 +422,25 @@ impl Document { match title_node { Some(ref mut title_node) => { - for mut title_child in title_node.children() { - assert!(title_node.RemoveChild(&mut title_child).is_ok()); + 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()); } let new_text = self.CreateTextNode(abstract_self, title.clone()); - assert!(title_node.AppendChild(&mut NodeCast::from(&new_text)).is_ok()); + let new_text = new_text.root(&roots); + + assert!(title_node.AppendChild(NodeCast::from_mut_ref(&mut new_text.root_ref())).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 new_text = self.CreateTextNode(abstract_self, title.clone()); - assert!(new_title.AppendChild(&mut NodeCast::from(&new_text)).is_ok()); - assert!(head.AppendChild(&mut new_title).is_ok()); + let new_text = new_text.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()); }, } }); @@ -441,7 +465,7 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn GetBody(&self, _: &JS<Document>) -> Option<JS<HTMLElement>> { + pub fn GetBody(&self, _: &JSRef<Document>) -> Option<JS<HTMLElement>> { self.get_html_element().and_then(|root| { let node: JS<Node> = NodeCast::from(&root); node.children().find(|child| { @@ -455,7 +479,9 @@ impl Document { } // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-body - pub fn SetBody(&self, abstract_self: &JS<Document>, new_body: Option<JS<HTMLElement>>) -> ErrorResult { + pub fn SetBody(&self, abstract_self: &JSRef<Document>, new_body: Option<JSRef<HTMLElement>>) -> ErrorResult { + let roots = RootCollection::new(); + // Step 1. match new_body { Some(ref node) => { @@ -469,7 +495,7 @@ impl Document { // Step 2. let old_body: Option<JS<HTMLElement>> = self.GetBody(abstract_self); - if old_body == new_body { + if old_body == new_body.as_ref().map(|new_body| new_body.unrooted()) { return Ok(()); } @@ -478,14 +504,18 @@ impl Document { // Step 4. None => return Err(HierarchyRequest), Some(root) => { - let mut new_body: JS<Node> = NodeCast::from(&new_body.unwrap()); + 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); match old_body { Some(child) => { - let mut child: JS<Node> = NodeCast::from(&child); - assert!(root.ReplaceChild(&mut new_body, &mut child).is_ok()) + let child: JS<Node> = NodeCast::from(&child); + let child = child.root(&roots); + + assert!(root.ReplaceChild(new_body, &mut child.root_ref()).is_ok()) } - None => assert!(root.AppendChild(&mut new_body).is_ok()) + None => assert!(root.AppendChild(new_body).is_ok()) }; } } @@ -495,132 +525,159 @@ impl Document { // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-getelementsbyname pub fn GetElementsByName(&self, name: DOMString) -> JS<NodeList> { self.createNodeList(|node| { - if !node.is_element() { + if !node.get().is_element() { return false; } - let element: JS<Element> = ElementCast::to(node).unwrap(); + let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); element.get_attribute(Null, "name").map_or(false, |attr| { attr.get().value_ref() == name }) }) } - pub fn Images(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Images(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct ImagesFilter; impl CollectionFilter for ImagesFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"img" } } let filter = ~ImagesFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Embeds(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Embeds(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct EmbedsFilter; impl CollectionFilter for EmbedsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"embed" } } let filter = ~EmbedsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Plugins(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Plugins(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { // FIXME: https://github.com/mozilla/servo/issues/1847 self.Embeds(abstract_self) } - pub fn Links(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Links(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct LinksFilter; impl CollectionFilter for LinksFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { (elem.get().local_name == ~"a" || elem.get().local_name == ~"area") && - elem.get_attribute(Null, "href").is_some() + elem.unrooted().get_attribute(Null, "href").is_some() } } let filter = ~LinksFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Forms(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Forms(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct FormsFilter; impl CollectionFilter for FormsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"form" } } let filter = ~FormsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Scripts(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Scripts(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct ScriptsFilter; impl CollectionFilter for ScriptsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"script" } } let filter = ~ScriptsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Anchors(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Anchors(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: https://github.com/mozilla/servo/issues/1847 struct AnchorsFilter; impl CollectionFilter for AnchorsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - elem.get().local_name == ~"a" && elem.get_attribute(Null, "name").is_some() + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + elem.get().local_name == ~"a" && elem.unrooted().get_attribute(Null, "name").is_some() } } let filter = ~AnchorsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Applets(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { + pub fn Applets(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + // FIXME: This should be return OBJECT elements containing applets. struct AppletsFilter; impl CollectionFilter for AppletsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"applet" } } let filter = ~AppletsFilter; - HTMLCollection::create(&self.window, &NodeCast::from(abstract_self), filter) + HTMLCollection::create(&window.root_ref(), NodeCast::from_ref(abstract_self), filter) } - pub fn Location(&mut self, abstract_self: &JS<Document>) -> JS<Location> { - self.window.get_mut().Location(&abstract_self.get().window) + pub fn Location(&mut self, _abstract_self: &JSRef<Document>) -> JS<Location> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + self.window.get_mut().Location(&window.root_ref()) } - pub fn Children(&self, abstract_self: &JS<Document>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) + pub fn Children(&self, abstract_self: &JSRef<Document>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(abstract_self)) } - pub fn createNodeList(&self, callback: |node: &JS<Node>| -> bool) -> JS<NodeList> { + pub fn createNodeList(&self, callback: |node: &JSRef<Node>| -> bool) -> JS<NodeList> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + let mut nodes = vec!(); match self.GetDocumentElement() { None => {}, Some(root) => { let root: JS<Node> = NodeCast::from(&root); for child in root.traverse_preorder() { - if callback(&child) { - nodes.push(child.clone()); + let child = child.root(&roots); + if callback(&child.root_ref()) { + nodes.push(child.root_ref().unrooted()); } } } } - NodeList::new_simple_list(&self.window, nodes) + NodeList::new_simple_list(&window.root_ref(), nodes) } pub fn content_changed(&self) { @@ -638,14 +695,14 @@ impl Document { /// Remove any existing association between the provided id and any elements in this document. pub fn unregister_named_element(&mut self, - abstract_self: &JS<Element>, + abstract_self: &JSRef<Element>, id: DOMString) { let mut is_empty = false; match self.idmap.find_mut(&id) { None => {}, Some(elements) => { let position = elements.iter() - .position(|element| element == abstract_self) + .position(|element| element == &abstract_self.unrooted()) .expect("This element should be in registered."); elements.remove(position); is_empty = elements.is_empty(); @@ -658,10 +715,10 @@ impl Document { /// Associate an element present in this document with the provided id. pub fn register_named_element(&mut self, - element: &JS<Element>, + element: &JSRef<Element>, id: DOMString) { assert!({ - let node: JS<Node> = NodeCast::from(element); + let node: JS<Node> = NodeCast::from(&element.unrooted()); node.is_in_doc() }); @@ -670,7 +727,7 @@ impl Document { let root = self.GetDocumentElement().expect("The element is in the document, so there must be a document element."); match self.idmap.find_mut(&id) { Some(elements) => { - let new_node = NodeCast::from(element); + let new_node = NodeCast::from_ref(element); let mut head : uint = 0u; let root: JS<Node> = NodeCast::from(&root); for node in root.traverse_preorder() { @@ -679,18 +736,18 @@ impl Document { if elements.get(head) == &elem { head = head + 1; } - if new_node == node || head == elements.len() { + if new_node.unrooted() == node || head == elements.len() { break; } } None => {} } } - elements.insert(head, element.clone()); + elements.insert(head, element.unrooted()); return; }, None => (), } - self.idmap.insert(id, vec!(element.clone())); + self.idmap.insert(id, vec!(element.unrooted())); } } diff --git a/src/components/script/dom/documentfragment.rs b/src/components/script/dom/documentfragment.rs index 7346a5a98ef..e10e9e1204c 100644 --- a/src/components/script/dom/documentfragment.rs +++ b/src/components/script/dom/documentfragment.rs @@ -4,12 +4,12 @@ use dom::bindings::codegen::InheritTypes::{DocumentFragmentDerived, NodeCast}; use dom::bindings::codegen::BindingDeclarations::DocumentFragmentBinding; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::Fallible; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; -use dom::node::{DocumentFragmentNodeTypeId, Node}; +use dom::node::{DocumentFragmentNodeTypeId, Node, window_from_node}; use dom::window::Window; #[deriving(Encodable)] @@ -34,22 +34,26 @@ impl DocumentFragment { } } - pub fn new(document: &JS<Document>) -> JS<DocumentFragment> { - let node = DocumentFragment::new_inherited(document.clone()); + pub fn new(document: &JSRef<Document>) -> JS<DocumentFragment> { + let node = DocumentFragment::new_inherited(document.unrooted()); Node::reflect_node(~node, document, DocumentFragmentBinding::Wrap) } } impl DocumentFragment { - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DocumentFragment>> { - Ok(DocumentFragment::new(&owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<DocumentFragment>> { + let roots = RootCollection::new(); + let document = owner.get().Document(); + let document = document.root(&roots); + + Ok(DocumentFragment::new(&document.root_ref())) } } impl DocumentFragment { - pub fn Children(&self, abstract_self: &JS<DocumentFragment>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) + pub fn Children(&self, abstract_self: &JSRef<DocumentFragment>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = window_from_node(&abstract_self.unrooted()).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 856dde0e98e..dacce041f5c 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::node::{Node, DoctypeNodeTypeId}; @@ -45,12 +45,12 @@ impl DocumentType { pub fn new(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: &JS<Document>) + document: &JSRef<Document>) -> JS<DocumentType> { let documenttype = DocumentType::new_inherited(name, public_id, system_id, - document.clone()); + document.unrooted()); Node::reflect_node(~documenttype, document, DocumentTypeBinding::Wrap) } } diff --git a/src/components/script/dom/domexception.rs b/src/components/script/dom/domexception.rs index 6bb946e4bed..db562d08c71 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; +use dom::bindings::js::{JS, JSRef}; 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: &JS<Window>, code: DOMErrorName) -> JS<DOMException> { + pub fn new(window: &JSRef<Window>, code: DOMErrorName) -> JS<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 28d226ba406..e002cf9d28c 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; 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}; @@ -33,8 +33,8 @@ impl DOMImplementation { } } - pub fn new(owner: &JS<Window>) -> JS<DOMImplementation> { - reflect_dom_object(~DOMImplementation::new_inherited(owner.clone()), owner, + pub fn new(owner: &JSRef<Window>) -> JS<DOMImplementation> { + reflect_dom_object(~DOMImplementation::new_inherited(owner.unrooted()), owner, DOMImplementationBinding::Wrap) } } @@ -53,28 +53,37 @@ impl Reflectable for DOMImplementation { impl DOMImplementation { // http://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype pub fn CreateDocumentType(&self, qname: DOMString, pubid: DOMString, sysid: DOMString) -> Fallible<JS<DocumentType>> { + let roots = RootCollection::new(); match xml_name_type(qname) { // Step 1. InvalidXMLName => Err(InvalidCharacter), // Step 2. Name => Err(NamespaceError), // Step 3. - QName => Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &self.owner.get().Document())) + QName => { + let document = self.owner.get().Document(); + let document = document.root(&roots); + Ok(DocumentType::new(qname, Some(pubid), Some(sysid), &document.root_ref())) + } } } // http://dom.spec.whatwg.org/#dom-domimplementation-createdocument pub fn CreateDocument(&self, namespace: Option<DOMString>, qname: DOMString, - maybe_doctype: Option<JS<DocumentType>>) -> Fallible<JS<Document>> { + mut maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<JS<Document>> { + let roots = RootCollection::new(); + let win = self.owner.root(&roots); + // Step 1. - let doc = Document::new(&self.owner, None, NonHTMLDocument, None); + 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); // Step 2-3. - let maybe_elem = if qname.is_empty() { + let mut maybe_elem = if qname.is_empty() { None } else { - match doc.get().CreateElementNS(&doc, namespace, qname) { + match doc.get().CreateElementNS(&doc_root.root_ref(), namespace, qname) { Err(error) => return Err(error), Ok(elem) => Some(elem) } @@ -83,13 +92,16 @@ impl DOMImplementation { // Step 4. match maybe_doctype { None => (), - Some(ref doctype) => assert!(doc_node.AppendChild(&mut NodeCast::from(doctype)).is_ok()) + Some(ref mut doctype) => assert!(doc_node.AppendChild(NodeCast::from_mut_ref(doctype)).is_ok()) } // Step 5. match maybe_elem { None => (), - Some(ref elem) => assert!(doc_node.AppendChild(&mut NodeCast::from(elem)).is_ok()) + Some(ref elem) => { + let elem = elem.root(&roots); + assert!(doc_node.AppendChild(NodeCast::from_mut_ref(&mut elem.root_ref())).is_ok()) + } } // Step 6. @@ -101,44 +113,54 @@ impl DOMImplementation { // http://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument pub fn CreateHTMLDocument(&self, title: Option<DOMString>) -> JS<Document> { + let roots = RootCollection::new(); + let owner = self.owner.root(&roots); + // Step 1-2. - let doc = Document::new(&self.owner, None, HTMLDocument, None); + 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); { // Step 3. - let doc_type = DocumentType::new(~"html", None, None, &doc); - assert!(doc_node.AppendChild(&mut NodeCast::from(&doc_type)).is_ok()); + 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()); } { // Step 4. - let mut doc_html = NodeCast::from(&HTMLHtmlElement::new(~"html", &doc)); - assert!(doc_node.AppendChild(&mut doc_html).is_ok()); + 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()); { // Step 5. - let mut doc_head = NodeCast::from(&HTMLHeadElement::new(~"head", &doc)); - assert!(doc_html.AppendChild(&mut doc_head).is_ok()); + 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()); // Step 6. match title { None => (), Some(title_str) => { // Step 6.1. - let mut doc_title = NodeCast::from(&HTMLTitleElement::new(~"title", &doc)); - assert!(doc_head.AppendChild(&mut doc_title).is_ok()); + 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()); // Step 6.2. - let title_text = Text::new(title_str, &doc); - assert!(doc_title.AppendChild(&mut NodeCast::from(&title_text)).is_ok()); + 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()); } } } // Step 7. - let doc_body = HTMLBodyElement::new(~"body", &doc); - assert!(doc_html.AppendChild(&mut NodeCast::from(&doc_body)).is_ok()); + 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()); } // Step 8. diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs index 1961c8d4661..d11c7270057 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object}; use dom::bindings::error::{Fallible, FailureUnknown}; use dom::document::{Document, HTMLDocument, NonHTMLDocument}; @@ -25,12 +25,12 @@ impl DOMParser { } } - pub fn new(owner: &JS<Window>) -> JS<DOMParser> { - reflect_dom_object(~DOMParser::new_inherited(owner.clone()), owner, + pub fn new(owner: &JSRef<Window>) -> JS<DOMParser> { + reflect_dom_object(~DOMParser::new_inherited(owner.unrooted()), owner, DOMParserBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<DOMParser>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<DOMParser>> { Ok(DOMParser::new(owner)) } @@ -38,12 +38,14 @@ impl DOMParser { _s: DOMString, ty: DOMParserBinding::SupportedType) -> Fallible<JS<Document>> { + let roots = RootCollection::new(); + let owner = self.owner.root(&roots); match ty { Text_html => { - Ok(Document::new(&self.owner, None, HTMLDocument, Some(~"text/html"))) + Ok(Document::new(&owner.root_ref(), None, HTMLDocument, Some(~"text/html"))) } Text_xml => { - Ok(Document::new(&self.owner, None, NonHTMLDocument, Some(~"text/xml"))) + Ok(Document::new(&owner.root_ref(), None, NonHTMLDocument, Some(~"text/xml"))) } _ => { Err(FailureUnknown) diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index 4f1e265e8f9..179f2c7571d 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -8,7 +8,7 @@ use dom::attr::{Attr, AttrSettingType, ReplacedAttr, FirstSetAttr}; use dom::attrlist::AttrList; use dom::bindings::codegen::BindingDeclarations::ElementBinding; use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::error::{ErrorResult, Fallible, NamespaceError, InvalidCharacter}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; @@ -19,6 +19,7 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlcollection::HTMLCollection; use dom::htmlserializer::serialize; use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node}; +use dom::node::window_from_node; use dom::virtualmethods::{VirtualMethods, vtable_for}; use layout_interface::ContentChangedDocumentDamage; use layout_interface::MatchSelectorsDocumentDamage; @@ -151,8 +152,8 @@ impl Element { } } - pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JS<Document>) -> JS<Element> { - let element = Element::new_inherited(ElementTypeId, local_name, namespace, prefix, document.clone()); + pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, document: &JSRef<Document>) -> JS<Element> { + let element = Element::new_inherited(ElementTypeId, local_name, namespace, prefix, document.unrooted()); Node::reflect_node(~element, document, ElementBinding::Wrap) } @@ -260,6 +261,7 @@ 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) { + 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 { @@ -270,8 +272,9 @@ impl AttributeHandlers for JS<Element> { None => { let doc = node.get().owner_doc().get(); - let attr = Attr::new(&doc.window, local_name.clone(), value.clone(), - name, namespace.clone(), prefix, self.clone()); + 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) } @@ -474,32 +477,34 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-id - pub fn Id(&self, abstract_self: &JS<Element>) -> DOMString { - abstract_self.get_string_attribute("id") + pub fn Id(&self, abstract_self: &JSRef<Element>) -> DOMString { + abstract_self.unrooted().get_string_attribute("id") } // http://dom.spec.whatwg.org/#dom-element-id - pub fn SetId(&mut self, abstract_self: &mut JS<Element>, id: DOMString) { - abstract_self.set_string_attribute("id", id); + pub fn SetId(&mut self, abstract_self: &mut JSRef<Element>, id: DOMString) { + abstract_self.unrooted().set_string_attribute("id", id); } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn ClassName(&self, abstract_self: &JS<Element>) -> DOMString { - abstract_self.get_string_attribute("class") + pub fn ClassName(&self, abstract_self: &JSRef<Element>) -> DOMString { + abstract_self.unrooted().get_string_attribute("class") } // http://dom.spec.whatwg.org/#dom-element-classname - pub fn SetClassName(&self, abstract_self: &mut JS<Element>, class: DOMString) { - abstract_self.set_string_attribute("class", class); + pub fn SetClassName(&self, abstract_self: &mut JSRef<Element>, class: DOMString) { + abstract_self.unrooted().set_string_attribute("class", class); } // http://dom.spec.whatwg.org/#dom-element-attributes - pub fn Attributes(&mut self, abstract_self: &JS<Element>) -> JS<AttrList> { + pub fn Attributes(&mut self, abstract_self: &JSRef<Element>) -> JS<AttrList> { + let roots = RootCollection::new(); match self.attr_list { None => { let doc = self.node.owner_doc(); let doc = doc.get(); - let list = AttrList::new(&doc.window, abstract_self); + let window = doc.window.root(&roots); + let list = AttrList::new(&window.root_ref(), abstract_self); self.attr_list = Some(list.clone()); list } @@ -508,142 +513,151 @@ impl Element { } // http://dom.spec.whatwg.org/#dom-element-getattribute - pub fn GetAttribute(&self, abstract_self: &JS<Element>, name: DOMString) -> Option<DOMString> { + pub fn GetAttribute(&self, abstract_self: &JSRef<Element>, name: DOMString) -> Option<DOMString> { let name = if abstract_self.get().html_element_in_html_document() { name.to_ascii_lower() } else { name }; - abstract_self.get_attribute(Null, name).map(|s| s.get().Value()) + abstract_self.unrooted().get_attribute(Null, name).map(|s| s.get().Value()) } // http://dom.spec.whatwg.org/#dom-element-getattributens - pub fn GetAttributeNS(&self, abstract_self: &JS<Element>, + pub fn GetAttributeNS(&self, abstract_self: &JSRef<Element>, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - abstract_self.get_attribute(namespace, local_name) + abstract_self.unrooted() + .get_attribute(namespace, local_name) .map(|attr| attr.get().value.clone()) } // http://dom.spec.whatwg.org/#dom-element-setattribute - pub fn SetAttribute(&self, abstract_self: &mut JS<Element>, + pub fn SetAttribute(&self, abstract_self: &mut JSRef<Element>, name: DOMString, value: DOMString) -> ErrorResult { - abstract_self.SetAttribute(name, value) + abstract_self.unrooted().SetAttribute(name, value) } // http://dom.spec.whatwg.org/#dom-element-setattributens pub fn SetAttributeNS(&self, - abstract_self: &mut JS<Element>, + abstract_self: &mut JSRef<Element>, namespace_url: Option<DOMString>, name: DOMString, value: DOMString) -> ErrorResult { - abstract_self.SetAttributeNS(namespace_url, name, value) + abstract_self.unrooted().SetAttributeNS(namespace_url, name, value) } // http://dom.spec.whatwg.org/#dom-element-removeattribute pub fn RemoveAttribute(&mut self, - abstract_self: &mut JS<Element>, + abstract_self: &mut JSRef<Element>, name: DOMString) -> ErrorResult { let name = if self.html_element_in_html_document() { name.to_ascii_lower() } else { name }; - abstract_self.remove_attribute(namespace::Null, name) + abstract_self.unrooted().remove_attribute(namespace::Null, name) } // http://dom.spec.whatwg.org/#dom-element-removeattributens pub fn RemoveAttributeNS(&mut self, - abstract_self: &mut JS<Element>, + abstract_self: &mut JSRef<Element>, namespace: Option<DOMString>, localname: DOMString) -> ErrorResult { let namespace = Namespace::from_str(null_str_as_empty_ref(&namespace)); - abstract_self.remove_attribute(namespace, localname) + abstract_self.unrooted().remove_attribute(namespace, localname) } // http://dom.spec.whatwg.org/#dom-element-hasattribute - pub fn HasAttribute(&self, abstract_self: &JS<Element>, + pub fn HasAttribute(&self, abstract_self: &JSRef<Element>, name: DOMString) -> bool { self.GetAttribute(abstract_self, name).is_some() } // http://dom.spec.whatwg.org/#dom-element-hasattributens - pub fn HasAttributeNS(&self, abstract_self: &JS<Element>, + pub fn HasAttributeNS(&self, abstract_self: &JSRef<Element>, namespace: Option<DOMString>, local_name: DOMString) -> bool { self.GetAttributeNS(abstract_self, namespace, local_name).is_some() } - pub fn GetElementsByTagName(&self, abstract_self: &JS<Element>, localname: DOMString) -> JS<HTMLCollection> { + pub fn GetElementsByTagName(&self, abstract_self: &JSRef<Element>, localname: DOMString) -> JS<HTMLCollection> { + let roots = RootCollection::new(); let doc = self.node.owner_doc(); let doc = doc.get(); - HTMLCollection::by_tag_name(&doc.window, &NodeCast::from(abstract_self), localname) + let window = doc.window.root(&roots); + HTMLCollection::by_tag_name(&window.root_ref(), NodeCast::from_ref(abstract_self), localname) } - pub fn GetElementsByTagNameNS(&self, abstract_self: &JS<Element>, maybe_ns: Option<DOMString>, + pub fn GetElementsByTagNameNS(&self, abstract_self: &JSRef<Element>, maybe_ns: Option<DOMString>, localname: DOMString) -> JS<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 }; - HTMLCollection::by_tag_name_ns(&doc.window, &NodeCast::from(abstract_self), localname, namespace) + let window = doc.window.root(&roots); + HTMLCollection::by_tag_name_ns(&window.root_ref(), NodeCast::from_ref(abstract_self), localname, namespace) } - pub fn GetElementsByClassName(&self, abstract_self: &JS<Element>, classes: DOMString) -> JS<HTMLCollection> { + pub fn GetElementsByClassName(&self, abstract_self: &JSRef<Element>, classes: DOMString) -> JS<HTMLCollection> { + let roots = RootCollection::new(); let doc = self.node.owner_doc(); let doc = doc.get(); - HTMLCollection::by_class_name(&doc.window, &NodeCast::from(abstract_self), classes) + let window = doc.window.root(&roots); + HTMLCollection::by_class_name(&window.root_ref(), NodeCast::from_ref(abstract_self), classes) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects - pub fn GetClientRects(&self, abstract_self: &JS<Element>) -> JS<ClientRectList> { + pub fn GetClientRects(&self, abstract_self: &JSRef<Element>) -> JS<ClientRectList> { + let roots = RootCollection::new(); let doc = self.node.owner_doc(); - let win = &doc.get().window; - let node: JS<Node> = NodeCast::from(abstract_self); + let win = doc.get().window.root(&roots); + let node: JS<Node> = NodeCast::from(&abstract_self.unrooted()); let rects = node.get_content_boxes(); let rects = rects.iter().map(|r| { ClientRect::new( - win, + &win.root_ref(), r.origin.y, r.origin.y + r.size.height, r.origin.x, r.origin.x + r.size.width) }).collect(); - ClientRectList::new(win, rects) + ClientRectList::new(&win.root_ref(), rects) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect - pub fn GetBoundingClientRect(&self, abstract_self: &JS<Element>) -> JS<ClientRect> { + pub fn GetBoundingClientRect(&self, abstract_self: &JSRef<Element>) -> JS<ClientRect> { + let roots = RootCollection::new(); let doc = self.node.owner_doc(); - let win = &doc.get().window; - let node: JS<Node> = NodeCast::from(abstract_self); + let win = doc.get().window.root(&roots); + let node: JS<Node> = NodeCast::from(&abstract_self.unrooted()); let rect = node.get_bounding_content_box(); ClientRect::new( - win, + &win.root_ref(), rect.origin.y, rect.origin.y + rect.size.height, rect.origin.x, rect.origin.x + rect.size.width) } - pub fn GetInnerHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { + pub fn GetInnerHTML(&self, abstract_self: &JSRef<Element>) -> Fallible<DOMString> { //XXX TODO: XML case - Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), false, false))) + Ok(serialize(&mut NodeIterator::new(NodeCast::from(&abstract_self.unrooted()), false, false))) } - pub fn GetOuterHTML(&self, abstract_self: &JS<Element>) -> Fallible<DOMString> { - Ok(serialize(&mut NodeIterator::new(NodeCast::from(abstract_self), true, false))) + pub fn GetOuterHTML(&self, abstract_self: &JSRef<Element>) -> Fallible<DOMString> { + Ok(serialize(&mut NodeIterator::new(NodeCast::from(&abstract_self.unrooted()), true, false))) } - pub fn Children(&self, abstract_self: &JS<Element>) -> JS<HTMLCollection> { - let doc = self.node.owner_doc(); - let doc = doc.get(); - HTMLCollection::children(&doc.window, &NodeCast::from(abstract_self)) + pub fn Children(&self, abstract_self: &JSRef<Element>) -> JS<HTMLCollection> { + let roots = RootCollection::new(); + let window = window_from_node(&abstract_self.unrooted()).root(&roots); + HTMLCollection::children(&window.root_ref(), NodeCast::from_ref(abstract_self)) } } @@ -667,6 +681,7 @@ impl VirtualMethods for JS<Element> { } 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()), _ => (), @@ -684,7 +699,8 @@ impl VirtualMethods for JS<Element> { // "borrowed value does not live long enough" let mut doc = node.get().owner_doc().clone(); let doc = doc.get_mut(); - doc.register_named_element(self, value.clone()); + let elem = self.root(&roots); + doc.register_named_element(&elem.root_ref(), value.clone()); } _ => () } @@ -693,6 +709,7 @@ impl VirtualMethods for JS<Element> { } fn before_remove_attr(&mut self, name: DOMString, value: DOMString) { + let roots = RootCollection::new(); match self.super_type() { Some(ref mut s) => s.before_remove_attr(name.clone(), value.clone()), _ => (), @@ -708,7 +725,8 @@ impl VirtualMethods for JS<Element> { // "borrowed value does not live long enough" let mut doc = node.get().owner_doc().clone(); let doc = doc.get_mut(); - doc.unregister_named_element(self, value); + let elem = self.root(&roots); + doc.unregister_named_element(&elem.root_ref(), value); } _ => () } @@ -717,6 +735,7 @@ impl VirtualMethods for JS<Element> { } fn bind_to_tree(&mut self) { + let roots = RootCollection::new(); match self.super_type() { Some(ref mut s) => s.bind_to_tree(), _ => (), @@ -725,13 +744,15 @@ impl VirtualMethods for JS<Element> { match self.get_attribute(Null, "id") { Some(attr) => { let mut doc = document_from_node(self); - doc.get_mut().register_named_element(self, attr.get().Value()); + let elem = self.root(&roots); + doc.get_mut().register_named_element(&elem.root_ref(), attr.get().Value()); } _ => () } } fn unbind_from_tree(&mut self) { + let roots = RootCollection::new(); match self.super_type() { Some(ref mut s) => s.unbind_from_tree(), _ => (), @@ -740,7 +761,8 @@ impl VirtualMethods for JS<Element> { match self.get_attribute(Null, "id") { Some(attr) => { let mut doc = document_from_node(self); - doc.get_mut().unregister_named_element(self, attr.get().Value()); + let elem = self.root(&roots); + doc.get_mut().unregister_named_element(&elem.root_ref(), attr.get().Value()); } _ => () } diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs index 22be9c3def0..89c250dbc95 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; +use dom::bindings::js::{JS, JSRef}; 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: &JS<Window>) -> JS<Event> { + pub fn new(window: &JSRef<Window>) -> JS<Event> { reflect_dom_object(~Event::new_inherited(HTMLEventTypeId), window, EventBinding::Wrap) @@ -155,7 +155,7 @@ impl Event { self.trusted } - pub fn Constructor(global: &JS<Window>, + pub fn Constructor(global: &JSRef<Window>, type_: DOMString, init: &EventBinding::EventInit) -> Fallible<JS<Event>> { let mut ev = Event::new(global); diff --git a/src/components/script/dom/eventdispatcher.rs b/src/components/script/dom/eventdispatcher.rs index d298ab38492..b8fbce59974 100644 --- a/src/components/script/dom/eventdispatcher.rs +++ b/src/components/script/dom/eventdispatcher.rs @@ -4,21 +4,23 @@ use dom::bindings::callback::ReportExceptions; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, NodeDerived}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef}; 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: &JS<EventTarget>, - pseudo_target: Option<JS<EventTarget>>, - event: &mut JS<Event>) -> bool { +pub fn dispatch_event(target: &JSRef<EventTarget>, + pseudo_target: Option<JSRef<EventTarget>>, + event: &mut JSRef<Event>) -> bool { assert!(!event.get().dispatching); { let event = event.get_mut(); - event.target = pseudo_target.or_else(|| { - Some(target.clone()) + event.target = pseudo_target.map(|pseudo_target| { + pseudo_target.unrooted() + }).or_else(|| { + Some(target.unrooted()) }); event.dispatching = true; } @@ -27,7 +29,7 @@ pub fn dispatch_event(target: &JS<EventTarget>, //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).unwrap(); + let target_node: JS<Node> = NodeCast::to(&target.unrooted()).unwrap(); target_node.ancestors().map(|ancestor| { let ancestor_target: JS<EventTarget> = EventTargetCast::from(&ancestor); ancestor_target @@ -70,7 +72,7 @@ pub fn dispatch_event(target: &JS<EventTarget>, { let event = event.get_mut(); event.phase = PhaseAtTarget; - event.current_target = Some(target.clone()); + event.current_target = Some(target.unrooted()); } let opt_listeners = target.get().get_listeners(type_); diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs index 5214aa0aa69..b77834e7cc4 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::error::{Fallible, InvalidState}; use dom::bindings::codegen::BindingDeclarations::EventListenerBinding; @@ -102,15 +102,15 @@ impl EventTarget { } } - pub fn DispatchEvent(&self, abstract_self: &JS<EventTarget>, - event: &mut JS<Event>) -> Fallible<bool> { + pub fn DispatchEvent(&self, abstract_self: &JSRef<EventTarget>, + event: &mut JSRef<Event>) -> Fallible<bool> { self.dispatch_event_with_target(abstract_self, None, event) } pub fn dispatch_event_with_target(&self, - abstract_self: &JS<EventTarget>, - abstract_target: Option<JS<EventTarget>>, - event: &mut JS<Event>) -> Fallible<bool> { + abstract_self: &JSRef<EventTarget>, + abstract_target: Option<JSRef<EventTarget>>, + event: &mut JSRef<Event>) -> Fallible<bool> { if event.get().dispatching || !event.get().initialized { return Err(InvalidState); } diff --git a/src/components/script/dom/formdata.rs b/src/components/script/dom/formdata.rs index 140c70a12d2..4b6d61c1d82 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; +use dom::bindings::js::{JS, JSRef}; use dom::blob::Blob; use dom::htmlformelement::HTMLFormElement; use dom::window::Window; @@ -28,27 +28,27 @@ pub struct FormData { } impl FormData { - pub fn new_inherited(form: Option<JS<HTMLFormElement>>, window: JS<Window>) -> FormData { + pub fn new_inherited(form: Option<JSRef<HTMLFormElement>>, window: JS<Window>) -> FormData { FormData { data: HashMap::new(), reflector_: Reflector::new(), window: window, - form: form + form: form.map(|form| form.unrooted()) } } - pub fn new(form: Option<JS<HTMLFormElement>>, window: &JS<Window>) -> JS<FormData> { - reflect_dom_object(~FormData::new_inherited(form, window.clone()), window, FormDataBinding::Wrap) + pub fn new(form: Option<JSRef<HTMLFormElement>>, window: &JSRef<Window>) -> JS<FormData> { + reflect_dom_object(~FormData::new_inherited(form, window.unrooted()), window, FormDataBinding::Wrap) } - pub fn Constructor(window: &JS<Window>, form: Option<JS<HTMLFormElement>>) + pub fn Constructor(window: &JSRef<Window>, form: Option<JSRef<HTMLFormElement>>) -> Fallible<JS<FormData>> { Ok(FormData::new(form, window)) } - pub fn Append(&mut self, name: DOMString, value: &JS<Blob>, filename: Option<DOMString>) { + pub fn Append(&mut self, name: DOMString, value: &JSRef<Blob>, filename: Option<DOMString>) { let blob = BlobData { - blob: value.clone(), + blob: value.unrooted(), name: filename.unwrap_or(~"default") }; self.data.insert(name.clone(), blob); diff --git a/src/components/script/dom/htmlanchorelement.rs b/src/components/script/dom/htmlanchorelement.rs index c773e8b55b1..7edd9116dea 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAnchorElementTypeId; @@ -34,8 +34,8 @@ impl HTMLAnchorElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAnchorElement> { - let element = HTMLAnchorElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 a6b4de0e21f..d2b9fcf2e80 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAppletElementTypeId; @@ -34,8 +34,8 @@ impl HTMLAppletElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAppletElement> { - let element = HTMLAppletElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 e50ad671023..f4950d46ad7 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLAreaElementTypeId; @@ -34,8 +34,8 @@ impl HTMLAreaElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAreaElement> { - let element = HTMLAreaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 20a36b60749..2b0b86a36f1 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLAudioElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLAudioElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLAudioElement> { - let element = HTMLAudioElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 bedfd156284..c7d206f3c65 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLBaseElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -34,8 +34,8 @@ impl HTMLBaseElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBaseElement> { - let element = HTMLBaseElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 6e7e0349e40..466c60c6430 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLBodyElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -34,8 +34,8 @@ impl HTMLBodyElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBodyElement> { - let element = HTMLBodyElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 1cf175468ae..e537b1b2c2a 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLBRElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -34,8 +34,8 @@ impl HTMLBRElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLBRElement> { - let element = HTMLBRElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 d40fdbe94be..cee5e13946c 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLButtonElementTypeId; @@ -36,8 +36,8 @@ impl HTMLButtonElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLButtonElement> { - let element = HTMLButtonElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLButtonElement> { + let element = HTMLButtonElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLButtonElementBinding::Wrap) } } @@ -135,9 +135,10 @@ impl HTMLButtonElement { } pub fn Validity(&self) -> JS<ValidityState> { + let roots = RootCollection::new(); let doc = self.htmlelement.element.node.owner_doc(); let doc = doc.get(); - ValidityState::new(&doc.window) + ValidityState::new(&doc.window.root(&roots).root_ref()) } 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 6bf26adc593..4c825780216 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::{ErrorResult}; use dom::document::Document; use dom::element::HTMLCanvasElementTypeId; @@ -34,8 +34,8 @@ impl HTMLCanvasElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLCanvasElement> { - let element = HTMLCanvasElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 79b35487634..8529d4daf64 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; use dom::node::{Node, NodeHelpers}; @@ -15,7 +15,7 @@ use servo_util::str::{DOMString, split_html_space_chars}; use serialize::{Encoder, Encodable}; pub trait CollectionFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool; + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool; } impl<S: Encoder<E>, E> Encodable<S, E> for ~CollectionFilter { @@ -46,24 +46,24 @@ impl HTMLCollection { } } - pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> { - reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection), + pub fn new(window: &JSRef<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> { + reflect_dom_object(~HTMLCollection::new_inherited(window.unrooted(), collection), window, HTMLCollectionBinding::Wrap) } } impl HTMLCollection { - pub fn create(window: &JS<Window>, root: &JS<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> { - HTMLCollection::new(window, Live(root.clone(), filter)) + pub fn create(window: &JSRef<Window>, root: &JSRef<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> { + HTMLCollection::new(window, Live(root.unrooted(), filter)) } - pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag: DOMString) + pub fn by_tag_name(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString) -> JS<HTMLCollection> { struct TagNameFilter { tag: DOMString } impl CollectionFilter for TagNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == self.tag } } @@ -73,14 +73,14 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag: DOMString, + pub fn by_tag_name_ns(window: &JSRef<Window>, root: &JSRef<Node>, tag: DOMString, namespace: Namespace) -> JS<HTMLCollection> { struct TagNameNSFilter { tag: DOMString, namespace: Namespace } impl CollectionFilter for TagNameNSFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().namespace == self.namespace && elem.get().local_name == self.tag } } @@ -91,14 +91,14 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) + pub fn by_class_name(window: &JSRef<Window>, root: &JSRef<Node>, classes: DOMString) -> JS<HTMLCollection> { struct ClassNameFilter { classes: Vec<DOMString> } impl CollectionFilter for ClassNameFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { - self.classes.iter().all(|class| elem.has_class(*class)) + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { + self.classes.iter().all(|class| elem.unrooted().has_class(*class)) } } let filter = ClassNameFilter { @@ -107,11 +107,11 @@ impl HTMLCollection { HTMLCollection::create(window, root, ~filter) } - pub fn children(window: &JS<Window>, root: &JS<Node>) -> JS<HTMLCollection> { + pub fn children(window: &JSRef<Window>, root: &JSRef<Node>) -> JS<HTMLCollection> { struct ElementChildFilter; impl CollectionFilter for ElementChildFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool { - root.is_parent_of(&NodeCast::from(elem)) + fn filter(&self, elem: &JSRef<Element>, root: &JSRef<Node>) -> bool { + root.unrooted().is_parent_of(NodeCast::from_ref(elem)) } } HTMLCollection::create(window, root, ~ElementChildFilter) @@ -121,32 +121,47 @@ impl HTMLCollection { impl HTMLCollection { // http://dom.spec.whatwg.org/#dom-htmlcollection-length pub fn Length(&self) -> u32 { + let roots = RootCollection::new(); match self.collection { Static(ref elems) => elems.len() as u32, - Live(ref root, ref filter) => root.traverse_preorder() - .count(|child| { - let elem: Option<JS<Element>> = ElementCast::to(&child); - elem.map_or(false, |elem| filter.filter(&elem, root)) - }) as u32 + Live(ref root, ref filter) => { + let root_root = root.root(&roots); + root.traverse_preorder() + .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()) + }) + }) as u32 + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-item pub fn Item(&self, index: u32) -> Option<JS<Element>> { + let roots = RootCollection::new(); match self.collection { Static(ref elems) => elems .as_slice() .get(index as uint) .map(|elem| elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .nth(index as uint).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()) + }) + .nth(index as uint).clone() + } } } // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> { + let roots = RootCollection::new(); // Step 1. if key.is_empty() { return None; @@ -159,13 +174,19 @@ impl HTMLCollection { elem.get_string_attribute("name") == key || elem.get_string_attribute("id") == key }) .map(|maybe_elem| maybe_elem.clone()), - Live(ref root, ref filter) => root.traverse_preorder() - .filter_map(|node| ElementCast::to(&node)) - .filter(|elem| filter.filter(elem, root)) - .find(|elem| { - elem.get_string_attribute("name") == key || - elem.get_string_attribute("id") == key }) - .map(|maybe_elem| maybe_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()) + }) + .find(|elem| { + elem.get_string_attribute("name") == key || + elem.get_string_attribute("id") == key }) + .map(|maybe_elem| maybe_elem.clone()) + } } } } diff --git a/src/components/script/dom/htmldataelement.rs b/src/components/script/dom/htmldataelement.rs index e242be54d9d..b95c77acc07 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDataElementTypeId; @@ -34,8 +34,8 @@ impl HTMLDataElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataElement> { - let element = HTMLDataElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 7a5d5329b18..b341a34dcb0 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::document::Document; use dom::element::{Element, HTMLDataListElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -34,22 +34,24 @@ impl HTMLDataListElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDataListElement> { - let element = HTMLDataListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLDataListElement> { + let element = HTMLDataListElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLDataListElementBinding::Wrap) } } impl HTMLDataListElement { - pub fn Options(&self, abstract_self: &JS<HTMLDataListElement>) -> JS<HTMLCollection> { + pub fn Options(&self, abstract_self: &JSRef<HTMLDataListElement>) -> JS<HTMLCollection> { struct HTMLDataListOptionsFilter; impl CollectionFilter for HTMLDataListOptionsFilter { - fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool { + fn filter(&self, elem: &JSRef<Element>, _root: &JSRef<Node>) -> bool { elem.get().local_name == ~"option" } } - let node: JS<Node> = NodeCast::from(abstract_self); + let roots = RootCollection::new(); + let node: &JSRef<Node> = NodeCast::from_ref(abstract_self); let filter = ~HTMLDataListOptionsFilter; - HTMLCollection::create(&window_from_node(&node), &node, filter) + let window = window_from_node(&node.unrooted()).root(&roots); + HTMLCollection::create(&window.root_ref(), node, filter) } } diff --git a/src/components/script/dom/htmldirectoryelement.rs b/src/components/script/dom/htmldirectoryelement.rs index d356fb0bb51..84ee0b539b6 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDirectoryElementTypeId; @@ -34,8 +34,8 @@ impl HTMLDirectoryElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDirectoryElement> { - let element = HTMLDirectoryElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 e018a1a0c3c..723a2088307 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDivElementTypeId; @@ -34,8 +34,8 @@ impl HTMLDivElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDivElement> { - let element = HTMLDivElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 f2f9784764e..8f3523189b7 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLDListElementTypeId; @@ -34,8 +34,8 @@ impl HTMLDListElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLDListElement> { - let element = HTMLDListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 61ebf7d1301..a7852aec276 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::{Element, ElementTypeId, HTMLElementTypeId}; @@ -39,8 +39,8 @@ impl HTMLElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLElement> { - let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLElement> { + let element = HTMLElement::new_inherited(HTMLElementTypeId, localName, document.unrooted()); Node::reflect_node(~element, document, HTMLElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlembedelement.rs b/src/components/script/dom/htmlembedelement.rs index d0a2e436043..73a915c4cc7 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLEmbedElementTypeId; @@ -34,8 +34,8 @@ impl HTMLEmbedElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLEmbedElement> { - let element = HTMLEmbedElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLEmbedElement> { + let element = HTMLEmbedElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLEmbedElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlfieldsetelement.rs b/src/components/script/dom/htmlfieldsetelement.rs index 21116ee41fb..3b1141f403e 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLFieldSetElementTypeId}; @@ -37,8 +37,8 @@ impl HTMLFieldSetElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFieldSetElement> { - let element = HTMLFieldSetElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFieldSetElement> { + let element = HTMLFieldSetElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLFieldSetElementBinding::Wrap) } } @@ -69,19 +69,21 @@ impl HTMLFieldSetElement { } // http://www.whatwg.org/html/#dom-fieldset-elements - pub fn Elements(&self, abstract_self: &JS<HTMLFieldSetElement>) -> JS<HTMLCollection> { + pub fn Elements(&self, abstract_self: &JSRef<HTMLFieldSetElement>) -> JS<HTMLCollection> { struct ElementsFilter; impl CollectionFilter for ElementsFilter { - fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool { + 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).unwrap(); - elem != root && tag_names.iter().any(|&tag_name| tag_name == elem.get().local_name) + 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 node: JS<Node> = NodeCast::from(abstract_self); + let roots = RootCollection::new(); + let node: &JSRef<Node> = NodeCast::from_ref(abstract_self); let filter = ~ElementsFilter; - HTMLCollection::create(&window_from_node(&node), &node, filter) + let window = window_from_node(&node.unrooted()).root(&roots); + HTMLCollection::create(&window.root_ref(), node, filter) } pub fn WillValidate(&self) -> bool { @@ -89,9 +91,11 @@ impl HTMLFieldSetElement { } pub fn Validity(&self) -> JS<ValidityState> { + let roots = RootCollection::new(); let doc = self.htmlelement.element.node.owner_doc(); let doc = doc.get(); - ValidityState::new(&doc.window) + let window = doc.window.root(&roots); + ValidityState::new(&window.root_ref()) } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlfontelement.rs b/src/components/script/dom/htmlfontelement.rs index 6eae087cdcd..f28971e7c43 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFontElementTypeId; @@ -34,8 +34,8 @@ impl HTMLFontElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFontElement> { - let element = HTMLFontElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 3fdf2a4ba7f..0e7159c61b9 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLFormElementTypeId}; @@ -35,8 +35,8 @@ impl HTMLFormElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFormElement> { - let element = HTMLFormElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFormElement> { + let element = HTMLFormElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLFormElementBinding::Wrap) } } @@ -116,9 +116,11 @@ impl HTMLFormElement { pub fn Elements(&self) -> JS<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(); - HTMLCollection::new(&doc.window, Static(vec!())) + let window = doc.window.root(&roots); + HTMLCollection::new(&window.root_ref(), Static(vec!())) } pub fn Length(&self) -> i32 { diff --git a/src/components/script/dom/htmlframeelement.rs b/src/components/script/dom/htmlframeelement.rs index a0ac8293ff7..535c0398690 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFrameElementTypeId; @@ -35,8 +35,8 @@ impl HTMLFrameElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameElement> { - let element = HTMLFrameElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLFrameElement> { + let element = HTMLFrameElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLFrameElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmlframesetelement.rs b/src/components/script/dom/htmlframesetelement.rs index 3d7297ca6ec..29691e01397 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLFrameSetElementTypeId; @@ -34,8 +34,8 @@ impl HTMLFrameSetElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLFrameSetElement> { - let element = HTMLFrameSetElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 bf0b3f3d9b8..3f2037d7188 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLHeadElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLHeadElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHeadElement> { - let element = HTMLHeadElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 5bf9ac39f55..40844eb36e5 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLHeadingElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -45,8 +45,8 @@ impl HTMLHeadingElement { } } - pub fn new(localName: DOMString, document: &JS<Document>, level: HeadingLevel) -> JS<HTMLHeadingElement> { - let element = HTMLHeadingElement::new_inherited(localName, document.clone(), level); + pub fn new(localName: DOMString, document: &JSRef<Document>, level: HeadingLevel) -> JS<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 25315450c5a..28bdd2ed3de 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLHRElementTypeId; @@ -34,8 +34,8 @@ impl HTMLHRElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHRElement> { - let element = HTMLHRElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 b88639b3c59..391bf7b2465 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLHtmlElementTypeId; @@ -34,8 +34,8 @@ impl HTMLHtmlElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLHtmlElement> { - let element = HTMLHtmlElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 99ddf3d30f2..c037f17f9a5 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{HTMLIFrameElementTypeId, Element}; @@ -74,8 +74,8 @@ impl HTMLIFrameElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLIFrameElement> { - let element = HTMLIFrameElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLIFrameElement> { + let element = HTMLIFrameElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLIFrameElementBinding::Wrap) } } @@ -105,13 +105,13 @@ impl HTMLIFrameElement { Ok(()) } - pub fn Sandbox(&self, abstract_self: &JS<HTMLIFrameElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Sandbox(&self, abstract_self: &JSRef<HTMLIFrameElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("sandbox") } - pub fn SetSandbox(&mut self, abstract_self: &mut JS<HTMLIFrameElement>, sandbox: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetSandbox(&mut self, abstract_self: &mut JSRef<HTMLIFrameElement>, sandbox: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("sandbox", sandbox); } diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 6bb7096fcde..d986f5d07e8 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{Element, HTMLImageElementTypeId}; @@ -43,8 +43,8 @@ impl HTMLImageElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLImageElement> { - let element = HTMLImageElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLImageElement> { + let element = HTMLImageElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLImageElementBinding::Wrap) } } @@ -79,23 +79,23 @@ impl HTMLImageElement { } } - pub fn Alt(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Alt(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("alt") } - pub fn SetAlt(&mut self, abstract_self: &JS<HTMLImageElement>, alt: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetAlt(&mut self, abstract_self: &JSRef<HTMLImageElement>, alt: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("alt", alt) } - pub fn Src(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Src(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("src") } - pub fn SetSrc(&mut self, abstract_self: &mut JS<HTMLImageElement>, src: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetSrc(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, src: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_url_attribute("src", src) } @@ -107,45 +107,45 @@ impl HTMLImageElement { Ok(()) } - pub fn UseMap(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn UseMap(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("useMap") } - pub fn SetUseMap(&mut self, abstract_self: &mut JS<HTMLImageElement>, use_map: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetUseMap(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, use_map: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("useMap", use_map) } - pub fn IsMap(&self, abstract_self: &JS<HTMLImageElement>) -> bool { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn IsMap(&self, abstract_self: &JSRef<HTMLImageElement>) -> bool { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); from_str::<bool>(element.get_string_attribute("hspace")).unwrap() } - pub fn SetIsMap(&self, abstract_self: &mut JS<HTMLImageElement>, is_map: bool) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetIsMap(&self, abstract_self: &mut JSRef<HTMLImageElement>, is_map: bool) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("isMap", is_map.to_str()) } - pub fn Width(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let node: JS<Node> = NodeCast::from(abstract_self); + pub fn Width(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 { + let node: JS<Node> = NodeCast::from(&abstract_self.unrooted()); let rect = node.get_bounding_content_box(); to_px(rect.size.width) as u32 } - pub fn SetWidth(&mut self, abstract_self: &JS<HTMLImageElement>, width: u32) { - let mut elem: JS<Element> = ElementCast::from(abstract_self); + pub fn SetWidth(&mut self, abstract_self: &JSRef<HTMLImageElement>, width: u32) { + let mut elem: JS<Element> = ElementCast::from(&abstract_self.unrooted()); elem.set_uint_attribute("width", width) } - pub fn Height(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let node: JS<Node> = NodeCast::from(abstract_self); + pub fn Height(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 { + let node: JS<Node> = NodeCast::from(&abstract_self.unrooted()); let rect = node.get_bounding_content_box(); to_px(rect.size.height) as u32 } - pub fn SetHeight(&mut self, abstract_self: &JS<HTMLImageElement>, height: u32) { - let mut elem: JS<Element> = ElementCast::from(abstract_self); + pub fn SetHeight(&mut self, abstract_self: &JSRef<HTMLImageElement>, height: u32) { + let mut elem: JS<Element> = ElementCast::from(&abstract_self.unrooted()); elem.set_uint_attribute("height", height) } @@ -161,63 +161,63 @@ impl HTMLImageElement { false } - pub fn Name(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Name(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("name") } - pub fn SetName(&mut self, abstract_self: &mut JS<HTMLImageElement>, name: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetName(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, name: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("name", name) } - pub fn Align(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Align(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("longdesc") } - pub fn SetAlign(&mut self, abstract_self: &mut JS<HTMLImageElement>, align: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetAlign(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, align: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("align", align) } - pub fn Hspace(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Hspace(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); from_str::<u32>(element.get_string_attribute("hspace")).unwrap() } - pub fn SetHspace(&mut self, abstract_self: &mut JS<HTMLImageElement>, hspace: u32) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetHspace(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, hspace: u32) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_uint_attribute("hspace", hspace) } - pub fn Vspace(&self, abstract_self: &JS<HTMLImageElement>) -> u32 { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Vspace(&self, abstract_self: &JSRef<HTMLImageElement>) -> u32 { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); from_str::<u32>(element.get_string_attribute("vspace")).unwrap() } - pub fn SetVspace(&mut self, abstract_self: &mut JS<HTMLImageElement>, vspace: u32) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetVspace(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, vspace: u32) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_uint_attribute("vspace", vspace) } - pub fn LongDesc(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn LongDesc(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("longdesc") } - pub fn SetLongDesc(&mut self, abstract_self: &mut JS<HTMLImageElement>, longdesc: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetLongDesc(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, longdesc: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("longdesc", longdesc) } - pub fn Border(&self, abstract_self: &JS<HTMLImageElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Border(&self, abstract_self: &JSRef<HTMLImageElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_string_attribute("border") } - pub fn SetBorder(&mut self, abstract_self: &mut JS<HTMLImageElement>, border: DOMString) { - let mut element: JS<Element> = ElementCast::from(abstract_self); + pub fn SetBorder(&mut self, abstract_self: &mut JSRef<HTMLImageElement>, border: DOMString) { + let mut element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.set_string_attribute("border", border) } } diff --git a/src/components/script/dom/htmlinputelement.rs b/src/components/script/dom/htmlinputelement.rs index 978ce8a0d63..90914fbc7bb 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLInputElementTypeId; @@ -34,8 +34,8 @@ impl HTMLInputElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLInputElement> { - let element = HTMLInputElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 70c811c949e..5c920fd75eb 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLLabelElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLLabelElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLabelElement> { - let element = HTMLLabelElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 a8fdf6a1405..ee6199808eb 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLegendElementTypeId; @@ -34,8 +34,8 @@ impl HTMLLegendElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLegendElement> { - let element = HTMLLegendElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 052557545ea..2a7501b08e9 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLIElementTypeId; @@ -34,8 +34,8 @@ impl HTMLLIElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLIElement> { - let element = HTMLLIElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 ae47e5168a2..528ea303a2c 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLLinkElementTypeId; @@ -34,8 +34,8 @@ impl HTMLLinkElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLLinkElement> { - let element = HTMLLinkElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 182a3194019..74bc99c0149 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLMainElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLMainElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMainElement> { - let element = HTMLMainElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 72214f0ff1d..aff393505af 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMapElementTypeId; @@ -35,8 +35,8 @@ impl HTMLMapElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMapElement> { - let element = HTMLMapElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLMapElement> { + let element = HTMLMapElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLMapElementBinding::Wrap) } } @@ -51,9 +51,11 @@ impl HTMLMapElement { } pub fn Areas(&self) -> JS<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(); - HTMLCollection::new(&doc.window, Static(vec!())) + let window = doc.window.root(&roots); + HTMLCollection::new(&window.root_ref(), Static(vec!())) } } diff --git a/src/components/script/dom/htmlmetaelement.rs b/src/components/script/dom/htmlmetaelement.rs index 3ecba0013d2..191a49f2444 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMetaElementTypeId; @@ -34,8 +34,8 @@ impl HTMLMetaElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMetaElement> { - let element = HTMLMetaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 044c4785cb8..19bac1c9797 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLMeterElementTypeId; @@ -34,8 +34,8 @@ impl HTMLMeterElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLMeterElement> { - let element = HTMLMeterElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 a656b891b1b..b934ef74b86 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLModElementTypeId; @@ -34,8 +34,8 @@ impl HTMLModElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLModElement> { - let element = HTMLModElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 e2c7d16c03d..f3f48cba313 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLObjectElementTypeId}; @@ -47,8 +47,8 @@ impl HTMLObjectElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLObjectElement> { - let element = HTMLObjectElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLObjectElement> { + let element = HTMLObjectElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLObjectElementBinding::Wrap) } } @@ -144,9 +144,11 @@ impl HTMLObjectElement { } pub fn Validity(&self) -> JS<ValidityState> { + let roots = RootCollection::new(); let doc = self.htmlelement.element.node.owner_doc(); let doc = doc.get(); - ValidityState::new(&doc.window) + let window = doc.window.root(&roots); + ValidityState::new(&window.root_ref()) } pub fn ValidationMessage(&self) -> DOMString { diff --git a/src/components/script/dom/htmlolistelement.rs b/src/components/script/dom/htmlolistelement.rs index ced7b98edb4..a62acc013c6 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOListElementTypeId; @@ -34,8 +34,8 @@ impl HTMLOListElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOListElement> { - let element = HTMLOListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 dfddb3e2546..3ef4df88ab9 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOptGroupElementTypeId; @@ -34,8 +34,8 @@ impl HTMLOptGroupElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptGroupElement> { - let element = HTMLOptGroupElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 e6a030df48c..5119ce17b73 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOptionElementTypeId; @@ -35,8 +35,8 @@ impl HTMLOptionElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOptionElement> { - let element = HTMLOptionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOptionElement> { + let element = HTMLOptionElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLOptionElementBinding::Wrap) } } diff --git a/src/components/script/dom/htmloutputelement.rs b/src/components/script/dom/htmloutputelement.rs index 1a1ec088489..4f5dae6d8c0 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLOutputElementTypeId; @@ -36,8 +36,8 @@ impl HTMLOutputElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLOutputElement> { - let element = HTMLOutputElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLOutputElement> { + let element = HTMLOutputElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLOutputElementBinding::Wrap) } } @@ -83,9 +83,11 @@ impl HTMLOutputElement { } pub fn Validity(&self) -> JS<ValidityState> { + let roots = RootCollection::new(); let doc = self.htmlelement.element.node.owner_doc(); let doc = doc.get(); - ValidityState::new(&doc.window) + let window = doc.window.root(&roots); + ValidityState::new(&window.root_ref()) } 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 e6e6473e816..b473a81613e 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLParagraphElementTypeId; @@ -34,8 +34,8 @@ impl HTMLParagraphElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParagraphElement> { - let element = HTMLParagraphElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 781221bfad0..c33b68fc932 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLParamElementTypeId; @@ -34,8 +34,8 @@ impl HTMLParamElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLParamElement> { - let element = HTMLParamElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 9b3e2c73953..cfbc2ddc3fe 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLPreElementTypeId; @@ -34,8 +34,8 @@ impl HTMLPreElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLPreElement> { - let element = HTMLPreElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 ccd0463539f..ec76ab7d41d 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLProgressElementTypeId; @@ -34,8 +34,8 @@ impl HTMLProgressElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLProgressElement> { - let element = HTMLProgressElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 87e313cc857..0ec36d39711 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLQuoteElementTypeId; @@ -34,8 +34,8 @@ impl HTMLQuoteElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLQuoteElement> { - let element = HTMLQuoteElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 bccaa740906..3be3739542a 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{HTMLScriptElementTypeId, Element, AttributeHandlers}; @@ -35,19 +35,19 @@ impl HTMLScriptElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLScriptElement> { - let element = HTMLScriptElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLScriptElement> { + let element = HTMLScriptElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLScriptElementBinding::Wrap) } } impl HTMLScriptElement { - pub fn Src(&self, abstract_self: &JS<HTMLScriptElement>) -> DOMString { - let element: JS<Element> = ElementCast::from(abstract_self); + pub fn Src(&self, abstract_self: &JSRef<HTMLScriptElement>) -> DOMString { + let element: JS<Element> = ElementCast::from(&abstract_self.unrooted()); element.get_url_attribute("src") } - pub fn SetSrc(&mut self, _abstract_self: &JS<HTMLScriptElement>, _src: DOMString) -> ErrorResult { + pub fn SetSrc(&mut self, _abstract_self: &JSRef<HTMLScriptElement>, _src: DOMString) -> ErrorResult { Ok(()) } diff --git a/src/components/script/dom/htmlselectelement.rs b/src/components/script/dom/htmlselectelement.rs index 47353bd8eb5..53a738e1a97 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::{Element, HTMLSelectElementTypeId}; @@ -38,8 +38,8 @@ impl HTMLSelectElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSelectElement> { - let element = HTMLSelectElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLSelectElement> { + let element = HTMLSelectElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLSelectElementBinding::Wrap) } } @@ -121,7 +121,7 @@ impl HTMLSelectElement { None } - pub fn IndexedSetter(&mut self, _index: u32, _option: Option<JS<HTMLOptionElement>>) -> ErrorResult { + pub fn IndexedSetter(&mut self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult { Ok(()) } @@ -154,9 +154,11 @@ impl HTMLSelectElement { } pub fn Validity(&self) -> JS<ValidityState> { + let roots = RootCollection::new(); let doc = self.htmlelement.element.node.owner_doc(); let doc = doc.get(); - ValidityState::new(&doc.window) + let window = doc.window.root(&roots); + ValidityState::new(&window.root_ref()) } 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 8bd5beb6cf8..e99982822ed 100644 --- a/src/components/script/dom/htmlserializer.rs +++ b/src/components/script/dom/htmlserializer.rs @@ -7,7 +7,7 @@ use dom::attr::Attr; use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, CommentCast}; use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, CharacterDataCast}; use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::characterdata::CharacterData; use dom::comment::Comment; use dom::documenttype::DocumentType; @@ -20,6 +20,7 @@ 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,23 +32,28 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { match node.type_id() { ElementNodeTypeId(..) => { let elem: JS<Element> = ElementCast::to(&node).unwrap(); - serialize_elem(&elem, &mut open_elements) + let elem = elem.root(&roots); + serialize_elem(&elem.root_ref(), &mut open_elements) } CommentNodeTypeId => { let comment: JS<Comment> = CommentCast::to(&node).unwrap(); - serialize_comment(&comment) + let comment = comment.root(&roots); + serialize_comment(&comment.root_ref()) } TextNodeTypeId => { let text: JS<Text> = TextCast::to(&node).unwrap(); - serialize_text(&text) + let text = text.root(&roots); + serialize_text(&text.root_ref()) } DoctypeNodeTypeId => { let doctype: JS<DocumentType> = DocumentTypeCast::to(&node).unwrap(); - serialize_doctype(&doctype) + let doctype = doctype.root(&roots); + serialize_doctype(&doctype.root_ref()) } ProcessingInstructionNodeTypeId => { let processing_instruction: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node).unwrap(); - serialize_processing_instruction(&processing_instruction) + let processing_instruction = processing_instruction.root(&roots); + serialize_processing_instruction(&processing_instruction.root_ref()) } DocumentFragmentNodeTypeId => { ~"" @@ -64,11 +70,11 @@ pub fn serialize(iterator: &mut NodeIterator) -> ~str { html } -fn serialize_comment(comment: &JS<Comment>) -> ~str { +fn serialize_comment(comment: &JSRef<Comment>) -> ~str { ~"<!--" + comment.get().characterdata.data + "-->" } -fn serialize_text(text: &JS<Text>) -> ~str { +fn serialize_text(text: &JSRef<Text>) -> ~str { match text.get().characterdata.node.parent_node { Some(ref parent) if parent.is_element() => { let elem: JS<Element> = ElementCast::to(parent).unwrap(); @@ -85,18 +91,20 @@ fn serialize_text(text: &JS<Text>) -> ~str { } } -fn serialize_processing_instruction(processing_instruction: &JS<ProcessingInstruction>) -> ~str { +fn serialize_processing_instruction(processing_instruction: &JSRef<ProcessingInstruction>) -> ~str { ~"<?" + processing_instruction.get().target + " " + processing_instruction.get().characterdata.data + "?>" } -fn serialize_doctype(doctype: &JS<DocumentType>) -> ~str { +fn serialize_doctype(doctype: &JSRef<DocumentType>) -> ~str { ~"<!DOCTYPE" + doctype.get().name + ">" } -fn serialize_elem(elem: &JS<Element>, open_elements: &mut Vec<~str>) -> ~str { +fn serialize_elem(elem: &JSRef<Element>, open_elements: &mut Vec<~str>) -> ~str { + let roots = RootCollection::new(); let mut rv = ~"<" + elem.get().local_name; for attr in elem.get().attrs.iter() { - rv.push_str(serialize_attr(attr)); + let attr = attr.root(&roots); + rv.push_str(serialize_attr(&attr.root_ref())); }; rv.push_str(">"); match elem.get().local_name.as_slice() { @@ -119,7 +127,7 @@ fn serialize_elem(elem: &JS<Element>, open_elements: &mut Vec<~str>) -> ~str { rv } -fn serialize_attr(attr: &JS<Attr>) -> ~str { +fn serialize_attr(attr: &JSRef<Attr>) -> ~str { let attr_name = if attr.get().namespace == namespace::XML { ~"xml:" + attr.get().local_name.clone() } else if attr.get().namespace == namespace::XMLNS && diff --git a/src/components/script/dom/htmlsourceelement.rs b/src/components/script/dom/htmlsourceelement.rs index 86f45c131ee..8db513bfbd2 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLSourceElementTypeId; @@ -34,8 +34,8 @@ impl HTMLSourceElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSourceElement> { - let element = HTMLSourceElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 14151f655a1..20e95ae4b8d 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLSpanElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLSpanElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLSpanElement> { - let element = HTMLSpanElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 29caa80da1d..be43a40f27d 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLStyleElementTypeId; @@ -37,8 +37,8 @@ impl HTMLStyleElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLStyleElement> { - let element = HTMLStyleElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<HTMLStyleElement> { + let element = HTMLStyleElement::new_inherited(localName, document.unrooted()); Node::reflect_node(~element, document, HTMLStyleElementBinding::Wrap) } } @@ -82,11 +82,13 @@ pub trait StyleElementHelpers { impl StyleElementHelpers for JS<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 url = win.get().page().get_url(); - let data = node.get().GetTextContent(&node).expect("Element.textContent must be a string"); + let data = node.get().GetTextContent(&node_root.root_ref()).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)); diff --git a/src/components/script/dom/htmltablecaptionelement.rs b/src/components/script/dom/htmltablecaptionelement.rs index 0366c458f27..6aa88d6c05a 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableCaptionElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTableCaptionElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableCaptionElement> { - let element = HTMLTableCaptionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 cb7da24bc26..cc967f14c49 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableColElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTableColElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableColElement> { - let element = HTMLTableColElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 84d55945a29..7a6185d6ec2 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLTableDataCellElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLTableDataCellElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableDataCellElement> { - let element = HTMLTableDataCellElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 e4dbddd65ab..20948ff1d67 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTableElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableElement> { - let element = HTMLTableElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 af3421a1309..47057fd0fa2 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLTableHeaderCellElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLTableHeaderCellElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableHeaderCellElement> { - let element = HTMLTableHeaderCellElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 aa46e96524f..1256dbfdabc 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableRowElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTableRowElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableRowElement> { - let element = HTMLTableRowElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 2e7cbda0f71..3689bba1f48 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTableSectionElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTableSectionElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTableSectionElement> { - let element = HTMLTableSectionElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 cc431bc117e..9880dc0b34d 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLTemplateElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLTemplateElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTemplateElement> { - let element = HTMLTemplateElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 d41b32070c1..4f4c7b55c9d 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::{ErrorResult, Fallible}; use dom::document::Document; use dom::element::HTMLTextAreaElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTextAreaElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTextAreaElement> { - let element = HTMLTextAreaElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 527267d30a4..938a1013876 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTimeElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTimeElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTimeElement> { - let element = HTMLTimeElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 6b4b8f118bd..3fe46fe1b81 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTitleElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTitleElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTitleElement> { - let element = HTMLTitleElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 c427c799ef1..19a58090dcf 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLTrackElementTypeId; @@ -34,8 +34,8 @@ impl HTMLTrackElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLTrackElement> { - let element = HTMLTrackElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 8c9958fd8ff..1fe1be79af1 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLUListElementTypeId; @@ -34,8 +34,8 @@ impl HTMLUListElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUListElement> { - let element = HTMLUListElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 a8a0b3cb41d..aa472bb04fc 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; +use dom::bindings::js::{JS, JSRef}; use dom::document::Document; use dom::element::HTMLUnknownElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -33,8 +33,8 @@ impl HTMLUnknownElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLUnknownElement> { - let element = HTMLUnknownElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 4ef1d9c57a3..3587ab4931a 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLVideoElementTypeId; @@ -34,8 +34,8 @@ impl HTMLVideoElement { } } - pub fn new(localName: DOMString, document: &JS<Document>) -> JS<HTMLVideoElement> { - let element = HTMLVideoElement::new_inherited(localName, document.clone()); + pub fn new(localName: DOMString, document: &JSRef<Document>) -> JS<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 0933d324c8b..fa0aaf103d7 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; +use dom::bindings::js::{JS, JSRef}; 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: &JS<Window>, page: Rc<Page>) -> JS<Location> { + pub fn new(window: &JSRef<Window>, page: Rc<Page>) -> JS<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 9db7963c2c9..a1f08aa72e0 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; +use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}; use dom::bindings::error::Fallible; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::event::{Event, MouseEventTypeId}; @@ -51,21 +51,24 @@ impl MouseEvent { } } - pub fn new(window: &JS<Window>) -> JS<MouseEvent> { + pub fn new(window: &JSRef<Window>) -> JS<MouseEvent> { reflect_dom_object(~MouseEvent::new_inherited(), window, MouseEventBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, + pub fn Constructor(owner: &JSRef<Window>, type_: DOMString, init: &MouseEventBinding::MouseEventInit) -> Fallible<JS<MouseEvent>> { + let roots = RootCollection::new(); let mut ev = MouseEvent::new(owner); - ev.get_mut().InitMouseEvent(type_, init.bubbles, init.cancelable, init.view.clone(), + 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(), init.detail, init.screenX, init.screenY, init.clientX, init.clientY, init.ctrlKey, init.altKey, init.shiftKey, init.metaKey, - init.button, init.relatedTarget.clone()); + init.button, related_target.root_ref()); Ok(ev) } @@ -123,7 +126,7 @@ impl MouseEvent { typeArg: DOMString, canBubbleArg: bool, cancelableArg: bool, - viewArg: Option<JS<Window>>, + viewArg: Option<JSRef<Window>>, detailArg: i32, screenXArg: i32, screenYArg: i32, @@ -134,7 +137,7 @@ impl MouseEvent { shiftKeyArg: bool, metaKeyArg: bool, buttonArg: u16, - relatedTargetArg: Option<JS<EventTarget>>) { + relatedTargetArg: Option<JSRef<EventTarget>>) { self.mouseevent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); self.screen_x = screenXArg; self.screen_y = screenYArg; @@ -145,7 +148,7 @@ impl MouseEvent { self.shift_key = shiftKeyArg; self.meta_key = metaKeyArg; self.button = buttonArg; - self.related_target = relatedTargetArg; + self.related_target = relatedTargetArg.map(|target| target.unrooted()); } } diff --git a/src/components/script/dom/navigator.rs b/src/components/script/dom/navigator.rs index 39788fa7013..63779428d94 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; +use dom::bindings::js::{JS, JSRef}; 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: &JS<Window>) -> JS<Navigator> { + pub fn new(window: &JSRef<Window>) -> JS<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 d5b43a6257f..4d40d8daeb7 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -10,7 +10,7 @@ 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; +use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{ErrorResult, Fallible, NotFound, HierarchyRequest}; use dom::bindings::utils; @@ -223,25 +223,28 @@ pub enum NodeTypeId { } pub trait INode { - fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; - fn ReplaceChild(&mut self, node: &mut JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>>; - fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>>; + 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>>; } impl INode for JS<Node> { - fn AppendChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().AppendChild(&mut self_node, 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 JS<Node>, child: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().ReplaceChild(&mut self_node, node, child) + 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) } - fn RemoveChild(&mut self, node: &mut JS<Node>) -> Fallible<JS<Node>> { - let mut self_node = self.clone(); - self.get_mut().RemoveChild(&mut self_node, node) + 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) } } @@ -251,8 +254,8 @@ pub trait NodeHelpers { fn child_elements(&self) -> ChildElementIterator; fn following_siblings(&self) -> AbstractNodeChildrenIterator; fn is_in_doc(&self) -> bool; - fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool; - fn is_parent_of(&self, child: &JS<Node>) -> bool; + fn is_inclusive_ancestor_of(&self, parent: &JSRef<Node>) -> bool; + fn is_parent_of(&self, child: &JSRef<Node>) -> bool; fn type_id(&self) -> NodeTypeId; @@ -270,8 +273,8 @@ pub trait NodeHelpers { fn node_inserted(&self); fn node_removed(&self); - fn add_child(&mut self, new_child: &mut JS<Node>, before: Option<JS<Node>>); - fn remove_child(&mut self, child: &mut JS<Node>); + fn add_child(&mut self, new_child: &mut JSRef<Node>, before: Option<JSRef<Node>>); + fn remove_child(&mut self, child: &mut JSRef<Node>); fn get_hover_state(&self) -> bool; fn set_hover_state(&mut self, state: bool); @@ -364,10 +367,7 @@ impl NodeHelpers for JS<Node> { #[inline] fn is_element(&self) -> bool { - match self.type_id() { - ElementNodeTypeId(..) => true, - _ => false - } + self.get().is_element() } #[inline] @@ -439,66 +439,81 @@ 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: &mut JS<Node>, before: Option<JS<Node>>) { + fn add_child(&mut self, new_child_root: &mut JSRef<Node>, 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(mut before) => { + Some(before_root) => { + let mut before = before_root.unrooted(); // 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.clone())); + self.get_mut().set_first_child(Some(new_child_root.clone())); }, Some(mut prev_sibling) => { - prev_sibling.get_mut().set_next_sibling(Some(new_child.clone())); - new_child.get_mut().set_prev_sibling(Some(prev_sibling.clone())); + 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())); }, } - before.get_mut().set_prev_sibling(Some(new_child.clone())); - new_child.get_mut().set_next_sibling(Some(before.clone())); + before.get_mut().set_prev_sibling(Some(new_child_root.clone())); + new_child.get_mut().set_next_sibling(Some(before_root.clone())); }, None => { match self.last_child() { - None => self.get_mut().set_first_child(Some(new_child.clone())), + None => self.get_mut().set_first_child(Some(new_child_root.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.clone())); - new_child.get_mut().set_prev_sibling(Some(last_child.clone())); + 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())); } } - self.get_mut().set_last_child(Some(new_child.clone())); + self.get_mut().set_last_child(Some(new_child_root.clone())); }, } - new_child.get_mut().set_parent_node(Some(self.clone())); + let self_root = self.root(&roots); + new_child.get_mut().set_parent_node(Some(self_root.root_ref())); } /// Removes the given child from this node's list of children. /// /// Fails unless `child` is a child of this node. (FIXME: This is not yet checked.) - fn remove_child(&mut self, child: &mut JS<Node>) { + fn remove_child(&mut self, child: &mut JSRef<Node>) { + let roots = RootCollection::new(); let this_node = self.get_mut(); let child_node = child.get_mut(); assert!(child_node.parent_node.is_some()); match child_node.prev_sibling { - None => this_node.set_first_child(child_node.next_sibling.clone()), + None => { + let next_sibling = child_node.next_sibling.as_ref().map(|next| next.root(&roots)); + this_node.set_first_child(next_sibling.root_ref()); + } Some(ref mut prev_sibling) => { let prev_sibling_node = prev_sibling.get_mut(); - prev_sibling_node.set_next_sibling(child_node.next_sibling.clone()); + let next_sibling = child_node.next_sibling.as_ref().map(|next| next.root(&roots)); + prev_sibling_node.set_next_sibling(next_sibling.root_ref()); } } match child_node.next_sibling { - None => this_node.set_last_child(child_node.prev_sibling.clone()), + None => { + let prev_sibling = child_node.prev_sibling.as_ref().map(|prev| prev.root(&roots)); + this_node.set_last_child(prev_sibling.root_ref()); + } Some(ref mut next_sibling) => { let next_sibling_node = next_sibling.get_mut(); - next_sibling_node.set_prev_sibling(child_node.prev_sibling.clone()); + let prev_sibling = child_node.prev_sibling.as_ref().map(|prev| prev.root(&roots)); + next_sibling_node.set_prev_sibling(prev_sibling.root_ref()); } } @@ -517,15 +532,19 @@ impl NodeHelpers for JS<Node> { /// Iterates over this node and all its descendants, in preorder. fn traverse_preorder(&self) -> TreeIterator { + let roots = RootCollection::new(); let mut nodes = vec!(); - gather_abstract_nodes(self, &mut nodes, false); + let self_root = self.root(&roots); + gather_abstract_nodes(&self_root.root_ref(), &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(); let mut nodes = vec!(); - gather_abstract_nodes(self, &mut nodes, true); + let self_root = self.root(&roots); + gather_abstract_nodes(&self_root.root_ref(), &mut nodes, true); TreeIterator::new(nodes) } @@ -535,7 +554,8 @@ impl NodeHelpers for JS<Node> { } } - fn is_inclusive_ancestor_of(&self, parent: &JS<Node>) -> bool { + fn is_inclusive_ancestor_of(&self, parent: &JSRef<Node>) -> bool { + let parent = &parent.unrooted(); self == parent || parent.ancestors().any(|ancestor| ancestor == *self) } @@ -545,8 +565,8 @@ impl NodeHelpers for JS<Node> { } } - fn is_parent_of(&self, child: &JS<Node>) -> bool { - match child.parent_node() { + fn is_parent_of(&self, child: &JSRef<Node>) -> bool { + match child.unrooted().parent_node() { Some(ref parent) if parent == self => true, _ => false } @@ -677,32 +697,35 @@ impl NodeIterator { } } - fn next_child(&self, node: &JS<Node>) -> Option<JS<Node>> { - if !self.include_descendants_of_void && node.is_element() { - let elem: JS<Element> = ElementCast::to(node).unwrap(); + fn next_child(&self, node: &JSRef<Node>) -> Option<JS<Node>> { + if !self.include_descendants_of_void && node.get().is_element() { + let elem: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); if elem.get().is_void() { None } else { - node.first_child() + node.get().first_child.clone() } } else { - node.first_child() + node.get().first_child.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 { None => { if self.include_start { Some(self.start_node.clone()) } else { - self.next_child(&self.start_node) + let start_node = self.start_node.root(&roots); + self.next_child(&start_node.root_ref()) } }, Some(ref node) => { - match self.next_child(node) { + let node_root = node.root(&roots); + match self.next_child(&node_root.root_ref()) { Some(child) => { self.depth += 1; Some(child.clone()) @@ -735,15 +758,17 @@ impl Iterator<JS<Node>> for NodeIterator { } } -fn gather_abstract_nodes(cur: &JS<Node>, refs: &mut Vec<JS<Node>>, postorder: bool) { +fn gather_abstract_nodes(cur: &JSRef<Node>, refs: &mut Vec<JS<Node>>, postorder: bool) { + let roots = RootCollection::new(); if !postorder { - refs.push(cur.clone()); + refs.push(cur.unrooted()); } - for kid in cur.children() { - gather_abstract_nodes(&kid, refs, postorder) + for kid in cur.unrooted().children() { + let kid = kid.root(&roots); + gather_abstract_nodes(&kid.root_ref(), refs, postorder) } if postorder { - refs.push(cur.clone()); + refs.push(cur.unrooted()); } } @@ -763,12 +788,19 @@ impl Node { } } + pub fn is_element(&self) -> bool { + match self.type_id { + ElementNodeTypeId(..) => true, + _ => false + } + } + pub fn owner_doc<'a>(&'a self) -> &'a JS<Document> { self.owner_doc.get_ref() } - pub fn set_owner_doc(&mut self, document: &JS<Document>) { - self.owner_doc = Some(document.clone()); + pub fn set_owner_doc(&mut self, document: &JSRef<Document>) { + self.owner_doc = Some(document.unrooted()); } pub fn children(&self) -> AbstractNodeChildrenIterator { @@ -788,24 +820,28 @@ impl Node { pub fn reflect_node<N: Reflectable+NodeBase> (node: ~N, - document: &JS<Document>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<Window>, ~N) -> JS<N>) + document: &JSRef<Document>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<Window>, ~N) -> JS<N>) -> JS<N> { + let roots = RootCollection::new(); assert!(node.reflector().get_jsobject().is_null()); - let node = reflect_dom_object(node, &document.get().window, wrap_fn); + let window = document.get().window.root(&roots); + let node = reflect_dom_object(node, &window.root_ref(), wrap_fn); assert!(node.reflector().get_jsobject().is_not_null()); node } pub fn new_inherited(type_id: NodeTypeId, doc: JS<Document>) -> Node { - Node::new_(type_id, Some(doc)) + let roots = RootCollection::new(); + let doc = doc.root(&roots); + Node::new_(type_id, Some(doc.root_ref())) } pub fn new_without_doc(type_id: NodeTypeId) -> Node { Node::new_(type_id, None) } - fn new_(type_id: NodeTypeId, doc: Option<JS<Document>>) -> Node { + fn new_(type_id: NodeTypeId, doc: Option<JSRef<Document>>) -> Node { Node { eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)), type_id: type_id, @@ -816,7 +852,7 @@ impl Node { next_sibling: None, prev_sibling: None, - owner_doc: doc, + owner_doc: doc.map(|doc| doc.unrooted()), child_list: None, flags: NodeFlags::new(type_id), @@ -854,21 +890,21 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-nodename - pub fn NodeName(&self, abstract_self: &JS<Node>) -> DOMString { + pub fn NodeName(&self, abstract_self: &JSRef<Node>) -> DOMString { match self.type_id { ElementNodeTypeId(..) => { - let elem: JS<Element> = ElementCast::to(abstract_self).unwrap(); + let elem: JS<Element> = ElementCast::to(&abstract_self.unrooted()).unwrap(); elem.get().TagName() } TextNodeTypeId => ~"#text", ProcessingInstructionNodeTypeId => { let processing_instruction: JS<ProcessingInstruction> = - ProcessingInstructionCast::to(abstract_self).unwrap(); + ProcessingInstructionCast::to(&abstract_self.unrooted()).unwrap(); processing_instruction.get().Target() } CommentNodeTypeId => ~"#comment", DoctypeNodeTypeId => { - let doctype: JS<DocumentType> = DocumentTypeCast::to(abstract_self).unwrap(); + let doctype: JS<DocumentType> = DocumentTypeCast::to(&abstract_self.unrooted()).unwrap(); doctype.get().name.clone() }, DocumentFragmentNodeTypeId => ~"#document-fragment", @@ -911,12 +947,14 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-childnodes - pub fn ChildNodes(&mut self, abstract_self: &JS<Node>) -> JS<NodeList> { + pub fn ChildNodes(&mut self, abstract_self: &JSRef<Node>) -> JS<NodeList> { + let roots = RootCollection::new(); match self.child_list { None => { let doc = self.owner_doc().clone(); let doc = doc.get(); - let list = NodeList::new_child_list(&doc.window, abstract_self); + let window = doc.window.root(&roots); + let list = NodeList::new_child_list(&window.root_ref(), abstract_self); self.child_list = Some(list.clone()); list } @@ -945,12 +983,12 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn GetNodeValue(&self, abstract_self: &JS<Node>) -> Option<DOMString> { + pub fn GetNodeValue(&self, abstract_self: &JSRef<Node>) -> Option<DOMString> { match self.type_id { CommentNodeTypeId | TextNodeTypeId | ProcessingInstructionNodeTypeId => { - let chardata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); + let chardata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap(); Some(chardata.get().Data()) } _ => { @@ -960,7 +998,7 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-nodevalue - pub fn SetNodeValue(&mut self, abstract_self: &mut JS<Node>, val: Option<DOMString>) + pub fn SetNodeValue(&mut self, abstract_self: &mut JSRef<Node>, val: Option<DOMString>) -> ErrorResult { match self.type_id { CommentNodeTypeId | @@ -973,12 +1011,12 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn GetTextContent(&self, abstract_self: &JS<Node>) -> Option<DOMString> { + pub fn GetTextContent(&self, abstract_self: &JSRef<Node>) -> Option<DOMString> { match self.type_id { DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => { let mut content = ~""; - for node in abstract_self.traverse_preorder() { + for node in abstract_self.unrooted().traverse_preorder() { if node.is_text() { let text: JS<Text> = TextCast::to(&node).unwrap(); content.push_str(text.get().characterdata.data.as_slice()); @@ -989,7 +1027,7 @@ impl Node { CommentNodeTypeId | TextNodeTypeId | ProcessingInstructionNodeTypeId => { - let characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); + let characterdata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap(); Some(characterdata.get().Data()) } DoctypeNodeTypeId | @@ -1000,8 +1038,9 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-textcontent - pub fn SetTextContent(&mut self, abstract_self: &mut JS<Node>, value: Option<DOMString>) + pub fn SetTextContent(&mut self, abstract_self: &mut JSRef<Node>, value: Option<DOMString>) -> ErrorResult { + let roots = RootCollection::new(); let value = null_str_as_empty(&value); match self.type_id { DocumentFragmentNodeTypeId | @@ -1011,17 +1050,20 @@ impl Node { None } else { let document = self.owner_doc(); - Some(NodeCast::from(&document.get().CreateTextNode(document, value))) + let document = document.root(&roots); + Some(NodeCast::from(&document.get().CreateTextNode(&document.root_ref(), value))) }; + let node = node.map(|node| node.root(&roots)); + // Step 3. - Node::replace_all(node, abstract_self); + Node::replace_all(node.root_ref(), abstract_self); } CommentNodeTypeId | TextNodeTypeId | ProcessingInstructionNodeTypeId => { self.wait_until_safe_to_modify_dom(); - let mut characterdata: JS<CharacterData> = CharacterDataCast::to(abstract_self).unwrap(); + let mut characterdata: JS<CharacterData> = CharacterDataCast::to(&abstract_self.unrooted()).unwrap(); characterdata.get_mut().data = value.clone(); // Notify the document that the content of this node is different @@ -1035,15 +1077,20 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-adopt - pub fn adopt(node: &mut JS<Node>, document: &JS<Document>) { + pub fn adopt(node_root: &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) => Node::remove(node, parent, Unsuppressed), + Some(ref mut parent) => { + let parent = parent.root(&roots); + Node::remove(node_root, &mut parent.root_ref(), Unsuppressed); + } None => (), } // Step 2. - if document_from_node(node) != *document { + if document_from_node(&node) != document.unrooted() { for mut descendant in node.traverse_preorder() { descendant.get_mut().set_owner_doc(document); } @@ -1054,8 +1101,11 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-insert - fn pre_insert(node: &mut JS<Node>, parent: &mut JS<Node>, child: Option<JS<Node>>) + fn pre_insert(node_root: &mut JSRef<Node>, parent_root: &mut JSRef<Node>, child: Option<JSRef<Node>>) -> Fallible<JS<Node>> { + let roots = RootCollection::new(); + let node = node_root.unrooted(); + let parent = parent_root.unrooted(); // Step 1. match parent.type_id() { DocumentNodeTypeId | @@ -1065,7 +1115,7 @@ impl Node { } // Step 2. - if node.is_inclusive_ancestor_of(parent) { + if node.is_inclusive_ancestor_of(parent_root) { return Err(HierarchyRequest); } @@ -1097,6 +1147,7 @@ impl Node { } // Step 6. + let child = child.map(|child| child.unrooted()); match parent.type_id() { DocumentNodeTypeId => { match node.type_id() { @@ -1175,25 +1226,31 @@ 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(), _ => child }; + let referenceChild = referenceChild.map(|child| child.root(&roots)); // Step 9. - Node::adopt(node, &document_from_node(parent)); + let document = document_from_node(&parent); + let document = document.root(&roots); + Node::adopt(node_root, &document.root_ref()); // Step 10. - Node::insert(node, parent, referenceChild, Unsuppressed); + Node::insert(node_root, parent_root, referenceChild.root_ref(), Unsuppressed); // Step 11. - return Ok(node.clone()) + return Ok(node) } // http://dom.spec.whatwg.org/#concept-node-insert - fn insert(node: &mut JS<Node>, - parent: &mut JS<Node>, - child: Option<JS<Node>>, + fn insert(node_root: &mut JSRef<Node>, + parent_root: &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. @@ -1206,8 +1263,9 @@ impl Node { // Step 6: DocumentFragment. match node.type_id() { DocumentFragmentNodeTypeId => { - for mut c in node.children() { - Node::remove(&mut c, node, Suppressed); + for c in node.children() { + let c = c.root(&roots); + Node::remove(&mut c.root_ref(), node_root, Suppressed); } }, _ => (), @@ -1216,7 +1274,7 @@ impl Node { // Step 7: mutation records. // Step 8. for node in nodes.mut_iter() { - parent.add_child(node, child.clone()); + parent.add_child(node_root, child.clone()); node.get_mut().flags.set_is_in_doc(parent.is_in_doc()); } @@ -1232,10 +1290,18 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-replace-all - pub fn replace_all(mut node: Option<JS<Node>>, parent: &mut JS<Node>) { + pub fn replace_all(mut node_root: Option<JSRef<Node>>, parent_root: &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 { - Some(ref mut node) => Node::adopt(node, &document_from_node(parent)), + match node_root { + Some(ref mut node) => { + let document = document_from_node(&parent); + let document = document.root(&roots); + Node::adopt(node, &document.root_ref()); + } None => (), } @@ -1252,13 +1318,14 @@ impl Node { }; // Step 4. - for mut child in parent.children() { - Node::remove(&mut child, parent, Suppressed); + for child in parent.children() { + let child = child.root(&roots); + Node::remove(&mut child.root_ref(), parent_root, Suppressed); } // Step 5. - match node { - Some(ref mut node) => Node::insert(node, parent, None, Suppressed), + match node_root { + Some(ref mut node) => Node::insert(node, parent_root, None, Suppressed), None => (), } @@ -1274,10 +1341,10 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-pre-remove - fn pre_remove(child: &mut JS<Node>, parent: &mut JS<Node>) -> Fallible<JS<Node>> { + fn pre_remove(child: &mut JSRef<Node>, parent: &mut JSRef<Node>) -> Fallible<JS<Node>> { // Step 1. - match child.parent_node() { - Some(ref node) if node != parent => return Err(NotFound), + match child.unrooted().parent_node() { + Some(ref node) if node != &parent.unrooted() => return Err(NotFound), _ => () } @@ -1285,17 +1352,19 @@ impl Node { Node::remove(child, parent, Unsuppressed); // Step 3. - Ok(child.clone()) + Ok(child.unrooted()) } // http://dom.spec.whatwg.org/#concept-node-remove - fn remove(node: &mut JS<Node>, parent: &mut JS<Node>, suppress_observers: SuppressObserver) { - assert!(node.parent_node().map_or(false, |ref node_parent| node_parent == parent)); + 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)); // Step 1-5: ranges. // Step 6-7: mutation observers. // Step 8. - parent.remove_child(node); + parent.remove_child(node_root); node.get_mut().flags.set_is_in_doc(false); // Step 9. @@ -1306,63 +1375,67 @@ impl Node { } // http://dom.spec.whatwg.org/#concept-node-clone - pub fn clone(node: &JS<Node>, maybe_doc: Option<&JS<Document>>, + pub fn clone(node: &JSRef<Node>, maybe_doc: Option<&JSRef<Document>>, clone_children: CloneChildrenFlag) -> JS<Node> { + let roots = RootCollection::new(); + // Step 1. let mut document = match maybe_doc { - Some(doc) => doc.clone(), + Some(doc) => doc.unrooted(), None => node.get().owner_doc().clone() }; + let document_root = document.root(&roots); // Step 2. // XXXabinader: clone() for each node as trait? - let mut copy: JS<Node> = match node.type_id() { + let copy: JS<Node> = match node.get().type_id { DoctypeNodeTypeId => { - let doctype: JS<DocumentType> = DocumentTypeCast::to(node).unwrap(); + let doctype: JS<DocumentType> = DocumentTypeCast::to(&node.unrooted()).unwrap(); let doctype = doctype.get(); let doctype = DocumentType::new(doctype.name.clone(), Some(doctype.public_id.clone()), - Some(doctype.system_id.clone()), &document); + Some(doctype.system_id.clone()), &document_root.root_ref()); NodeCast::from(&doctype) }, DocumentFragmentNodeTypeId => { - let doc_fragment = DocumentFragment::new(&document); + let doc_fragment = DocumentFragment::new(&document_root.root_ref()); NodeCast::from(&doc_fragment) }, CommentNodeTypeId => { - let comment: JS<Comment> = CommentCast::to(node).unwrap(); + let comment: JS<Comment> = CommentCast::to(&node.unrooted()).unwrap(); let comment = comment.get(); - let comment = Comment::new(comment.characterdata.data.clone(), &document); + let comment = Comment::new(comment.characterdata.data.clone(), &document_root.root_ref()); NodeCast::from(&comment) }, DocumentNodeTypeId => { - let document: JS<Document> = DocumentCast::to(node).unwrap(); + let document: JS<Document> = DocumentCast::to(&node.unrooted()).unwrap(); let document = document.get(); let is_html_doc = match document.is_html_document { true => HTMLDocument, false => NonHTMLDocument }; - let document = Document::new(&document.window, Some(document.url().clone()), + let window = document.window.root(&roots); + let document = Document::new(&window.root_ref(), Some(document.url().clone()), is_html_doc, None); NodeCast::from(&document) }, ElementNodeTypeId(..) => { - let element: JS<Element> = ElementCast::to(node).unwrap(); + let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); let element = element.get(); - let element = build_element_from_tag(element.local_name.clone(), &document); + let element = build_element_from_tag(element.local_name.clone(), &document_root.root_ref()); NodeCast::from(&element) }, TextNodeTypeId => { - let text: JS<Text> = TextCast::to(node).unwrap(); + let text: JS<Text> = TextCast::to(&node.unrooted()).unwrap(); let text = text.get(); - let text = Text::new(text.characterdata.data.clone(), &document); + let text = Text::new(text.characterdata.data.clone(), &document_root.root_ref()); NodeCast::from(&text) }, ProcessingInstructionNodeTypeId => { - let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(node).unwrap(); + let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node.unrooted()).unwrap(); let pi = pi.get(); let pi = ProcessingInstruction::new(pi.target.clone(), - pi.characterdata.data.clone(), &document); + pi.characterdata.data.clone(), &document_root.root_ref()); NodeCast::from(&pi) }, }; @@ -1371,12 +1444,13 @@ impl Node { if copy.is_document() { document = DocumentCast::to(©).unwrap(); } + let document_root = document.root(&roots); assert!(copy.get().owner_doc() == &document); // Step 4 (some data already copied in step 2). - match node.type_id() { + match node.get().type_id { DocumentNodeTypeId => { - let node_doc: JS<Document> = DocumentCast::to(node).unwrap(); + let node_doc: JS<Document> = DocumentCast::to(&node.unrooted()).unwrap(); let node_doc = node_doc.get(); let mut copy_doc: JS<Document> = DocumentCast::to(©).unwrap(); let copy_doc = copy_doc.get_mut(); @@ -1384,7 +1458,7 @@ impl Node { copy_doc.set_quirks_mode(node_doc.quirks_mode()); }, ElementNodeTypeId(..) => { - let node_elem: JS<Element> = ElementCast::to(node).unwrap(); + let node_elem: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); let node_elem = node_elem.get(); let mut copy_elem: JS<Element> = ElementCast::to(©).unwrap(); @@ -1394,9 +1468,10 @@ impl Node { let copy_elem = copy_elem.get_mut(); // FIXME: https://github.com/mozilla/servo/issues/1737 copy_elem.namespace = node_elem.namespace.clone(); + let window = document.get().window.root(&roots); for attr in node_elem.attrs.iter() { let attr = attr.get(); - copy_elem.attrs.push(Attr::new(&document.get().window, + 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())); @@ -1410,8 +1485,10 @@ impl Node { // Step 6. if clone_children == CloneChildren { for ref child in node.get().children() { - let mut child_copy = Node::clone(child, Some(&document), clone_children); - let _inserted_node = Node::pre_insert(&mut child_copy, &mut copy, None); + 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); } } @@ -1420,7 +1497,7 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-insertbefore - pub fn InsertBefore(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>, child: Option<JS<Node>>) + pub fn InsertBefore(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>, child: Option<JSRef<Node>>) -> Fallible<JS<Node>> { Node::pre_insert(node, abstract_self, child) } @@ -1431,14 +1508,19 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-appendchild - pub fn AppendChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) + pub fn AppendChild(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>) -> Fallible<JS<Node>> { Node::pre_insert(node, abstract_self, None) } // http://dom.spec.whatwg.org/#concept-node-replace - pub fn ReplaceChild(&self, parent: &mut JS<Node>, node: &mut JS<Node>, child: &mut JS<Node>) + pub fn ReplaceChild(&self, parent_root: &mut JSRef<Node>, node_root: &mut JSRef<Node>, child_root: &mut JSRef<Node>) -> Fallible<JS<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() { DocumentNodeTypeId | @@ -1448,12 +1530,12 @@ impl Node { } // Step 2. - if node.is_inclusive_ancestor_of(parent) { + if node.is_inclusive_ancestor_of(parent_root) { return Err(HierarchyRequest); } // Step 3. - if !parent.is_parent_of(child) { + if !parent.is_parent_of(child_root) { return Err(NotFound); } @@ -1484,7 +1566,7 @@ 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(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1498,7 +1580,7 @@ impl Node { }, // Step 6.2 ElementNodeTypeId(..) => { - if parent.child_elements().any(|c| &NodeCast::from(&c) != child) { + if parent.child_elements().any(|c| NodeCast::from(&c) != child) { return Err(HierarchyRequest); } if child.following_siblings() @@ -1508,11 +1590,11 @@ impl Node { }, // Step 6.3 DoctypeNodeTypeId => { - if parent.children().any(|c| c.is_doctype() && &c != child) { + if parent.children().any(|c| c.is_doctype() && c != child) { return Err(HierarchyRequest); } if parent.children() - .take_while(|c| c != child) + .take_while(|c| c != &child) .any(|c| c.is_element()) { return Err(HierarchyRequest); } @@ -1527,26 +1609,29 @@ impl Node { } // Ok if not caught by previous error checks. - if *node == *child { - return Ok(child.clone()); + if node == child { + return Ok(child); } // Step 7-8. let next_sibling = child.next_sibling(); let reference_child = match next_sibling { - Some(ref sibling) if sibling == node => node.next_sibling(), + Some(ref sibling) if sibling == &node => node.next_sibling(), _ => next_sibling }; + let reference_child = reference_child.map(|child| child.root(&roots)); // Step 9. - Node::adopt(node, &document_from_node(parent)); + let document = document_from_node(&parent); + let document = document.root(&roots); + Node::adopt(node_root, &document.root_ref()); { // Step 10. - Node::remove(child, parent, Suppressed); + Node::remove(child_root, parent_root, Suppressed); // Step 11. - Node::insert(node, parent, reference_child, Suppressed); + Node::insert(node_root, parent_root, reference_child.root_ref(), Suppressed); } // Step 12-14. @@ -1561,36 +1646,40 @@ impl Node { } // Step 15. - Ok(child.clone()) + Ok(child) } // http://dom.spec.whatwg.org/#dom-node-removechild - pub fn RemoveChild(&self, abstract_self: &mut JS<Node>, node: &mut JS<Node>) + pub fn RemoveChild(&self, abstract_self: &mut JSRef<Node>, node: &mut JSRef<Node>) -> Fallible<JS<Node>> { Node::pre_remove(node, abstract_self) } // http://dom.spec.whatwg.org/#dom-node-normalize - pub fn Normalize(&mut self, abstract_self: &mut JS<Node>) { + 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(); if characterdata.get().Length() == 0 { - abstract_self.remove_child(&mut child); + let child = child.root(&roots); + abstract_self.remove_child(&mut child.root_ref()); } else { match prev_text { Some(ref text_node) => { let mut prev_characterdata: JS<CharacterData> = CharacterDataCast::to(text_node).unwrap(); let _ = prev_characterdata.get_mut().AppendData(characterdata.get().Data()); - abstract_self.remove_child(&mut child); + let child = child.root(&roots); + abstract_self.remove_child(&mut child.root_ref()); }, None => prev_text = Some(child) } } } else { - let c = &mut child.clone(); - child.get_mut().Normalize(c); + let c = child.root(&roots); + child.get_mut().Normalize(&mut c.root_ref()); prev_text = None; } @@ -1598,7 +1687,7 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-clonenode - pub fn CloneNode(&self, abstract_self: &mut JS<Node>, deep: bool) -> JS<Node> { + pub fn CloneNode(&self, abstract_self: &mut JSRef<Node>, deep: bool) -> JS<Node> { match deep { true => Node::clone(abstract_self, None, CloneChildren), false => Node::clone(abstract_self, None, DoNotCloneChildren) @@ -1606,36 +1695,36 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-isequalnode - pub fn IsEqualNode(&self, abstract_self: &JS<Node>, maybe_node: Option<JS<Node>>) -> bool { - fn is_equal_doctype(node: &JS<Node>, other: &JS<Node>) -> bool { - let doctype: JS<DocumentType> = DocumentTypeCast::to(node).unwrap(); - let other_doctype: JS<DocumentType> = DocumentTypeCast::to(other).unwrap(); + pub fn IsEqualNode(&self, abstract_self: &JSRef<Node>, maybe_node: Option<JSRef<Node>>) -> bool { + fn is_equal_doctype(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let doctype: JS<DocumentType> = DocumentTypeCast::to(&node.unrooted()).unwrap(); + let other_doctype: JS<DocumentType> = DocumentTypeCast::to(&other.unrooted()).unwrap(); (doctype.get().name == other_doctype.get().name) && (doctype.get().public_id == other_doctype.get().public_id) && (doctype.get().system_id == other_doctype.get().system_id) } - fn is_equal_element(node: &JS<Node>, other: &JS<Node>) -> bool { - let element: JS<Element> = ElementCast::to(node).unwrap(); - let other_element: JS<Element> = ElementCast::to(other).unwrap(); + fn is_equal_element(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); + let other_element: JS<Element> = ElementCast::to(&other.unrooted()).unwrap(); // FIXME: namespace prefix (element.get().namespace == other_element.get().namespace) && (element.get().local_name == other_element.get().local_name) && (element.get().attrs.len() == other_element.get().attrs.len()) } - fn is_equal_processinginstruction(node: &JS<Node>, other: &JS<Node>) -> bool { - let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(node).unwrap(); - let other_pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(other).unwrap(); + fn is_equal_processinginstruction(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&node.unrooted()).unwrap(); + let other_pi: JS<ProcessingInstruction> = ProcessingInstructionCast::to(&other.unrooted()).unwrap(); (pi.get().target == other_pi.get().target) && (pi.get().characterdata.data == other_pi.get().characterdata.data) } - fn is_equal_characterdata(node: &JS<Node>, other: &JS<Node>) -> bool { - let characterdata: JS<CharacterData> = CharacterDataCast::to(node).unwrap(); - let other_characterdata: JS<CharacterData> = CharacterDataCast::to(other).unwrap(); + fn is_equal_characterdata(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let characterdata: JS<CharacterData> = CharacterDataCast::to(&node.unrooted()).unwrap(); + let other_characterdata: JS<CharacterData> = CharacterDataCast::to(&other.unrooted()).unwrap(); characterdata.get().data == other_characterdata.get().data } - fn is_equal_element_attrs(node: &JS<Node>, other: &JS<Node>) -> bool { - let element: JS<Element> = ElementCast::to(node).unwrap(); - let other_element: JS<Element> = ElementCast::to(other).unwrap(); + fn is_equal_element_attrs(node: &JSRef<Node>, other: &JSRef<Node>) -> bool { + let element: JS<Element> = ElementCast::to(&node.unrooted()).unwrap(); + let other_element: JS<Element> = ElementCast::to(&other.unrooted()).unwrap(); assert!(element.get().attrs.len() == other_element.get().attrs.len()); element.get().attrs.iter().all(|attr| { other_element.get().attrs.iter().any(|other_attr| { @@ -1645,13 +1734,17 @@ impl Node { }) }) } - fn is_equal_node(this: &JS<Node>, node: &JS<Node>) -> bool { + 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.type_id() != node.type_id() { + if this_node.type_id() != other.type_id() { return false; } - match node.type_id() { + match other.type_id() { // Step 3. DoctypeNodeTypeId if !is_equal_doctype(this, node) => return false, ElementNodeTypeId(..) if !is_equal_element(this, node) => return false, @@ -1664,12 +1757,16 @@ impl Node { } // Step 5. - if this.children().len() != node.children().len() { + if this_node.children().len() != other.children().len() { return false; } // Step 6. - this.children().zip(node.children()).all(|(ref child, ref other_child)| is_equal_node(child, other_child)) + 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()) + }) } match maybe_node { // Step 1. @@ -1680,7 +1777,9 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-comparedocumentposition - pub fn CompareDocumentPosition(&self, abstract_self: &JS<Node>, other: &JS<Node>) -> u16 { + 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(); if abstract_self == other { // step 2. 0 @@ -1688,7 +1787,7 @@ 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; @@ -1696,7 +1795,7 @@ impl Node { lastself = ancestor; } 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; @@ -1720,11 +1819,11 @@ impl Node { } for child in lastself.traverse_preorder() { - if &child == other { + 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; } @@ -1734,10 +1833,10 @@ impl Node { } // http://dom.spec.whatwg.org/#dom-node-contains - pub fn Contains(&self, abstract_self: &JS<Node>, maybe_other: Option<JS<Node>>) -> bool { + pub fn Contains(&self, abstract_self: &JSRef<Node>, maybe_other: Option<JSRef<Node>>) -> bool { match maybe_other { None => false, - Some(ref other) => abstract_self.is_inclusive_ancestor_of(other) + Some(ref other) => abstract_self.unrooted().is_inclusive_ancestor_of(other) } } @@ -1763,34 +1862,34 @@ impl Node { // Low-level pointer stitching // - pub fn set_parent_node(&mut self, new_parent_node: Option<JS<Node>>) { + pub fn set_parent_node(&mut self, new_parent_node: Option<JSRef<Node>>) { let doc = self.owner_doc().clone(); doc.get().wait_until_safe_to_modify_dom(); - self.parent_node = new_parent_node + self.parent_node = new_parent_node.map(|node| node.unrooted()) } - pub fn set_first_child(&mut self, new_first_child: Option<JS<Node>>) { + pub fn set_first_child(&mut self, new_first_child: Option<JSRef<Node>>) { let doc = self.owner_doc().clone(); doc.get().wait_until_safe_to_modify_dom(); - self.first_child = new_first_child + self.first_child = new_first_child.map(|node| node.unrooted()) } - pub fn set_last_child(&mut self, new_last_child: Option<JS<Node>>) { + pub fn set_last_child(&mut self, new_last_child: Option<JSRef<Node>>) { let doc = self.owner_doc().clone(); doc.get().wait_until_safe_to_modify_dom(); - self.last_child = new_last_child + self.last_child = new_last_child.map(|node| node.unrooted()) } - pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<JS<Node>>) { + pub fn set_prev_sibling(&mut self, new_prev_sibling: Option<JSRef<Node>>) { let doc = self.owner_doc().clone(); doc.get().wait_until_safe_to_modify_dom(); - self.prev_sibling = new_prev_sibling + self.prev_sibling = new_prev_sibling.map(|node| node.unrooted()) } - pub fn set_next_sibling(&mut self, new_next_sibling: Option<JS<Node>>) { + pub fn set_next_sibling(&mut self, new_next_sibling: Option<JSRef<Node>>) { let doc = self.owner_doc().clone(); doc.get().wait_until_safe_to_modify_dom(); - self.next_sibling = new_next_sibling + self.next_sibling = new_next_sibling.map(|node| node.unrooted()) } pub fn get_hover_state(&self) -> bool { diff --git a/src/components/script/dom/nodelist.rs b/src/components/script/dom/nodelist.rs index 714f0e34079..751c15ab098 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::node::{Node, NodeHelpers}; use dom::window::Window; @@ -31,18 +31,18 @@ impl NodeList { } } - pub fn new(window: &JS<Window>, + pub fn new(window: &JSRef<Window>, list_type: NodeListType) -> JS<NodeList> { - reflect_dom_object(~NodeList::new_inherited(window.clone(), list_type), + reflect_dom_object(~NodeList::new_inherited(window.unrooted(), list_type), window, NodeListBinding::Wrap) } - pub fn new_simple_list(window: &JS<Window>, elements: Vec<JS<Node>>) -> JS<NodeList> { + pub fn new_simple_list(window: &JSRef<Window>, elements: Vec<JS<Node>>) -> JS<NodeList> { NodeList::new(window, Simple(elements)) } - pub fn new_child_list(window: &JS<Window>, node: &JS<Node>) -> JS<NodeList> { - NodeList::new(window, Children(node.clone())) + pub fn new_child_list(window: &JSRef<Window>, node: &JSRef<Node>) -> JS<NodeList> { + NodeList::new(window, Children(node.unrooted())) } pub fn Length(&self) -> u32 { diff --git a/src/components/script/dom/processinginstruction.rs b/src/components/script/dom/processinginstruction.rs index e39286d9aaa..7064f8d3ca7 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; +use dom::bindings::js::{JS, JSRef}; use dom::characterdata::CharacterData; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; @@ -35,8 +35,8 @@ impl ProcessingInstruction { } } - pub fn new(target: DOMString, data: DOMString, document: &JS<Document>) -> JS<ProcessingInstruction> { - let node = ProcessingInstruction::new_inherited(target, data, document.clone()); + pub fn new(target: DOMString, data: DOMString, document: &JSRef<Document>) -> JS<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 6283b5a350e..e05cec800bb 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::codegen::BindingDeclarations::TestBindingBinding; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use self::TestBindingBinding::TestEnum; @@ -51,8 +51,12 @@ impl TestBinding { pub fn SetByteStringAttribute(&self, _: ByteString) {} pub fn EnumAttribute(&self) -> TestEnum { _empty } pub fn SetEnumAttribute(&self, _: TestEnum) {} - pub fn InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) } - pub fn SetInterfaceAttribute(&self, _: &JS<Blob>) {} + pub fn InterfaceAttribute(&self) -> JS<Blob> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + Blob::new(&window.root_ref()) + } + pub fn SetInterfaceAttribute(&self, _: &JSRef<Blob>) {} pub fn AnyAttribute(&self, _: *JSContext) -> JSVal { NullValue() } pub fn SetAnyAttribute(&self, _: *JSContext, _: JSVal) {} @@ -83,8 +87,12 @@ 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>> { Some(Blob::new(&self.window)) } - pub fn SetInterfaceAttributeNullable(&self, _: Option<JS<Blob>>) {} + pub fn GetInterfaceAttributeNullable(&self) -> Option<JS<Blob>> { + let roots = RootCollection::new(); + let window = self.window.root(&roots); + Some(Blob::new(&window.root_ref())) + } + pub fn SetInterfaceAttributeNullable(&self, _: Option<JSRef<Blob>>) {} pub fn PassBoolean(&self, _: bool) {} pub fn PassByte(&self, _: i8) {} @@ -100,7 +108,7 @@ impl TestBinding { pub fn PassString(&self, _: DOMString) {} pub fn PassByteString(&self, _: ByteString) {} pub fn PassEnum(&self, _: TestEnum) {} - pub fn PassInterface(&self, _: &JS<Blob>) {} + pub fn PassInterface(&self, _: &JSRef<Blob>) {} pub fn PassUnion(&self, _: HTMLElementOrLong) {} pub fn PassAny(&self, _: *JSContext, _: JSVal) {} @@ -118,7 +126,7 @@ impl TestBinding { pub fn PassNullableString(&self, _: Option<DOMString>) {} pub fn PassNullableByteString(&self, _: Option<ByteString>) {} // pub fn PassNullableEnum(&self, _: Option<TestEnum>) {} - pub fn PassNullableInterface(&self, _: Option<JS<Blob>>) {} + pub fn PassNullableInterface(&self, _: Option<JSRef<Blob>>) {} pub fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} pub fn PassNullableAny(&self, _: *JSContext, _: Option<JSVal>) {} @@ -136,7 +144,7 @@ impl TestBinding { pub fn PassOptionalString(&self, _: Option<DOMString>) {} pub fn PassOptionalByteString(&self, _: Option<ByteString>) {} pub fn PassOptionalEnum(&self, _: Option<TestEnum>) {} - pub fn PassOptionalInterface(&self, _: Option<JS<Blob>>) {} + pub fn PassOptionalInterface(&self, _: Option<JSRef<Blob>>) {} pub fn PassOptionalUnion(&self, _: Option<HTMLElementOrLong>) {} pub fn PassOptionalAny(&self, _: *JSContext, _: Option<JSVal>) {} @@ -183,7 +191,7 @@ impl TestBinding { pub fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>) {} pub fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} // pub fn PassOptionalNullableEnumWithDefault(&self, _: Option<TestEnum>) {} - pub fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JS<Blob>>) {} + pub fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JSRef<Blob>>) {} pub fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} pub fn PassOptionalAnyWithDefault(&self, _: *JSContext, _: JSVal) {} diff --git a/src/components/script/dom/text.rs b/src/components/script/dom/text.rs index 417ae255cb9..61c37d2ad52 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::error::Fallible; use dom::characterdata::CharacterData; use dom::document::Document; @@ -35,13 +35,16 @@ impl Text { } } - pub fn new(text: DOMString, document: &JS<Document>) -> JS<Text> { - let node = Text::new_inherited(text, document.clone()); + pub fn new(text: DOMString, document: &JSRef<Document>) -> JS<Text> { + let node = Text::new_inherited(text, document.unrooted()); Node::reflect_node(~node, document, TextBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, text: DOMString) -> Fallible<JS<Text>> { - Ok(Text::new(text.clone(), &owner.get().Document())) + pub fn Constructor(owner: &JSRef<Window>, text: DOMString) -> Fallible<JS<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>> { diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs index 7a2c94fb052..50c97ee8373 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; +use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}; use dom::bindings::error::Fallible; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::event::{Event, EventTypeId, UIEventTypeId}; @@ -36,18 +36,20 @@ impl UIEvent { } } - pub fn new(window: &JS<Window>) -> JS<UIEvent> { + pub fn new(window: &JSRef<Window>) -> JS<UIEvent> { reflect_dom_object(~UIEvent::new_inherited(UIEventTypeId), window, UIEventBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>, + pub fn Constructor(owner: &JSRef<Window>, type_: DOMString, init: &UIEventBinding::UIEventInit) -> Fallible<JS<UIEvent>> { + let roots = RootCollection::new(); let mut ev = UIEvent::new(owner); + let view = init.view.as_ref().map(|view| view.root(&roots)); ev.get_mut().InitUIEvent(type_, init.parent.bubbles, init.parent.cancelable, - init.view.clone(), init.detail); + view.root_ref(), init.detail); Ok(ev) } @@ -63,10 +65,10 @@ impl UIEvent { type_: DOMString, can_bubble: bool, cancelable: bool, - view: Option<JS<Window>>, + view: Option<JSRef<Window>>, detail: i32) { self.event.InitEvent(type_, can_bubble, cancelable); - self.view = view; + self.view = view.map(|view| view.unrooted()); self.detail = detail; } diff --git a/src/components/script/dom/validitystate.rs b/src/components/script/dom/validitystate.rs index 042d41a829a..9a03134169f 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; +use dom::bindings::js::{JS, JSRef}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::window::Window; @@ -23,8 +23,8 @@ impl ValidityState { } } - pub fn new(window: &JS<Window>) -> JS<ValidityState> { - reflect_dom_object(~ValidityState::new_inherited(window.clone()), + pub fn new(window: &JSRef<Window>) -> JS<ValidityState> { + reflect_dom_object(~ValidityState::new_inherited(window.unrooted()), window, ValidityStateBinding::Wrap) } diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 89325125da2..883e24c329e 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -156,7 +156,7 @@ interface TestBinding { void passOptionalNullableString(optional DOMString? arg); void passOptionalNullableByteString(optional ByteString? arg); // void passOptionalNullableEnum(optional TestEnum? arg); - void passOptionalNullableInterface(optional Blob? arg); + //void passOptionalNullableInterface(optional Blob? arg); //XXXjdm disabled until later commit void passOptionalNullableUnion(optional (HTMLElement or long)? arg); void passOptionalBooleanWithDefault(optional boolean arg = false); diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index 1e4f7167f45..a1155434d89 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::BindingDeclarations::WindowBinding; -use dom::bindings::js::JS; -use dom::bindings::trace::Untraceable; +use dom::bindings::js::{JS, JSRef}; +use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::browsercontext::BrowserContext; use dom::document::Document; @@ -35,33 +35,25 @@ use std::rc::Rc; use serialize::{Encoder, Encodable}; use url::Url; -pub struct TimerHandle { - pub handle: i32, - pub cancel_chan: Option<Sender<()>>, -} +#[deriving(Eq, Encodable, TotalEq)] +pub struct TimerId(i32); -impl<S: Encoder<E>, E> Encodable<S, E> for TimerHandle { - fn encode(&self, _s: &mut S) -> Result<(), E> { - Ok(()) - } +#[deriving(Encodable)] +pub struct TimerHandle { + pub handle: TimerId, + pub data: TimerData, + pub cancel_chan: Untraceable<Option<Sender<()>>>, } -impl Hash for TimerHandle { +impl Hash for TimerId { fn hash(&self, state: &mut sip::SipState) { - self.handle.hash(state); - } -} - -impl Eq for TimerHandle { - fn eq(&self, other: &TimerHandle) -> bool { - self.handle == other.handle + let TimerId(id) = *self; + id.hash(state); } } -impl TotalEq for TimerHandle { } - impl TimerHandle { - fn cancel(&self) { + fn cancel(&mut self) { self.cancel_chan.as_ref().map(|chan| chan.send(())); } } @@ -74,7 +66,7 @@ pub struct Window { pub location: Option<JS<Location>>, pub navigator: Option<JS<Navigator>>, pub image_cache_task: ImageCacheTask, - pub active_timers: ~HashMap<i32, TimerHandle>, + pub active_timers: ~HashMap<TimerId, TimerHandle>, pub next_timer_handle: i32, pub compositor: Untraceable<~ScriptListener>, pub browser_context: Option<BrowserContext>, @@ -98,7 +90,7 @@ impl Window { #[unsafe_destructor] impl Drop for Window { fn drop(&mut self) { - for timer_handle in self.active_timers.values() { + for (_, timer_handle) in self.active_timers.mut_iter() { timer_handle.cancel(); } } @@ -107,10 +99,10 @@ impl Drop for Window { // Holder for the various JS values associated with setTimeout // (ie. function value to invoke and all arguments to pass // to the function when calling it) +#[deriving(Encodable)] pub struct TimerData { - pub handle: i32, pub is_interval: bool, - pub funval: JSVal, + pub funval: Traceable<JSVal>, } impl Window { @@ -160,21 +152,21 @@ impl Window { None } - pub fn Location(&mut self, abstract_self: &JS<Window>) -> JS<Location> { + pub fn Location(&mut self, abstract_self: &JSRef<Window>) -> JS<Location> { if self.location.is_none() { self.location = Some(Location::new(abstract_self, self.page.clone())); } self.location.get_ref().clone() } - pub fn Console(&mut self, abstract_self: &JS<Window>) -> JS<Console> { + pub fn Console(&mut self, abstract_self: &JSRef<Window>) -> JS<Console> { if self.console.is_none() { self.console = Some(Console::new(abstract_self)); } self.console.get_ref().clone() } - pub fn Navigator(&mut self, abstract_self: &JS<Window>) -> JS<Navigator> { + pub fn Navigator(&mut self, abstract_self: &JSRef<Window>) -> JS<Navigator> { if self.navigator.is_none() { self.navigator = Some(Navigator::new(abstract_self)); } @@ -243,13 +235,8 @@ impl Window { let id = select.wait(); if id == timeout_handle.id() { timeout_port.recv(); - let data = ~TimerData { - handle: handle, - is_interval: is_interval, - funval: callback, - }; let ScriptChan(ref chan) = chan; - chan.send(FireTimerMsg(page_id, data)); + chan.send(FireTimerMsg(page_id, TimerId(handle))); if !is_interval { break; } @@ -258,7 +245,16 @@ impl Window { } } }); - self.active_timers.insert(handle, TimerHandle { handle: handle, cancel_chan: Some(cancel_chan) }); + let timer_id = TimerId(handle); + let timer = TimerHandle { + handle: timer_id, + cancel_chan: Untraceable::new(Some(cancel_chan)), + data: TimerData { + is_interval: is_interval, + funval: Traceable::new(callback), + } + }; + self.active_timers.insert(timer_id, timer); handle } @@ -267,11 +263,12 @@ impl Window { } pub fn ClearTimeout(&mut self, handle: i32) { - let timer_handle = self.active_timers.pop(&handle); + let mut timer_handle = self.active_timers.pop(&TimerId(handle)); match timer_handle { - Some(handle) => handle.cancel(), + Some(ref mut handle) => handle.cancel(), None => { } } + self.active_timers.remove(&TimerId(handle)); } pub fn SetInterval(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { @@ -282,11 +279,11 @@ impl Window { self.ClearTimeout(handle); } - pub fn Window(&self, abstract_self: &JS<Window>) -> JS<Window> { - abstract_self.clone() + pub fn Window(&self, abstract_self: &JSRef<Window>) -> JS<Window> { + abstract_self.unrooted() } - pub fn Self(&self, abstract_self: &JS<Window>) -> JS<Window> { + pub fn Self(&self, abstract_self: &JSRef<Window>) -> JS<Window> { self.Window(abstract_self) } diff --git a/src/components/script/dom/xmlhttprequest.rs b/src/components/script/dom/xmlhttprequest.rs index 76099a4d0d0..9f2bbf180b5 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; +use dom::bindings::js::{JS, JSRef}; use js::jsapi::JSContext; use js::jsval::{JSVal, NullValue}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; @@ -41,7 +41,7 @@ pub struct XMLHttpRequest { } impl XMLHttpRequest { - pub fn new_inherited(owner: &JS<Window>) -> XMLHttpRequest { + pub fn new_inherited(owner: &JSRef<Window>) -> XMLHttpRequest { XMLHttpRequest { eventtarget: XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestTypeId), ready_state: 0, @@ -56,12 +56,12 @@ impl XMLHttpRequest { response_xml: None } } - pub fn new(window: &JS<Window>) -> JS<XMLHttpRequest> { + pub fn new(window: &JSRef<Window>) -> JS<XMLHttpRequest> { reflect_dom_object(~XMLHttpRequest::new_inherited(window), window, XMLHttpRequestBinding::Wrap) } - pub fn Constructor(owner: &JS<Window>) -> Fallible<JS<XMLHttpRequest>> { + pub fn Constructor(owner: &JSRef<Window>) -> Fallible<JS<XMLHttpRequest>> { Ok(XMLHttpRequest::new(owner)) } pub fn ReadyState(&self) -> u16 { diff --git a/src/components/script/dom/xmlhttprequestupload.rs b/src/components/script/dom/xmlhttprequestupload.rs index bcfb2d02c47..5e06d51b1d3 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; +use dom::bindings::js::{JS, 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: &JS<Window>) -> JS<XMLHttpRequestUpload> { + pub fn new(window: &JSRef<Window>) -> JS<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 18945f9062a..771b75f3e9c 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; +use dom::bindings::js::{JS, JSRef, RootCollection}; use dom::bindings::utils::Reflectable; use dom::document::Document; use dom::element::{AttributeHandlers, HTMLLinkElementTypeId, HTMLIFrameElementTypeId}; @@ -75,16 +75,19 @@ pub struct HtmlParserResult { } trait NodeWrapping { - unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr; - unsafe fn from_hubbub_node(n: hubbub::NodeDataPtr) -> Self; + 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> { - unsafe fn to_hubbub_node(&self) -> hubbub::NodeDataPtr { + 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) -> JS<T> { - JS::from_raw(cast::transmute(n)) + 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 } } @@ -160,7 +163,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: &JS<Document>) -> JS<Element> { +pub fn build_element_from_tag(tag: DOMString, document: &JSRef<Document>) -> JS<Element> { // TODO (Issue #85): use atoms handle_element!(document, tag, "a", HTMLAnchorElement); handle_element!(document, tag, "applet", HTMLAppletElement); @@ -246,7 +249,7 @@ pub fn build_element_from_tag(tag: DOMString, document: &JS<Document>) -> JS<Ele } pub fn parse_html(page: &Page, - document: &mut JS<Document>, + document: &mut JSRef<Document>, url: Url, resource_task: ResourceTask) -> HtmlParserResult { @@ -292,7 +295,9 @@ pub fn parse_html(page: &Page, let mut parser = hubbub::Parser("UTF-8", false); debug!("created parser"); - parser.set_document_node(unsafe { document.to_hubbub_node() }); + let roots = RootCollection::new(); + + parser.set_document_node(unsafe { document.unrooted().to_hubbub_node(&roots) }); parser.enable_scripting(true); parser.enable_styling(true); @@ -309,7 +314,7 @@ pub fn parse_html(page: &Page, let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp)); - unsafe { comment.to_hubbub_node() } + unsafe { comment.to_hubbub_node(&roots) } }, create_doctype: |doctype: ~hubbub::Doctype| { debug!("create doctype"); @@ -322,15 +327,16 @@ pub fn parse_html(page: &Page, let tmp = &*tmp_borrow; let doctype_node = DocumentType::new(name, public_id, system_id, *tmp); unsafe { - doctype_node.to_hubbub_node() + doctype_node.to_hubbub_node(&roots) } }, create_element: |tag: ~hubbub::Tag| { - debug!("create element"); + debug!("create element {:?}", tag.name.clone()); // 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); debug!("-- attach attrs"); for attr in tag.attributes.iter() { @@ -389,7 +395,7 @@ pub fn parse_html(page: &Page, _ => {} } - unsafe { element.to_hubbub_node() } + unsafe { element.to_hubbub_node(&roots) } }, create_text: |data: ~str| { debug!("create text"); @@ -397,16 +403,17 @@ pub fn parse_html(page: &Page, let tmp_borrow = doc_cell.borrow(); let tmp = &*tmp_borrow; let text = Text::new(data, *tmp); - unsafe { text.to_hubbub_node() } + unsafe { text.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); - let mut child: JS<Node> = NodeWrapping::from_hubbub_node(child); - assert!(parent.AppendChild(&mut child).is_ok()); + 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()); } child }, @@ -457,7 +464,7 @@ pub fn parse_html(page: &Page, }, complete_script: |script| { unsafe { - let script: JS<Element> = NodeWrapping::from_hubbub_node(script); + let script: JS<Element> = NodeWrapping::from_hubbub_node(script, None); match script.get_attribute(Null, "src") { Some(src) => { debug!("found script: {:s}", src.get().Value()); diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index a9cd5edbaff..f442ddae7c1 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -7,9 +7,9 @@ use dom::bindings::codegen::RegisterBindings; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, ElementCast, EventCast}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, RootCollection, RootedReference}; use dom::bindings::trace::{Traceable, Untraceable}; -use dom::bindings::utils::{Reflectable, GlobalStaticData, with_gc_enabled, wrap_for_same_compartment}; +use dom::bindings::utils::{Reflectable, GlobalStaticData, wrap_for_same_compartment}; use dom::document::{Document, HTMLDocument}; use dom::element::{Element, AttributeHandlers}; use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent}; @@ -17,7 +17,7 @@ use dom::event::Event; use dom::uievent::UIEvent; use dom::eventtarget::EventTarget; use dom::node::{Node, NodeHelpers}; -use dom::window::{TimerData, Window}; +use dom::window::{TimerId, Window}; use html::hubbub_html_parser::HtmlParserResult; use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript}; use html::hubbub_html_parser; @@ -32,7 +32,7 @@ use layout_interface; use geom::point::Point2D; use geom::size::Size2D; use js::global::DEBUG_FNS; -use js::jsapi::{JSObject, JS_InhibitGC, JS_AllowGC, JS_CallFunctionValue, JS_DefineFunctions}; +use js::jsapi::{JSObject, JS_CallFunctionValue, JS_DefineFunctions}; use js::jsapi::JS_SetWrapObjectCallbacks; use js::jsval::NullValue; use js::rust::{Cx, RtUtils}; @@ -73,7 +73,7 @@ pub enum ScriptMsg { /// Window resized. Sends a DOM event eventually, but first we combine events. ResizeMsg(PipelineId, Size2D<uint>), /// Fires a JavaScript timeout. - FireTimerMsg(PipelineId, ~TimerData), + FireTimerMsg(PipelineId, TimerId), /// Notifies script that reflow is finished. ReflowCompleteMsg(PipelineId, uint), /// Notifies script that window has been resized but to not take immediate action. @@ -427,10 +427,6 @@ impl Page { js_context.set_default_options_and_version(); js_context.set_logging_error_reporter(); - unsafe { - JS_InhibitGC(js_context.deref().ptr); - } - let mut js_info = self.mut_js_info(); *js_info = Some(JSPageInfo { dom_static: GlobalStaticData(), @@ -554,11 +550,7 @@ impl<'a> Drop for ScriptMemoryFailsafe<'a> { Some(owner) => { let mut page_tree = owner.page_tree.borrow_mut(); for page in page_tree.iter() { - let mut js_info = page.mut_js_info(); - unsafe { - JS_AllowGC(js_info.get_ref().js_context.deref().deref().ptr); - } - *js_info = None; + *page.mut_js_info() = None; } } None => (), @@ -700,7 +692,7 @@ impl ScriptTask { AttachLayoutMsg(new_layout_info) => self.handle_new_layout(new_layout_info), LoadMsg(id, url) => self.load(id, url), SendEventMsg(id, event) => self.handle_event(id, event), - FireTimerMsg(id, timer_data) => self.handle_fire_timer_msg(id, timer_data), + FireTimerMsg(id, timer_id) => self.handle_fire_timer_msg(id, timer_id), NavigateMsg(direction) => self.handle_navigate_msg(direction), ReflowCompleteMsg(id, reflow_id) => self.handle_reflow_complete_msg(id, reflow_id), ResizeInactiveMsg(id, new_size) => self.handle_resize_inactive_msg(id, new_size), @@ -733,35 +725,35 @@ impl ScriptTask { } /// Handles a timer that fired. - fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) { + fn handle_fire_timer_msg(&self, id: PipelineId, timer_id: TimerId) { let mut page_tree = self.page_tree.borrow_mut(); let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a pipeline ID not associated with this script task. This is a bug.").page(); let frame = page.frame(); let mut window = frame.get_ref().window.clone(); - { - let timer_handle = window.get().active_timers.find(&timer_data.handle); - if timer_handle.is_none() { - return; + let is_interval; + match window.get().active_timers.find(&timer_id) { + None => return, + Some(timer_handle) => { + let this_value = window.reflector().get_jsobject(); + + // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. + let rval = NullValue(); + let js_info = page.js_info(); + let cx = js_info.get_ref().js_context.deref().deref().ptr; + unsafe { + JS_CallFunctionValue(cx, this_value, *timer_handle.data.funval, + 0, ptr::null(), &rval); + } + + is_interval = timer_handle.data.is_interval; } } - if !timer_data.is_interval { - window.get_mut().active_timers.remove(&timer_data.handle); + if !is_interval { + window.get_mut().active_timers.remove(&timer_id); } - - let this_value = window.reflector().get_jsobject(); - - // TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`. - let rval = NullValue(); - let js_info = page.js_info(); - let cx = js_info.get_ref().js_context.deref().deref().ptr; - with_gc_enabled(cx, || { - unsafe { - JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval); - } - }); } /// Handles a notification that reflow completed. @@ -849,6 +841,8 @@ impl ScriptTask { fn load(&self, pipeline_id: PipelineId, url: Url) { debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id); + let roots = RootCollection::new(); + let mut page_tree = self.page_tree.borrow_mut(); let page_tree = page_tree.find(pipeline_id).expect("ScriptTask: received a load message for a layout channel that is not associated with this script task. This @@ -875,13 +869,15 @@ impl ScriptTask { self.chan.clone(), self.compositor.dup(), self.image_cache_task.clone()); + let window_root = window.root(&roots); page.initialize_js_info(cx.clone(), window.reflector().get_jsobject()); - let mut document = Document::new(&window, Some(url.clone()), HTMLDocument, None); + 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 js_info = page.mut_js_info(); - RegisterBindings::Register(&window, js_info.get_mut_ref()); + RegisterBindings::Register(&window_root.root_ref(), js_info.get_mut_ref()); } self.compositor.set_ready_state(Loading); @@ -889,7 +885,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 document, + &mut doc_root.root_ref(), url.clone(), self.resource_task.clone()); @@ -965,26 +961,28 @@ impl ScriptTask { // Evaluate every script in the document. for file in js_scripts.iter() { - with_gc_enabled((*cx).ptr, || { - let global_obj = window.reflector().get_jsobject(); - //FIXME: this should have some kind of error handling, or explicitly - // drop an exception on the floor. - match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) { - Ok(_) => (), - Err(_) => println!("evaluate_script failed") - } - }); + let global_obj = window.reflector().get_jsobject(); + //FIXME: this should have some kind of error handling, or explicitly + // drop an exception on the floor. + match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) { + Ok(_) => (), + Err(_) => println!("evaluate_script failed") + } } // 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); + let mut event = Event::new(&window_root.root_ref()); 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 winclone = wintarget.clone(); - let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event); + 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 mut fragment_node = page.fragment_node.deref().borrow_mut(); *fragment_node = fragment.map_or(None, |fragid| page.find_fragment_node(fragid)); @@ -1009,48 +1007,58 @@ impl ScriptTask { /// /// TODO: Actually perform DOM event dispatch. fn handle_event(&self, pipeline_id: PipelineId, event: Event_) { - let mut page_tree = self.page_tree.borrow_mut(); - let page = page_tree.find(pipeline_id).expect("ScriptTask: received an event - message for a layout channel that is not associated with this script task. This - is a bug.").page(); + fn get_page<'a>(page_tree: &'a mut PageTree, pipeline_id: PipelineId) -> &'a Page { + page_tree.find(pipeline_id).expect("ScriptTask: received an event \ + message for a layout channel that is not associated with this script task.\ + This is a bug.").page() + } match event { ResizeEvent(new_width, new_height) => { debug!("script got resize event: {:u}, {:u}", new_width, new_height); - { - let mut window_size = page.window_size.deref().borrow_mut(); - *window_size = Size2D(new_width, new_height); - } + let window = { + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); + { + let mut window_size = page.window_size.deref().borrow_mut(); + *window_size = Size2D(new_width, new_height); + } - { let frame = page.frame(); if frame.is_some() { page.damage(ReflowDocumentDamage); page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor) } - } - let mut fragment_node = page.fragment_node.deref().borrow_mut(); - match fragment_node.take() { - Some(node) => self.scroll_fragment_point(pipeline_id, node), - None => {} - } + let mut fragment_node = page.fragment_node.deref().borrow_mut(); + match fragment_node.take() { + Some(node) => self.scroll_fragment_point(pipeline_id, node), + None => {} + } - let frame = page.frame(); - match *frame { - Some(ref frame) => { + frame.as_ref().map(|frame| frame.window.clone()) + }; + + match window { + Some(ref 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 mut uievent = UIEvent::new(&frame.window); - uievent.get_mut().InitUIEvent(~"resize", false, false, Some(frame.window.clone()), 0i32); - let event: &mut JS<Event> = &mut EventCast::from(&uievent); - - let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window); - let winclone = wintarget.clone(); - let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, None, event); + 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(), + None, + &mut event.root_ref()); } - None =>() + None => () } } @@ -1058,6 +1066,8 @@ impl ScriptTask { ReflowEvent => { debug!("script got reflow event"); + let mut page_tree = self.page_tree.borrow_mut(); + let page = get_page(&mut *page_tree, pipeline_id); let frame = page.frame(); if frame.is_some() { page.damage(MatchSelectorsDocumentDamage); @@ -1067,6 +1077,8 @@ impl ScriptTask { ClickEvent(_button, point) => { 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); @@ -1087,7 +1099,9 @@ impl ScriptTask { if node.is_element() { let element: JS<Element> = ElementCast::to(&node).unwrap(); if "a" == element.get().local_name { - self.load_url_from_element(page, &element) + let roots = RootCollection::new(); + let element = element.root(&roots); + self.load_url_from_element(page, &element.root_ref()) } } } @@ -1098,6 +1112,8 @@ impl ScriptTask { MouseDownEvent(..) => {} MouseUpEvent(..) => {} MouseMoveEvent(point) => { + 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) { Some(node_address) => { @@ -1165,9 +1181,9 @@ impl ScriptTask { } } - fn load_url_from_element(&self, page: &Page, element: &JS<Element>) { + fn load_url_from_element(&self, page: &Page, element: &JSRef<Element>) { // if the node's element is "a," load url from href attr - let attr = element.get_attribute(Null, "href"); + let attr = element.unrooted().get_attribute(Null, "href"); for href in attr.iter() { debug!("ScriptTask: clicked on link to {:s}", href.get().Value()); let click_frag = href.get().value_ref().starts_with("#"); @@ -1202,9 +1218,6 @@ fn shut_down_layout(page: &Page) { // compartment to shutdown, run GC, etc. let mut js_info = page.mut_js_info(); - unsafe { - JS_AllowGC(js_info.get_ref().js_context.deref().deref().ptr); - } let mut frame = page.mut_frame(); *frame = None; |