diff options
author | Michael Wu <mwu@mozilla.com> | 2015-04-06 19:27:56 -0400 |
---|---|---|
committer | Michael Wu <mwu@mozilla.com> | 2015-06-19 18:42:48 -0400 |
commit | 675267b7822d2d6c30c0e36fc22e0191b741b973 (patch) | |
tree | 640b22869e8a7eb7d5657df3074f0b0ccd528c29 | |
parent | a256f39796270cd3a5f40f33eaa4e407117b0cc6 (diff) | |
download | servo-675267b7822d2d6c30c0e36fc22e0191b741b973.tar.gz servo-675267b7822d2d6c30c0e36fc22e0191b741b973.zip |
Upgrade to SM 39
205 files changed, 6535 insertions, 5329 deletions
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 7bbaaa2bfe9..de7987e307d 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -521,6 +521,7 @@ pub struct LayoutElement<'le> { impl<'le> LayoutElement<'le> { pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> { + use script::dom::element::ElementHelpers; let style: &Option<PropertyDeclarationBlock> = unsafe { &*self.element.style_attribute().borrow_for_layout() }; @@ -536,6 +537,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> { #[inline] fn get_namespace(self) -> &'le Namespace { + use script::dom::element::ElementHelpers; self.element.namespace() } diff --git a/components/plugins/lints/unrooted_must_root.rs b/components/plugins/lints/unrooted_must_root.rs index 7c1d8161f67..f9e9c7b6db1 100644 --- a/components/plugins/lints/unrooted_must_root.rs +++ b/components/plugins/lints/unrooted_must_root.rs @@ -34,8 +34,7 @@ pub struct UnrootedPass; // TODO (#3874, sort of): unwrap other types like Vec/Option/HashMap/etc fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) { match ty.node { - ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) | - ast::TyPtr(ast::MutTy { ty: ref t, ..}) | ast::TyRptr(_, ast::MutTy { ty: ref t, ..}) => + ast::TyVec(ref t) | ast::TyFixedLengthVec(ref t, _) => lint_unrooted_ty(cx, &**t, warning), ast::TyPath(..) => { match cx.tcx.def_map.borrow()[&ty.id] { @@ -47,7 +46,7 @@ fn lint_unrooted_ty(cx: &Context, ty: &ast::Ty, warning: &str) { _ => (), } } - _ => (), + _ => (), }; } diff --git a/components/plugins/reflector.rs b/components/plugins/reflector.rs index 68a6011e7d4..6bb43552a3e 100644 --- a/components/plugins/reflector.rs +++ b/components/plugins/reflector.rs @@ -25,6 +25,9 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable: fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { &self.$field_name } + fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) { + self.$field_name.set_jsobject(obj); + } } ); impl_item.map(|it| push(Annotatable::Item(it))) @@ -37,6 +40,9 @@ pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable: fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { self.$field_name.reflector() } + fn init_reflector(&mut self, obj: *mut ::js::jsapi::JSObject) { + self.$field_name.init_reflector(obj); + } } ); impl_item.map(|it| push(Annotatable::Item(it))) diff --git a/components/script/devtools.rs b/components/script/devtools.rs index f14e19999a5..ea79a3850a1 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -6,18 +6,19 @@ use devtools_traits::{CachedConsoleMessage, CachedConsoleMessageTypes, PAGE_ERRO use devtools_traits::{EvaluateJSReply, NodeInfo, Modification, TimelineMarker, TimelineMarkerType}; use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::conversions::StringificationBehavior; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::DOMRectBinding::{DOMRectMethods}; use dom::bindings::codegen::Bindings::ElementBinding::{ElementMethods}; use dom::node::{Node, NodeHelpers}; use dom::window::{WindowHelpers, ScriptHelpers}; -use dom::element::Element; use dom::document::DocumentHelpers; use page::{IterablePage, Page}; use msg::constellation_msg::PipelineId; use script_task::{get_page, ScriptTask}; +use js::jsapi::RootedValue; +use js::jsval::UndefinedValue; use std::sync::mpsc::Sender; use std::rc::Rc; @@ -25,53 +26,54 @@ use std::rc::Rc; pub fn handle_evaluate_js(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<EvaluateJSReply>){ let page = get_page(&*page, pipeline); - let window = page.window().root(); + let window = page.window(); let cx = window.r().get_cx(); - let rval = window.r().evaluate_js_on_global_with_result(&eval); + let mut rval = RootedValue::new(cx, UndefinedValue()); + window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut()); - reply.send(if rval.is_undefined() { + reply.send(if rval.ptr.is_undefined() { EvaluateJSReply::VoidValue - } else if rval.is_boolean() { - EvaluateJSReply::BooleanValue(rval.to_boolean()) - } else if rval.is_double() { - EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval, ()).unwrap()) - } else if rval.is_string() { + } else if rval.ptr.is_boolean() { + EvaluateJSReply::BooleanValue(rval.ptr.to_boolean()) + } else if rval.ptr.is_double() { + EvaluateJSReply::NumberValue(FromJSValConvertible::from_jsval(cx, rval.handle(), ()).unwrap()) + } else if rval.ptr.is_string() { //FIXME: use jsstring_to_str when jsval grows to_jsstring EvaluateJSReply::StringValue( - FromJSValConvertible::from_jsval(cx, rval, StringificationBehavior::Default).unwrap()) - } else if rval.is_null() { + FromJSValConvertible::from_jsval(cx, rval.handle(), StringificationBehavior::Default).unwrap()) + } else if rval.ptr.is_null() { EvaluateJSReply::NullValue } else { //FIXME: jsvals don't have an is_int32/is_number yet - assert!(rval.is_object()); + assert!(rval.ptr.is_object()); panic!("object values unimplemented") }).unwrap(); } pub fn handle_get_root_node(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) { let page = get_page(&*page, pipeline); - let document = page.document().root(); + let document = page.document(); - let node: JSRef<Node> = NodeCast::from_ref(document.r()); + let node = NodeCast::from_ref(document.r()); reply.send(node.summarize()).unwrap(); } pub fn handle_get_document_element(page: &Rc<Page>, pipeline: PipelineId, reply: Sender<NodeInfo>) { let page = get_page(&*page, pipeline); - let document = page.document().root(); - let document_element = document.r().GetDocumentElement().root().unwrap(); + let document = page.document(); + let document_element = document.r().GetDocumentElement().unwrap(); - let node: JSRef<Node> = NodeCast::from_ref(document_element.r()); + let node = NodeCast::from_ref(document_element.r()); reply.send(node.summarize()).unwrap(); } -fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Temporary<Node> { +fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Root<Node> { let page = get_page(&*page, pipeline); - let document = page.document().root(); - let node: JSRef<Node> = NodeCast::from_ref(document.r()); + let document = page.document(); + let node = NodeCast::from_ref(document.r()); for candidate in node.traverse_preorder() { - if candidate.root().r().get_unique_id() == node_id { + if candidate.r().get_unique_id() == node_id { return candidate; } } @@ -80,18 +82,17 @@ fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String } pub fn handle_get_children(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Vec<NodeInfo>>) { - let parent = find_node_by_unique_id(&*page, pipeline, node_id).root(); + let parent = find_node_by_unique_id(&*page, pipeline, node_id); let children = parent.r().children().map(|child| { - let child = child.root(); child.r().summarize() }).collect(); reply.send(children).unwrap(); } pub fn handle_get_layout(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<(f32, f32)>) { - let node = find_node_by_unique_id(&*page, pipeline, node_id).root(); - let elem: JSRef<Element> = ElementCast::to_ref(node.r()).expect("should be getting layout of element"); - let rect = elem.GetBoundingClientRect().root(); + let node = find_node_by_unique_id(&*page, pipeline, node_id); + let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element"); + let rect = elem.GetBoundingClientRect(); let width = *rect.r().Width(); let height = *rect.r().Height(); reply.send((width, height)).unwrap(); @@ -141,8 +142,8 @@ pub fn handle_modify_attribute(page: &Rc<Page>, pipeline: PipelineId, node_id: String, modifications: Vec<Modification>) { - let node = find_node_by_unique_id(&*page, pipeline, node_id).root(); - let elem: JSRef<Element> = ElementCast::to_ref(node.r()).expect("should be getting layout of element"); + let node = find_node_by_unique_id(&*page, pipeline, node_id); + let elem = ElementCast::to_ref(node.r()).expect("should be getting layout of element"); for modification in modifications.iter(){ match modification.newValue { @@ -156,7 +157,7 @@ pub fn handle_modify_attribute(page: &Rc<Page>, pub fn handle_wants_live_notifications(page: &Rc<Page>, pipeline_id: PipelineId, send_notifications: bool) { let page = get_page(&*page, pipeline_id); - let window = page.window().root(); + let window = page.window(); window.r().set_devtools_wants_updates(send_notifications); } @@ -167,7 +168,7 @@ pub fn handle_set_timeline_markers(page: &Rc<Page>, for marker_type in &marker_types { match *marker_type { TimelineMarkerType::Reflow => { - let window = page.window().root(); + let window = page.window(); window.r().set_devtools_timeline_marker(TimelineMarkerType::Reflow, reply.clone()); } TimelineMarkerType::DOMEvent => { @@ -180,7 +181,7 @@ pub fn handle_set_timeline_markers(page: &Rc<Page>, pub fn handle_drop_timeline_markers(page: &Rc<Page>, script_task: &ScriptTask, marker_types: Vec<TimelineMarkerType>) { - let window = page.window().root(); + let window = page.window(); for marker_type in &marker_types { match *marker_type { TimelineMarkerType::Reflow => { @@ -195,6 +196,6 @@ pub fn handle_drop_timeline_markers(page: &Rc<Page>, pub fn handle_request_animation_frame(page: &Rc<Page>, id: PipelineId, callback: Box<Fn(f64, )>) { let page = page.find(id).expect("There is no such page"); - let doc = page.document().root(); + let doc = page.document(); doc.r().request_animation_frame(callback); } diff --git a/components/script/dom/activation.rs b/components/script/dom/activation.rs index dbbe4689e1b..67dc0f1b731 100644 --- a/components/script/dom/activation.rs +++ b/components/script/dom/activation.rs @@ -4,7 +4,6 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; -use dom::bindings::js::{JSRef, Temporary, OptionalRootable, Rootable}; use dom::element::{Element, ActivationElementHelpers}; use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; @@ -15,7 +14,7 @@ use std::borrow::ToOwned; /// Trait for elements with defined activation behavior pub trait Activatable { - fn as_element(&self) -> Temporary<Element>; + fn as_element<'a>(&'a self) -> &'a Element; // Is this particular instance of the element activatable? fn is_instance_activatable(&self) -> bool; @@ -27,32 +26,32 @@ pub trait Activatable { fn canceled_activation(&self); // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps - fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>); + fn activation_behavior(&self, event: &Event, target: &EventTarget); // https://html.spec.whatwg.org/multipage/#implicit-submission fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool); // https://html.spec.whatwg.org/multipage/#run-synthetic-click-activation-steps fn synthetic_click_activation(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) { - let element = self.as_element().root(); + let element = self.as_element(); // Step 1 - if element.r().click_in_progress() { + if element.click_in_progress() { return; } // Step 2 - element.r().set_click_in_progress(true); + element.set_click_in_progress(true); // Step 3 self.pre_click_activation(); // Step 4 // https://html.spec.whatwg.org/multipage/#fire-a-synthetic-mouse-event - let win = window_from_node(element.r()).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(element.r()); + let win = window_from_node(element); + let target = EventTargetCast::from_ref(element); let mouse = MouseEvent::new(win.r(), "click".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, Some(win.r()), 1, 0, 0, 0, 0, ctrlKey, shiftKey, altKey, metaKey, - 0, None).root(); - let event: JSRef<Event> = EventCast::from_ref(mouse.r()); + 0, None); + let event = EventCast::from_ref(mouse.r()); event.fire(target); // Step 5 @@ -64,6 +63,6 @@ pub trait Activatable { } // Step 6 - element.r().set_click_in_progress(false); + element.set_click_in_progress(false); } } diff --git a/components/script/dom/attr.rs b/components/script/dom/attr.rs index 299d7408eaf..5ec04a8df87 100644 --- a/components/script/dom/attr.rs +++ b/components/script/dom/attr.rs @@ -6,11 +6,10 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::AttrBinding::{self, AttrMethods}; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Temporary}; -use dom::bindings::js::{OptionalRootable, Rootable, RootedReference}; +use dom::bindings::js::{JS, MutNullableHeap}; +use dom::bindings::js::{Root, RootedReference}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; -use dom::node::Node; use dom::window::Window; use dom::virtualmethods::vtable_for; @@ -125,7 +124,7 @@ pub struct Attr { impl Attr { fn new_inherited(local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, - prefix: Option<Atom>, owner: Option<JSRef<Element>>) -> Attr { + prefix: Option<Atom>, owner: Option<&Element>) -> Attr { Attr { reflector_: Reflector::new(), local_name: local_name, @@ -133,13 +132,13 @@ impl Attr { name: name, namespace: namespace, prefix: prefix, - owner: MutNullableHeap::new(owner.map(JS::from_rooted)), + owner: MutNullableHeap::new(owner.map(JS::from_ref)), } } - pub fn new(window: JSRef<Window>, local_name: Atom, value: AttrValue, + pub fn new(window: &Window, local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, - prefix: Option<Atom>, owner: Option<JSRef<Element>>) -> Temporary<Attr> { + prefix: Option<Atom>, owner: Option<&Element>) -> Root<Attr> { reflect_dom_object( box Attr::new_inherited(local_name, value, name, namespace, prefix, owner), GlobalRef::Window(window), @@ -162,7 +161,7 @@ impl Attr { } } -impl<'a> AttrMethods for JSRef<'a, Attr> { +impl<'a> AttrMethods for &'a Attr { // https://dom.spec.whatwg.org/#dom-attr-localname fn LocalName(self) -> DOMString { (**self.local_name()).to_owned() @@ -177,8 +176,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { fn SetValue(self, value: DOMString) { match self.owner() { None => *self.value.borrow_mut() = AttrValue::String(value), - Some(o) => { - let owner = o.root(); + Some(owner) => { let value = owner.r().parse_attribute(&self.namespace, self.local_name(), value); self.set_value(AttrSettingType::ReplacedAttr, value, owner.r()); } @@ -225,7 +223,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } // https://dom.spec.whatwg.org/#dom-attr-ownerelement - fn GetOwnerElement(self) -> Option<Temporary<Element>> { + fn GetOwnerElement(self) -> Option<Root<Element>> { self.owner() } @@ -236,19 +234,19 @@ impl<'a> AttrMethods for JSRef<'a, Attr> { } pub trait AttrHelpers<'a> { - fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>); + fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element); fn value(self) -> Ref<'a, AttrValue>; fn local_name(self) -> &'a Atom; - fn set_owner(self, owner: Option<JSRef<Element>>); - fn owner(self) -> Option<Temporary<Element>>; + fn set_owner(self, owner: Option<&Element>); + fn owner(self) -> Option<Root<Element>>; fn summarize(self) -> AttrInfo; } -impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> { - fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: JSRef<Element>) { - assert!(Some(owner) == self.owner().root().r()); +impl<'a> AttrHelpers<'a> for &'a Attr { + fn set_value(self, set_type: AttrSettingType, value: AttrValue, owner: &Element) { + assert!(Some(owner) == self.owner().r()); - let node: JSRef<Node> = NodeCast::from_ref(owner); + let node = NodeCast::from_ref(owner); let namespace_is_null = self.namespace == ns!(""); match set_type { @@ -265,21 +263,21 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> { } fn value(self) -> Ref<'a, AttrValue> { - self.extended_deref().value.borrow() + self.value.borrow() } fn local_name(self) -> &'a Atom { - &self.extended_deref().local_name + &self.local_name } /// Sets the owner element. Should be called after the attribute is added /// or removed from its older parent. - fn set_owner(self, owner: Option<JSRef<Element>>) { + fn set_owner(self, owner: Option<&Element>) { let ref ns = self.namespace; - match (self.owner().root().r(), owner) { + match (self.owner().r(), owner) { (None, Some(new)) => { // Already in the list of attributes of new owner. - assert!(new.get_attribute(&ns, &self.local_name).root().r() == Some(self)) + assert!(new.get_attribute(&ns, &self.local_name) == Some(Root::from_ref(self))) } (Some(old), None) => { // Already gone from the list of attributes of old owner. @@ -287,11 +285,11 @@ impl<'a> AttrHelpers<'a> for JSRef<'a, Attr> { } (old, new) => assert!(old == new) } - self.owner.set(owner.map(JS::from_rooted)) + self.owner.set(owner.map(JS::from_ref)) } - fn owner(self) -> Option<Temporary<Element>> { - self.owner.get().map(Temporary::from_rooted) + fn owner(self) -> Option<Root<Element>> { + self.owner.get().map(Root::from_rooted) } fn summarize(self) -> AttrInfo { @@ -311,7 +309,7 @@ pub trait AttrHelpersForLayout { unsafe fn value_atom_forever(&self) -> Option<Atom>; unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]>; unsafe fn local_name_atom_forever(&self) -> Atom; - unsafe fn value(&self) -> &AttrValue; + unsafe fn value_for_layout(&self) -> &AttrValue; } #[allow(unsafe_code)] @@ -354,7 +352,7 @@ impl AttrHelpersForLayout for Attr { } #[inline] - unsafe fn value(&self) -> &AttrValue { + unsafe fn value_for_layout(&self) -> &AttrValue { self.value.borrow_for_layout() } } diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index 4baccae098e..bc6077c8cb7 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -6,15 +6,22 @@ use dom::bindings::error::{Fallible, Error}; use dom::bindings::global::global_object_for_js_object; -use dom::bindings::js::JSRef; use dom::bindings::utils::Reflectable; -use js::jsapi::{JSContext, JSObject, JS_WrapObject, JS_ObjectIsCallable, JS_GetGlobalObject}; +use js::jsapi::{JSContext, JSObject, JS_WrapObject, IsCallable}; use js::jsapi::{JS_GetProperty, JS_IsExceptionPending, JS_ReportPendingException}; +use js::jsapi::{RootedObject, RootedValue, MutableHandleObject, Heap}; +use js::jsapi::{JSAutoCompartment}; +use js::jsapi::{JS_BeginRequest, JS_EndRequest}; +use js::jsapi::{JS_EnterCompartment, JS_LeaveCompartment, JSCompartment}; +use js::jsapi::GetGlobalForObjectCrossCompartment; +use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain}; use js::jsval::{JSVal, UndefinedValue}; -use js::rust::with_compartment; use std::ffi::CString; use std::ptr; +use std::rc::Rc; +use std::intrinsics::return_address; +use std::default::Default; /// The exception handling used for a call. #[derive(Copy, Clone, PartialEq)] @@ -26,7 +33,7 @@ pub enum ExceptionHandling { } /// A common base class for representing IDL callback function types. -#[derive(Copy, Clone,PartialEq)] +#[derive(PartialEq)] #[jstraceable] pub struct CallbackFunction { object: CallbackObject @@ -34,17 +41,23 @@ pub struct CallbackFunction { impl CallbackFunction { /// Create a new `CallbackFunction` for this object. - pub fn new(callback: *mut JSObject) -> CallbackFunction { + pub fn new() -> CallbackFunction { CallbackFunction { object: CallbackObject { - callback: callback + callback: Heap::default() } } } + + /// Initialize the callback function with a value. + /// Should be called once this object is done moving. + pub fn init(&mut self, callback: *mut JSObject) { + self.object.callback.set(callback); + } } /// A common base class for representing IDL callback interface types. -#[derive(Copy, Clone,PartialEq)] +#[derive(PartialEq)] #[jstraceable] pub struct CallbackInterface { object: CallbackObject @@ -53,18 +66,23 @@ pub struct CallbackInterface { /// A common base class for representing IDL callback function and /// callback interface types. #[allow(raw_pointer_derive)] -#[derive(Copy, Clone,PartialEq)] #[jstraceable] struct CallbackObject { /// The underlying `JSObject`. - callback: *mut JSObject, + callback: Heap<*mut JSObject>, +} + +impl PartialEq for CallbackObject { + fn eq(&self, other: &CallbackObject) -> bool { + self.callback.get() == other.callback.get() + } } /// A trait to be implemented by concrete IDL callback function and /// callback interface types. pub trait CallbackContainer { /// Create a new CallbackContainer object for the given `JSObject`. - fn new(callback: *mut JSObject) -> Self; + fn new(callback: *mut JSObject) -> Rc<Self>; /// Returns the underlying `JSObject`. fn callback(&self) -> *mut JSObject; } @@ -72,83 +90,103 @@ pub trait CallbackContainer { impl CallbackInterface { /// Returns the underlying `JSObject`. pub fn callback(&self) -> *mut JSObject { - self.object.callback + self.object.callback.get() } } impl CallbackFunction { /// Returns the underlying `JSObject`. pub fn callback(&self) -> *mut JSObject { - self.object.callback + self.object.callback.get() } } impl CallbackInterface { /// Create a new CallbackInterface object for the given `JSObject`. - pub fn new(callback: *mut JSObject) -> CallbackInterface { + pub fn new() -> CallbackInterface { CallbackInterface { object: CallbackObject { - callback: callback + callback: Heap::default() } } } + /// Initialize the callback function with a value. + /// Should be called once this object is done moving. + pub fn init(&mut self, callback: *mut JSObject) { + self.object.callback.set(callback); + } + /// Returns the property with the given `name`, if it is a callable object, /// or an error otherwise. pub fn get_callable_property(&self, cx: *mut JSContext, name: &str) -> Fallible<JSVal> { - let mut callable = UndefinedValue(); + let mut callable = RootedValue::new(cx, UndefinedValue()); + let obj = RootedObject::new(cx, self.callback()); unsafe { let c_name = CString::new(name).unwrap(); - if JS_GetProperty(cx, self.callback(), c_name.as_ptr(), &mut callable) == 0 { + if JS_GetProperty(cx, obj.handle(), c_name.as_ptr(), + callable.handle_mut()) == 0 { return Err(Error::JSFailed); } - if !callable.is_object() || - JS_ObjectIsCallable(cx, callable.to_object()) == 0 { + if !callable.ptr.is_object() || + IsCallable(callable.ptr.to_object()) == 0 { return Err(Error::Type( format!("The value of the {} property is not callable", name))); } } - Ok(callable) + Ok(callable.ptr) } } /// Wraps the reflector for `p` into the compartment of `cx`. pub fn wrap_call_this_object<T: Reflectable>(cx: *mut JSContext, - p: JSRef<T>) -> *mut JSObject { - let mut obj = p.reflector().get_jsobject(); - assert!(!obj.is_null()); + p: &T, + mut rval: MutableHandleObject) { + rval.set(p.reflector().get_jsobject().get()); + assert!(!rval.get().is_null()); unsafe { - if JS_WrapObject(cx, &mut obj) == 0 { - return ptr::null_mut(); + if JS_WrapObject(cx, rval) == 0 { + rval.set(ptr::null_mut()); } } - - return obj; } /// A class that performs whatever setup we need to safely make a call while /// this class is on the stack. After `new` returns, the call is safe to make. pub struct CallSetup { + /// The compartment for reporting exceptions. + /// As a RootedObject, this must be the first field in order to + /// determine the final address on the stack correctly. + exception_compartment: RootedObject, /// The `JSContext` used for the call. cx: *mut JSContext, + /// The compartment we were in before the call. + old_compartment: *mut JSCompartment, /// The exception handling used for the call. - _handling: ExceptionHandling, + handling: ExceptionHandling, } impl CallSetup { /// Performs the setup needed to make a call. #[allow(unrooted_must_root)] - pub fn new<T: CallbackContainer>(callback: T, handling: ExceptionHandling) -> CallSetup { + pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup { let global = global_object_for_js_object(callback.callback()); - let global = global.root(); let cx = global.r().get_cx(); + unsafe { JS_BeginRequest(cx); } + let exception_compartment = unsafe { + GetGlobalForObjectCrossCompartment(callback.callback()) + }; CallSetup { + exception_compartment: + RootedObject::new_with_addr(cx, exception_compartment, + unsafe { return_address() }), cx: cx, - _handling: handling, + old_compartment: unsafe { JS_EnterCompartment(cx, callback.callback()) }, + handling: handling, } } @@ -160,14 +198,23 @@ impl CallSetup { impl Drop for CallSetup { fn drop(&mut self) { - let need_to_deal_with_exception = unsafe { JS_IsExceptionPending(self.cx) } != 0; + unsafe { JS_LeaveCompartment(self.cx, self.old_compartment); } + let need_to_deal_with_exception = + self.handling == ExceptionHandling::Report && + unsafe { JS_IsExceptionPending(self.cx) } != 0; if need_to_deal_with_exception { unsafe { - let old_global = JS_GetGlobalObject(self.cx); - with_compartment(self.cx, old_global, || { - JS_ReportPendingException(self.cx) - }); + let old_global = RootedObject::new(self.cx, self.exception_compartment.ptr); + let saved = JS_SaveFrameChain(self.cx) != 0; + { + let _ac = JSAutoCompartment::new(self.cx, old_global.ptr); + JS_ReportPendingException(self.cx); + } + if saved { + JS_RestoreFrameChain(self.cx); + } } } + unsafe { JS_EndRequest(self.cx); } } } diff --git a/components/script/dom/bindings/cell.rs b/components/script/dom/bindings/cell.rs index 177fed9397b..6513e250166 100644 --- a/components/script/dom/bindings/cell.rs +++ b/components/script/dom/bindings/cell.rs @@ -40,7 +40,9 @@ impl<T> DOMRefCell<T> { /// so you have to be careful in trace code! #[allow(unsafe_code)] pub unsafe fn borrow_for_gc_trace<'a>(&'a self) -> &'a T { - debug_assert!(task_state::get().contains(SCRIPT | IN_GC)); + // FIXME: IN_GC isn't reliable enough - doesn't catch minor GCs + // https://github.com/servo/servo/issues/6389 + //debug_assert!(task_state::get().contains(SCRIPT | IN_GC)); &*self.value.as_unsafe_cell().get() } diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf index 439ddfbd59e..48b6067d00c 100644 --- a/components/script/dom/bindings/codegen/Bindings.conf +++ b/components/script/dom/bindings/codegen/Bindings.conf @@ -15,7 +15,7 @@ DOMInterfaces = { 'Window': { - 'outerObjectHook': 'Some(bindings::utils::outerize_global as extern fn(*mut JSContext, JSHandleObject) -> *mut JSObject)', + 'outerObjectHook': 'Some(bindings::utils::outerize_global)', }, #FIXME(jdm): This should be 'register': False, but then we don't generate enum types diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index aa1b1ae14d3..f9e929c68da 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -8,12 +8,15 @@ import operator import os import re import string +import textwrap +import functools from WebIDL import ( BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLType, + IDLInterfaceMember, IDLUndefinedValue, ) @@ -103,15 +106,16 @@ class CastableObjectUnwrapper(): codeOnFailure is the code to run if unwrapping fails. """ - def __init__(self, descriptor, source, codeOnFailure): + def __init__(self, descriptor, source, codeOnFailure, handletype): self.substitution = { "source": source, "codeOnFailure": CGIndenter(CGGeneric(codeOnFailure), 8).define(), + "handletype": handletype, } def __str__(self): return string.Template("""\ -match native_from_reflector_jsmanaged(${source}) { +match native_from_handle${handletype}(${source}) { Ok(val) => val, Err(()) => { ${codeOnFailure} @@ -119,6 +123,136 @@ ${codeOnFailure} }""").substitute(self.substitution) +# We'll want to insert the indent at the beginnings of lines, but we +# don't want to indent empty lines. So only indent lines that have a +# non-newline character on them. +lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE) + + +def indent(s, indentLevel=2): + """ + Indent C++ code. + + Weird secret feature: this doesn't indent lines that start with # (such as + #include lines or #ifdef/#endif). + """ + if s == "": + return s + return re.sub(lineStartDetector, indentLevel * " ", s) + + +# dedent() and fill() are often called on the same string multiple +# times. We want to memoize their return values so we don't keep +# recomputing them all the time. +def memoize(fn): + """ + Decorator to memoize a function of one argument. The cache just + grows without bound. + """ + cache = {} + @functools.wraps(fn) + def wrapper(arg): + retval = cache.get(arg) + if retval is None: + retval = cache[arg] = fn(arg) + return retval + return wrapper + +@memoize +def dedent(s): + """ + Remove all leading whitespace from s, and remove a blank line + at the beginning. + """ + if s.startswith('\n'): + s = s[1:] + return textwrap.dedent(s) + + +# This works by transforming the fill()-template to an equivalent +# string.Template. +fill_multiline_substitution_re = re.compile(r"( *)\$\*{(\w+)}(\n)?") + + +@memoize +def compile_fill_template(template): + """ + Helper function for fill(). Given the template string passed to fill(), + do the reusable part of template processing and return a pair (t, + argModList) that can be used every time fill() is called with that + template argument. + + argsModList is list of tuples that represent modifications to be + made to args. Each modification has, in order: i) the arg name, + ii) the modified name, iii) the indent depth. + """ + t = dedent(template) + assert t.endswith("\n") or "\n" not in t + argModList = [] + + def replace(match): + """ + Replaces a line like ' $*{xyz}\n' with '${xyz_n}', + where n is the indent depth, and add a corresponding entry to + argModList. + + Note that this needs to close over argModList, so it has to be + defined inside compile_fill_template(). + """ + indentation, name, nl = match.groups() + depth = len(indentation) + + # Check that $*{xyz} appears by itself on a line. + prev = match.string[:match.start()] + if (prev and not prev.endswith("\n")) or nl is None: + raise ValueError("Invalid fill() template: $*{%s} must appear by itself on a line" % name) + + # Now replace this whole line of template with the indented equivalent. + modified_name = name + "_" + str(depth) + argModList.append((name, modified_name, depth)) + return "${" + modified_name + "}" + + t = re.sub(fill_multiline_substitution_re, replace, t) + return (string.Template(t), argModList) + +def fill(template, **args): + """ + Convenience function for filling in a multiline template. + + `fill(template, name1=v1, name2=v2)` is a lot like + `string.Template(template).substitute({"name1": v1, "name2": v2})`. + + However, it's shorter, and has a few nice features: + + * If `template` is indented, fill() automatically dedents it! + This makes code using fill() with Python's multiline strings + much nicer to look at. + + * If `template` starts with a blank line, fill() strips it off. + (Again, convenient with multiline strings.) + + * fill() recognizes a special kind of substitution + of the form `$*{name}`. + + Use this to paste in, and automatically indent, multiple lines. + (Mnemonic: The `*` is for "multiple lines"). + + A `$*` substitution must appear by itself on a line, with optional + preceding indentation (spaces only). The whole line is replaced by the + corresponding keyword argument, indented appropriately. If the + argument is an empty string, no output is generated, not even a blank + line. + """ + + t, argModList = compile_fill_template(template) + # Now apply argModList to args + for (name, modified_name, depth) in argModList: + if not (args[name] == "" or args[name].endswith("\n")): + raise ValueError("Argument %s with value %r is missing a newline" % (name, args[name])) + args[modified_name] = indent(args[name], depth) + + return t.substitute(args) + class CGThing(): """ Abstract base class for things that spit out code. @@ -232,14 +366,13 @@ class CGMethodCall(CGThing): # Doesn't matter which of the possible signatures we use, since # they all have the same types up to that point; just use # possibleSignatures[0] - caseBody = [CGGeneric("let argv_start = JS_ARGV(cx, vp);")] - caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i], - i, "argv_start", "argc", + caseBody = [ CGArgumentConverter(possibleSignatures[0][1][i], + i, "args", "argc", descriptor) for i in - range(0, distinguishingIndex) ]) + range(0, distinguishingIndex) ] # Select the right overload from our set. - distinguishingArg = "(*argv_start.offset(%d))" % distinguishingIndex + distinguishingArg = "args.get(%d)" % distinguishingIndex def pickFirstSignature(condition, filterLambda): sigs = filter(filterLambda, possibleSignatures) @@ -282,7 +415,7 @@ class CGMethodCall(CGThing): # also allow the unwrapping test to skip having to do codegen # for the null-or-undefined case, which we already handled # above. - caseBody.append(CGGeneric("if (%s).is_object() {" % + caseBody.append(CGGeneric("if %s.get().is_object() {" % (distinguishingArg))) for idx, sig in enumerate(interfacesSigs): caseBody.append(CGIndenter(CGGeneric("loop {"))); @@ -319,7 +452,7 @@ class CGMethodCall(CGThing): # XXXbz Now we're supposed to check for distinguishingArg being # an array or a platform object that supports indexed # properties... skip that last for now. It's a bit of a pain. - pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" % + pickFirstSignature("%s.get().isObject() && IsArrayLike(cx, &%s.get().toObject())" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isArray() or @@ -328,14 +461,14 @@ class CGMethodCall(CGThing): # Check for Date objects # XXXbz Do we need to worry about security wrappers around the Date? - pickFirstSignature("%s.isObject() && JS_ObjectIsDate(cx, &%s.toObject())" % + pickFirstSignature("%s.get().isObject() && JS_ObjectIsDate(cx, &%s.get().toObject())" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isDate() or s[1][distinguishingIndex].type.isObject())) # Check for vanilla JS objects # XXXbz Do we need to worry about security wrappers? - pickFirstSignature("%s.is_object() && !is_platform_object(%s.to_object())" % + pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object())" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isCallback() or s[1][distinguishingIndex].type.isCallbackInterface() or @@ -524,7 +657,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, # failureCode will prevent pending exceptions from being set in cases when # they really should be! if exceptionCode is None: - exceptionCode = "return 0;" + exceptionCode = "return JSFalse;" needsRooting = typeNeedsRooting(type, descriptorProvider) @@ -581,11 +714,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, # Handle the non-object cases by wrapping up the whole # thing in an if cascade. templateBody = ( - "if (${val}).is_object() {\n" + + "if ${val}.get().is_object() {\n" + CGIndenter(CGGeneric(templateBody)).define() + "\n") if type.nullable(): templateBody += ( - "} else if (${val}).is_null_or_undefined() {\n" + "} else if ${val}.get().is_null_or_undefined() {\n" " %s\n") % nullValue templateBody += ( "} else {\n" + @@ -621,8 +754,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if descriptor.interface.isCallback(): name = descriptor.nativeType - declType = CGGeneric(name) - template = "%s::new((${val}).to_object())" % name + declType = CGWrapper(CGGeneric(name), pre="Rc<", post=">") + template = "%s::new(${val}.get().to_object())" % name if type.nullable(): declType = CGWrapper(declType, pre="Option<", post=">") template = wrapObjectTemplate("Some(%s)" % template, "None", @@ -658,17 +791,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, templateBody = str(CastableObjectUnwrapper( descriptor, - "(${val}).to_object()", - unwrapFailureCode)) + "${val}", + unwrapFailureCode, + "value")) declType = CGGeneric(descriptorType) if type.nullable(): templateBody = "Some(%s)" % templateBody declType = CGWrapper(declType, pre="Option<", post=">") - if isMember: - templateBody += ".root()" - templateBody = wrapObjectTemplate(templateBody, "None", isDefinitelyObject, type, failureCode) @@ -681,8 +812,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert not isEnforceRange and not isClamp treatAs = { - "Default": "Default", - "EmptyString": "Empty", + "Default": "StringificationBehavior::Default", + "EmptyString": "StringificationBehavior::Empty", } if treatNullAs not in treatAs: raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs) @@ -794,23 +925,25 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull() declType = CGGeneric('%s::%s' % (type.unroll().module(), type.unroll().identifier.name)) + finalDeclType = CGTemplatedType("Rc", declType) conversion = CGCallbackTempRoot(declType.define()) if type.nullable(): declType = CGTemplatedType("Option", declType) + finalDeclType = CGTemplatedType("Option", finalDeclType) conversion = CGWrapper(conversion, pre="Some(", post=")") if allowTreatNonObjectAsNull and type.treatNonObjectAsNull(): if not isDefinitelyObject: - haveObject = "${val}.is_object()" + haveObject = "${val}.get().is_object()" template = CGIfElseWrapper(haveObject, conversion, CGGeneric("None")).define() else: template = conversion else: - template = CGIfElseWrapper("JS_ObjectIsCallable(cx, ${val}.to_object()) != 0", + template = CGIfElseWrapper("IsCallable(${val}.get().to_object()) != 0", conversion, onFailureNotCallable(failureCode)).define() template = wrapObjectTemplate( @@ -829,29 +962,47 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, else: default = None - return JSToNativeConversionInfo(template, default, declType, needsRooting=needsRooting) + return JSToNativeConversionInfo(template, default, finalDeclType, needsRooting=needsRooting) if type.isAny(): assert not isEnforceRange and not isClamp - declType = CGGeneric("JSVal") - - if defaultValue is None: - default = None - elif isinstance(defaultValue, IDLNullValue): - default = "NullValue()" - elif isinstance(defaultValue, IDLUndefinedValue): - default = "UndefinedValue()" + declType = "" + default = "" + if isMember == "Dictionary": + # TODO: Need to properly root dictionaries + # https://github.com/servo/servo/issues/6381 + declType = CGGeneric("JSVal") + + if defaultValue is None: + default = None + elif isinstance(defaultValue, IDLNullValue): + default = "NullValue()" + elif isinstance(defaultValue, IDLUndefinedValue): + default = "UndefinedValue()" + else: + raise TypeError("Can't handle non-null, non-undefined default value here") else: - raise TypeError("Can't handle non-null, non-undefined default value here") + declType = CGGeneric("HandleValue") + + if defaultValue is None: + default = None + elif isinstance(defaultValue, IDLNullValue): + default = "HandleValue::null()" + elif isinstance(defaultValue, IDLUndefinedValue): + default = "HandleValue::undefined()" + else: + raise TypeError("Can't handle non-null, non-undefined default value here") return handleOptional("${val}", declType, default) if type.isObject(): assert not isEnforceRange and not isClamp + # TODO: Need to root somehow + # https://github.com/servo/servo/issues/6382 declType = CGGeneric("*mut JSObject") - templateBody = wrapObjectTemplate("${val}.to_object()", + templateBody = wrapObjectTemplate("${val}.get().to_object()", "ptr::null_mut()", isDefinitelyObject, type, failureCode) @@ -871,7 +1022,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, " Err(_) => return 0,\n" "}" % typeName) - return handleOptional(template, declType, handleDefaultNull("%s::empty()" % typeName)) + return handleOptional(template, declType, handleDefaultNull("%s::empty(cx)" % typeName)) if type.isVoid(): # This one only happens for return values, and its easy: Just @@ -948,11 +1099,6 @@ def instantiateJSToNativeConversionTemplate(templateBody, replacements, # conversion. result.append(CGGeneric("")) - if needsRooting: - rootBody = "let %s = %s.root();" % (declName, declName) - result.append(CGGeneric(rootBody)) - result.append(CGGeneric("")) - return result; def convertConstIDLValueToJSVal(value): @@ -979,7 +1125,7 @@ class CGArgumentConverter(CGThing): argument list, and the argv and argc strings and generates code to unwrap the argument to the right native type. """ - def __init__(self, argument, index, argv, argc, descriptorProvider, + def __init__(self, argument, index, args, argc, descriptorProvider, invalidEnumValueFatal=True): CGThing.__init__(self) assert(not argument.defaultValue or argument.optional) @@ -987,12 +1133,12 @@ class CGArgumentConverter(CGThing): replacer = { "index": index, "argc": argc, - "argv": argv + "args": args } condition = string.Template("${index} < ${argc}").substitute(replacer) replacementVariables = { - "val": string.Template("(*${argv}.offset(${index}))").substitute(replacer), + "val": string.Template("${args}.get(${index})").substitute(replacer), } info = getJSToNativeConversionInfo( @@ -1032,7 +1178,7 @@ class CGArgumentConverter(CGThing): else: assert argument.optional variadicConversion = { - "val": string.Template("(*${argv}.offset(variadicArg as isize))").substitute(replacer), + "val": string.Template("${args}.get(variadicArg)").substitute(replacer), } innerConverter = instantiateJSToNativeConversionTemplate( template, variadicConversion, declType, "slot", @@ -1066,16 +1212,17 @@ class CGArgumentConverter(CGThing): return self.converter.define() -def wrapForType(jsvalRef, result='result', successCode='return 1;'): +def wrapForType(jsvalRef, result='result', successCode='return 1;', pre=''): """ Reflect a Rust value into JS. - * 'jsvalRef': a Rust reference to the JSVal in which to store the result + * 'jsvalRef': a MutableHandleValue in which to store the result of the conversion; * 'result': the name of the variable in which the Rust value is stored; * 'successCode': the code to run once we have done the conversion. + * 'pre': code to run before the conversion if rooting is necessary """ - wrap = "%s = (%s).to_jsval(cx);" % (jsvalRef, result) + wrap = "%s\n(%s).to_jsval(cx, %s);" % (pre, result, jsvalRef) if successCode: wrap += "\n%s" % successCode return wrap @@ -1142,8 +1289,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): result = CGWrapper(result, pre="Option<", post=">") return result if returnType.isCallback(): - result = CGGeneric('%s::%s' % (returnType.unroll().module(), - returnType.unroll().identifier.name)) + result = CGGeneric('Rc<%s::%s>' % (returnType.unroll().module(), + returnType.unroll().identifier.name)) if returnType.nullable(): result = CGWrapper(result, pre="Option<", post=">") return result @@ -1152,6 +1299,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType.nullable(): result = CGWrapper(result, pre="Option<", post=">") return result + # TODO: Return the value through a MutableHandleValue outparam + # https://github.com/servo/servo/issues/6307 if returnType.isAny(): return CGGeneric("JSVal") if returnType.isObject() or returnType.isSpiderMonkeyInterface(): @@ -1258,9 +1407,9 @@ class MethodDefiner(PropertyDefiner): # FIXME Check for an existing iterator on the interface first. if any(m.isGetter() and m.isIndexed() for m in methods): - self.regular.append({"name": 'iterator', + self.regular.append({"name": '@@iterator', "methodInfo": False, - "nativeName": "JS_ArrayIterator", + "selfHostedName": "ArrayValues", "length": 0, "flags": "JSPROP_ENUMERATE" }) @@ -1280,21 +1429,31 @@ class MethodDefiner(PropertyDefiner): return "" def specData(m): - if m.get("methodInfo", True): - identifier = m.get("nativeName", m["name"]) - jitinfo = "&%s_methodinfo" % identifier - accessor = "genericMethod as NonNullJSNative" - else: + # TODO: Use something like JS_FNSPEC + # https://github.com/servo/servo/issues/6391 + if "selfHostedName" in m: + selfHostedName = '%s as *const u8 as *const i8' % str_to_const_array(m["selfHostedName"]) + assert not m.get("methodInfo", True) + accessor = "None" jitinfo = "0 as *const JSJitInfo" - accessor = m.get("nativeName", m["name"]) - if accessor[0:3] != 'JS_': - accessor = "%s as NonNullJSNative" % accessor - return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], m["flags"]) + else: + selfHostedName = "0 as *const i8" + if m.get("methodInfo", True): + identifier = m.get("nativeName", m["name"]) + jitinfo = "&%s_methodinfo" % identifier + accessor = "Some(genericMethod)" + else: + jitinfo = "0 as *const JSJitInfo" + accessor = 'Some(%s)' % m.get("nativeName", m["name"]) + if m["name"].startswith("@@"): + return ('(SymbolCode::%s as i32 + 1)' % m["name"][2:], accessor, jitinfo, m["length"], m["flags"], selfHostedName) + return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], m["flags"], selfHostedName) + return self.generatePrefableArray( array, name, - ' JSFunctionSpec { name: %s as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: Some(%s), info: %s}, nargs: %s, flags: %s as u16, selfHostedName: 0 as *const libc::c_char }', - ' JSFunctionSpec { name: 0 as *const libc::c_char, call: JSNativeWrapper {op: None, info: 0 as *const JSJitInfo}, nargs: 0, flags: 0, selfHostedName: 0 as *const libc::c_char }', + ' JSFunctionSpec { name: %s as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: %s, info: %s}, nargs: %s, flags: %s as u16, selfHostedName: %s }', + ' JSFunctionSpec { name: 0 as *const i8, call: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, nargs: 0, flags: 0, selfHostedName: 0 as *const i8 }', 'JSFunctionSpec', specData) @@ -1314,12 +1473,12 @@ class AttrDefiner(PropertyDefiner): return "" def flags(attr): - return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS" + return "JSPROP_SHARED | JSPROP_ENUMERATE" def getter(attr): if self.static: accessor = 'get_' + attr.identifier.name - jitinfo = "0" + jitinfo = "0 as *const JSJitInfo" else: if attr.hasLenientThis(): accessor = "genericLenientGetter" @@ -1327,17 +1486,17 @@ class AttrDefiner(PropertyDefiner): accessor = "genericGetter" jitinfo = "&%s_getterinfo" % attr.identifier.name - return ("JSPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}" + return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }" % {"info" : jitinfo, "native" : accessor}) def setter(attr): if attr.readonly and not attr.getExtendedAttribute("PutForwards"): - return "JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}" + return "JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }" if self.static: accessor = 'set_' + attr.identifier.name - jitinfo = "0" + jitinfo = "0 as *const JSJitInfo" else: if attr.hasLenientThis(): accessor = "genericLenientSetter" @@ -1345,7 +1504,7 @@ class AttrDefiner(PropertyDefiner): accessor = "genericSetter" jitinfo = "&%s_setterinfo" % attr.identifier.name - return ("JSStrictPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}" + return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }" % {"info" : jitinfo, "native" : accessor}) @@ -1355,8 +1514,8 @@ class AttrDefiner(PropertyDefiner): return self.generatePrefableArray( array, name, - ' JSPropertySpec { name: %s as *const u8 as *const libc::c_char, tinyid: 0, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }', - ' JSPropertySpec { name: 0 as *const libc::c_char, tinyid: 0, flags: 0, getter: JSPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}, setter: JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo} }', + ' JSPropertySpec { name: %s as *const u8 as *const libc::c_char, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }', + ' JSPropertySpec { name: 0 as *const i8, flags: 0, getter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, setter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo } }', 'JSPropertySpec', specData) @@ -1562,8 +1721,9 @@ class CGDOMJSClass(CGThing): self.descriptor = descriptor def define(self): - traceHook = 'Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject))' % TRACE_HOOK_NAME + traceHook = 'Some(%s)' % TRACE_HOOK_NAME if self.descriptor.isGlobal(): + traceHook = "Some(js::jsapi::_Z24JS_GlobalObjectTraceHookP8JSTracerP8JSObject)" flags = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL" slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1" else: @@ -1571,66 +1731,54 @@ class CGDOMJSClass(CGThing): slots = "1" return """\ static Class: DOMJSClass = DOMJSClass { - base: js::Class { + base: js::jsapi::Class { name: %s as *const u8 as *const libc::c_char, - flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s), - addProperty: Some(JS_PropertyStub), - delProperty: Some(JS_PropertyStub), - getProperty: Some(JS_PropertyStub), - setProperty: Some(JS_StrictPropertyStub), - enumerate: Some(JS_EnumerateStub), - resolve: Some(JS_ResolveStub), - convert: Some(JS_ConvertStub), - finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)), - checkAccess: None, + flags: JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s), + addProperty: None, + delProperty: None, + getProperty: None, + setProperty: None, + enumerate: None, + resolve: None, + convert: None, + finalize: Some(%s), call: None, hasInstance: None, construct: None, trace: %s, - ext: js::ClassExtension { - equality: 0 as *const u8, + spec: js::jsapi::ClassSpec { + createConstructor: None, + createPrototype: None, + constructorFunctions: 0 as *const js::jsapi::JSFunctionSpec, + constructorProperties: 0 as *const js::jsapi::JSPropertySpec, + prototypeFunctions: 0 as *const js::jsapi::JSFunctionSpec, + prototypeProperties: 0 as *const js::jsapi::JSPropertySpec, + finishInit: None, + flags: 0, + }, + + ext: js::jsapi::ClassExtension { outerObject: %s, innerObject: None, - iteratorObject: 0 as *const u8, - unused: 0 as *const u8, - isWrappedNative: 0 as *const u8, + isWrappedNative: 0, + weakmapKeyDelegateOp: None, + objectMovedOp: None, }, - ops: js::ObjectOps { - lookupGeneric: 0 as *const u8, - lookupProperty: 0 as *const u8, - lookupElement: 0 as *const u8, - lookupSpecial: 0 as *const u8, - defineGeneric: 0 as *const u8, - defineProperty: 0 as *const u8, - defineElement: 0 as *const u8, - defineSpecial: 0 as *const u8, - getGeneric: 0 as *const u8, - getProperty: 0 as *const u8, - getElement: 0 as *const u8, - getElementIfPresent: 0 as *const u8, - getSpecial: 0 as *const u8, - setGeneric: 0 as *const u8, - setProperty: 0 as *const u8, - setElement: 0 as *const u8, - setSpecial: 0 as *const u8, - getGenericAttributes: 0 as *const u8, - getPropertyAttributes: 0 as *const u8, - getElementAttributes: 0 as *const u8, - getSpecialAttributes: 0 as *const u8, - setGenericAttributes: 0 as *const u8, - setPropertyAttributes: 0 as *const u8, - setElementAttributes: 0 as *const u8, - setSpecialAttributes: 0 as *const u8, - deleteProperty: 0 as *const u8, - deleteElement: 0 as *const u8, - deleteSpecial: 0 as *const u8, - - enumerate: 0 as *const u8, - typeOf: 0 as *const u8, + ops: js::jsapi::ObjectOps { + lookupProperty: None, + defineProperty: None, + hasProperty: None, + getProperty: None, + setProperty: None, + getOwnPropertyDescriptor: None, + deleteProperty: None, + watch: None, + unwatch: None, + getElements: None, + enumerate: None, thisObject: %s, - clear: 0 as *const u8, }, }, dom_class: %s @@ -1640,7 +1788,7 @@ static Class: DOMJSClass = DOMJSClass { FINALIZE_HOOK_NAME, traceHook, self.descriptor.outerObjectHook, self.descriptor.outerObjectHook, - CGIndenter(CGGeneric(DOMClass(self.descriptor))).define()) + CGGeneric(DOMClass(self.descriptor)).define()) def str_to_const_array(s): return "b\"%s\\0\"" % s @@ -1655,20 +1803,19 @@ class CGPrototypeJSClass(CGThing): static PrototypeClass: JSClass = JSClass { name: %s as *const u8 as *const libc::c_char, flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT, //JSCLASS_HAS_RESERVED_SLOTS(1) - addProperty: Some(JS_PropertyStub), - delProperty: Some(JS_PropertyStub), - getProperty: Some(JS_PropertyStub), - setProperty: Some(JS_StrictPropertyStub), - enumerate: Some(JS_EnumerateStub), - resolve: Some(JS_ResolveStub), - convert: Some(JS_ConvertStub), + addProperty: None, + delProperty: None, + getProperty: None, + setProperty: None, + enumerate: None, + resolve: None, + convert: None, finalize: None, - checkAccess: None, call: None, hasInstance: None, construct: None, trace: None, - reserved: [0 as *mut libc::c_void; 40] + reserved: [0 as *mut libc::c_void; 25] }; """ % str_to_const_array(self.descriptor.interface.identifier.name + "Prototype") @@ -1742,13 +1889,7 @@ class CGGeneric(CGThing): class CGCallbackTempRoot(CGGeneric): def __init__(self, name): - val = "%s::new(tempRoot)" % name - define = """\ -{ - let tempRoot = ${val}.to_object(); - %s -}""" % val - CGGeneric.__init__(self, define) + CGGeneric.__init__(self, "%s::new(${val}.get().to_object())" % name) def getAllTypes(descriptors, dictionaries, callbacks): @@ -1792,12 +1933,13 @@ def UnionTypes(descriptors, dictionaries, callbacks, config): 'dom::bindings::codegen::PrototypeList', 'dom::bindings::conversions::FromJSValConvertible', 'dom::bindings::conversions::ToJSValConvertible', - 'dom::bindings::conversions::native_from_reflector_jsmanaged', - 'dom::bindings::conversions::StringificationBehavior::Default', + 'dom::bindings::conversions::native_from_handlevalue', + 'dom::bindings::conversions::StringificationBehavior', 'dom::bindings::error::throw_not_in_union', - 'dom::bindings::js::Unrooted', + 'dom::bindings::js::Root', 'dom::types::*', 'js::jsapi::JSContext', + 'js::jsapi::{HandleValue, MutableHandleValue}', 'js::jsval::JSVal', 'util::str::DOMString', ] @@ -1917,32 +2059,36 @@ class CGAbstractMethod(CGThing): assert(False) # Override me! def CreateBindingJSObject(descriptor, parent=None): - create = "let mut raw: Unrooted<%s> = Unrooted::from_raw(&*object);\n" % descriptor.concreteType + create = "let mut raw = boxed::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n" if descriptor.proxy: assert not descriptor.isGlobal() create += """ let handler = RegisterBindings::proxy_handlers[PrototypeList::Proxies::%s as usize]; -let mut private = PrivateValue(boxed::into_raw(object) as *const libc::c_void); -let obj = with_compartment(cx, proto, || { +let private = RootedValue::new(cx, PrivateValue(raw as *const libc::c_void)); +let obj = { + let _ac = JSAutoCompartment::new(cx, proto.ptr); NewProxyObject(cx, handler, - &private, - proto, %s, + private.handle(), + proto.ptr, %s.get(), ptr::null_mut(), ptr::null_mut()) -}); -assert!(!obj.is_null());\ +}; +assert!(!obj.is_null()); +let obj = RootedObject::new(cx, obj);\ """ % (descriptor.name, parent) else: if descriptor.isGlobal(): - create += "let obj = create_dom_global(cx, &Class.base as *const js::Class as *const JSClass);\n" + create += "let obj = RootedObject::new(cx, create_dom_global(cx, &Class.base as *const js::jsapi::Class as *const JSClass, Some(%s)));\n" % TRACE_HOOK_NAME else: - create += ("let obj = with_compartment(cx, proto, || {\n" - " JS_NewObject(cx, &Class.base as *const js::Class as *const JSClass, &*proto, &*%s)\n" - "});\n" % parent) + create += ("let obj = {\n" + " let _ac = JSAutoCompartment::new(cx, proto.ptr);\n" + " JS_NewObjectWithGivenProto(cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle())\n" + "};\n" + "let obj = RootedObject::new(cx, obj);\n") create += """\ -assert!(!obj.is_null()); +assert!(!obj.ptr.is_null()); -JS_SetReservedSlot(obj, DOM_OBJECT_SLOT, - PrivateValue(boxed::into_raw(object) as *const libc::c_void));""" +JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT, + PrivateValue(raw as *const libc::c_void));""" return create class CGWrapMethod(CGAbstractMethod): @@ -1958,37 +2104,46 @@ class CGWrapMethod(CGAbstractMethod): else: args = [Argument('*mut JSContext', 'cx'), Argument("Box<%s>" % descriptor.concreteType, 'object', mutable=True)] - retval = 'Temporary<%s>' % descriptor.concreteType + retval = 'Root<%s>' % descriptor.concreteType CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, pub=True) def definition_body(self): if not self.descriptor.isGlobal(): return CGGeneric("""\ +let _ar = JSAutoRequest::new(cx); let scope = scope.reflector().get_jsobject(); -assert!(!scope.is_null()); -assert!(((*JS_GetClass(scope)).flags & JSCLASS_IS_GLOBAL) != 0); +assert!(!scope.get().is_null()); +assert!(((*JS_GetClass(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0); -let proto = with_compartment(cx, scope, || GetProtoObject(cx, scope, scope)); -assert!(!proto.is_null()); +let mut proto = RootedObject::new(cx, ptr::null_mut()); +{ + let _ac = JSAutoCompartment::new(cx, scope.get()); + GetProtoObject(cx, scope, scope, proto.handle_mut()) +} +assert!(!proto.ptr.is_null()); %s -raw.reflector().set_jsobject(obj); +(*raw).init_reflector(obj.ptr); -Temporary::from_unrooted(raw)""" % CreateBindingJSObject(self.descriptor, "scope")) +Root::from_ref(&*raw)""" % CreateBindingJSObject(self.descriptor, "scope")) else: return CGGeneric("""\ +let _ar = JSAutoRequest::new(cx); %s -with_compartment(cx, obj, || { - let proto = GetProtoObject(cx, obj, obj); - JS_SetPrototype(cx, obj, proto); - raw.reflector().set_jsobject(obj); +let _ac = JSAutoCompartment::new(cx, obj.ptr); +let mut proto = RootedObject::new(cx, ptr::null_mut()); +GetProtoObject(cx, obj.handle(), obj.handle(), proto.handle_mut()); +JS_SetPrototype(cx, obj.handle(), proto.handle()); + +(*raw).init_reflector(obj.ptr); - RegisterBindings::Register(cx, obj); -}); +let ret = Root::from_ref(&*raw); -Temporary::from_unrooted(raw)""" % CreateBindingJSObject(self.descriptor)) +RegisterBindings::Register(cx, obj.handle()); + +ret""" % CreateBindingJSObject(self.descriptor)) class CGIDLInterface(CGThing): @@ -2083,21 +2238,23 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): properties should be a PropertyArrays instance. """ def __init__(self, descriptor, properties): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'), - Argument('*mut JSObject', 'receiver')] - CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'), + Argument('HandleObject', 'receiver'), + Argument('MutableHandleObject', 'rval')] + CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args) self.properties = properties def definition_body(self): protoChain = self.descriptor.prototypeChain if len(protoChain) == 1: - getParentProto = "JS_GetObjectPrototype(cx, global)" + getParentProto = "parent_proto.ptr = JS_GetObjectPrototype(cx, global)" else: parentProtoName = self.descriptor.prototypeChain[-2] - getParentProto = ("%s::GetProtoObject(cx, global, receiver)" % + getParentProto = ("%s::GetProtoObject(cx, global, receiver, parent_proto.handle_mut())" % toBindingNamespace(parentProtoName)) - getParentProto = ("let parent_proto: *mut JSObject = %s;\n" - "assert!(!parent_proto.is_null());\n") % getParentProto + getParentProto = ("let mut parent_proto = RootedObject::new(cx, ptr::null_mut());\n" + "%s;\n" + "assert!(!parent_proto.ptr.is_null());\n") % getParentProto if self.descriptor.interface.isCallback(): protoClass = "None" @@ -2127,10 +2284,10 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): constructor = 'None' call = """\ -return do_create_interface_objects(cx, global, receiver, parent_proto, - %s, %s, - %s, - &sNativeProperties);""" % (protoClass, constructor, domClass) +do_create_interface_objects(cx, receiver, parent_proto.handle(), + %s, %s, + %s, + &sNativeProperties, rval);""" % (protoClass, constructor, domClass) return CGList([ CGGeneric(getParentProto), @@ -2143,10 +2300,11 @@ class CGGetPerInterfaceObject(CGAbstractMethod): constructor object). """ def __init__(self, descriptor, name, idPrefix="", pub=False): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'), - Argument('*mut JSObject', 'receiver')] + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'), + Argument('HandleObject', 'receiver'), + Argument('MutableHandleObject', 'rval')] CGAbstractMethod.__init__(self, descriptor, name, - '*mut JSObject', args, pub=pub) + 'void', args, pub=pub) self.id = idPrefix + "ID::" + self.descriptor.name def definition_body(self): return CGGeneric(""" @@ -2157,19 +2315,22 @@ class CGGetPerInterfaceObject(CGAbstractMethod): wrapper and global is the sandbox's global. */ -assert!(((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0); +assert!(((*JS_GetClass(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0); /* Check to see whether the interface objects are already installed */ -let proto_or_iface_array = get_proto_or_iface_array(global); -let cached_object: *mut JSObject = (*proto_or_iface_array)[%s as usize]; -if cached_object.is_null() { - let tmp: *mut JSObject = CreateInterfaceObjects(cx, global, receiver); - assert!(!tmp.is_null()); - (*proto_or_iface_array)[%s as usize] = tmp; - tmp -} else { - cached_object -}""" % (self.id, self.id)) +let proto_or_iface_array = get_proto_or_iface_array(global.get()); +rval.set((*proto_or_iface_array)[%s as usize]); +if !rval.get().is_null() { + return; +} + +CreateInterfaceObjects(cx, global, receiver, rval); +assert!(!rval.get().is_null()); +(*proto_or_iface_array)[%s as usize] = rval.get(); +if <*mut JSObject>::needs_post_barrier(rval.get()) { + <*mut JSObject>::post_barrier((*proto_or_iface_array).as_mut_ptr().offset(%s as isize)) +} +""" % (self.id, self.id, self.id)) class CGGetProtoObjectMethod(CGGetPerInterfaceObject): """ @@ -2224,40 +2385,39 @@ class CGDefineProxyHandler(CGAbstractMethod): body = """\ let traps = ProxyTraps { - getPropertyDescriptor: Some(get_property_descriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool), - getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool), - defineProperty: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut JSPropertyDescriptor) -> bool), - getOwnPropertyNames: Some(proxyhandler::get_own_property_names as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool), - delete_: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), - enumerate: Some(proxyhandler::enumerate as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool), - + enter: None, + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), + defineProperty: Some(%s), + ownPropertyKeys: Some(proxyhandler::own_property_keys), + delete_: Some(%s), + enumerate: None, + preventExtensions: Some(proxyhandler::prevent_extensions), + isExtensible: Some(proxyhandler::is_extensible), has: None, - hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), - get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool), + get: Some(get), set: None, - keys: None, - iterate: None, - call: None, construct: None, - nativeCall: ptr::null(), + getPropertyDescriptor: Some(get_property_descriptor), + hasOwn: Some(hasOwn), + getOwnEnumerablePropertyKeys: None, + nativeCall: None, hasInstance: None, - typeOf: None, objectClassIs: None, - obj_toString: Some(obj_toString as unsafe extern "C" fn(*mut JSContext, *mut JSObject) -> *mut js::jsapi::JSString), + className: Some(className), fun_toString: None, - //regexp_toShared: ptr::null(), + boxedValue_unbox: None, defaultValue: None, - iteratorNext: None, - finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)), - getElementIfPresent: None, - getPrototypeOf: None, - trace: Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject)) + trace: Some(%s), + finalize: Some(%s), + objectMoved: None, + isCallable: None, + isConstructor: None, }; CreateProxyHandler(&traps, &Class as *const _ as *const _)\ -""" % (customDefineProperty, customDelete, FINALIZE_HOOK_NAME, - TRACE_HOOK_NAME) +""" % (customDefineProperty, customDelete, TRACE_HOOK_NAME, + FINALIZE_HOOK_NAME) return CGGeneric(body) @@ -2270,7 +2430,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): assert descriptor.interface.hasInterfaceObject() args = [ Argument('*mut JSContext', 'cx'), - Argument('*mut JSObject', 'global'), + Argument('HandleObject', 'global'), ] CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True) @@ -2279,10 +2439,17 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): def definition_body(self): if self.descriptor.interface.isCallback(): - code = "CreateInterfaceObjects(cx, global, global);" + code = """\ +let mut obj = RootedObject::new(cx, ptr::null_mut()); +CreateInterfaceObjects(cx, global, global, obj.handle_mut()); +""" else: - code = "assert!(!GetProtoObject(cx, global, global).is_null());" - return CGGeneric("assert!(!global.is_null());\n" + code) + code = """\ +let mut proto = RootedObject::new(cx, ptr::null_mut()); +GetProtoObject(cx, global, global, proto.handle_mut()); +assert!(!proto.ptr.is_null()); +""" + return CGGeneric("assert!(!global.get().is_null());\n" + code) def needCx(returnType, arguments, considerTypes): return (considerTypes and @@ -2329,7 +2496,7 @@ class CGCallGenerator(CGThing): if static: call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name) else: - call = CGWrapper(call, pre="%s.r()." % object) + call = CGWrapper(call, pre="%s." % object) call = CGList([call, CGWrapper(args, pre="(", post=")")]) self.cgRoot.append(CGList([ @@ -2344,8 +2511,7 @@ class CGCallGenerator(CGThing): if static: glob = "" else: - glob = " let global = global_object_for_js_object(this.r().reflector().get_jsobject());\n"\ - " let global = global.root();\n" + glob = " let global = global_object_for_js_object(this.reflector().get_jsobject().get());\n" self.cgRoot.append(CGGeneric( "let result = match result {\n" @@ -2357,9 +2523,6 @@ class CGCallGenerator(CGThing): " },\n" "};" % (glob, errorResult))) - if typeRetValNeedsRooting(returnType): - self.cgRoot.append(CGGeneric("let result = result.root();")) - def define(self): return self.cgRoot.define() @@ -2403,22 +2566,15 @@ class CGPerSignatureCall(CGThing): self.argsPre = argsPre self.arguments = arguments self.argCount = len(arguments) - if self.argCount > argConversionStartsAt: - # Insert our argv in there - cgThings = [CGGeneric(self.getArgvDecl())] - else: - cgThings = [] - cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(), + cgThings = [] + cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgs(), self.getArgc(), self.descriptor, invalidEnumValueFatal=not setter) for i in range(argConversionStartsAt, self.argCount)]) errorResult = None if self.isFallible(): - if nativeMethodName == "NamedSetter": - errorResult = " false" - else: - errorResult = " false as JSBool" + errorResult = " JSFalse" cgThings.append(CGCallGenerator( errorResult, @@ -2427,10 +2583,8 @@ class CGPerSignatureCall(CGThing): static)) self.cgRoot = CGList(cgThings, "\n") - def getArgv(self): - return "argv" if self.argCount > 0 else "" - def getArgvDecl(self): - return "\nlet argv = JS_ARGV(cx, vp);\n" + def getArgs(self): + return "args" if self.argCount > 0 else "" def getArgc(self): return "argc" def getArguments(self): @@ -2445,7 +2599,7 @@ class CGPerSignatureCall(CGThing): return not 'infallible' in self.extendedAttributes def wrap_return_value(self): - return wrapForType('*vp') + return wrapForType('args.rval()') def define(self): return (self.cgRoot.define() + "\n" + self.wrap_return_value()) @@ -2551,7 +2705,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): CGThing which is already properly indented. """ def __init__(self, descriptor, name, args, unwrapFailureCode=None): - CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) + CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args) if unwrapFailureCode is None: self.unwrapFailureCode = ( @@ -2568,14 +2722,20 @@ class CGAbstractBindingMethod(CGAbstractExternMethod): # consumption by FailureFatalCastableObjectUnwrapper. unwrapThis = str(CastableObjectUnwrapper( FakeCastableDescriptor(self.descriptor), - "obj", self.unwrapFailureCode)) + "obj.handle()", self.unwrapFailureCode, "object")) unwrapThis = CGGeneric( - "let obj: *mut JSObject = JS_THIS_OBJECT(cx, vp as *mut JSVal);\n" - "if obj.is_null() {\n" - " return false as JSBool;\n" + "let args = CallArgs::from_vp(vp, argc);\n" + "let thisobj = args.thisv();\n" + "if !thisobj.get().is_null_or_undefined() && !thisobj.get().is_object() {\n" + " return JSFalse;\n" "}\n" + "let obj = if thisobj.get().is_object() {\n" + " RootedObject::new(cx, thisobj.get().to_object())\n" + "} else {\n" + " RootedObject::new(cx, GetGlobalForObjectCrossCompartment(JS_CALLEE(cx, vp).to_object_or_null()))\n" + "};\n" "\n" - "let this: Unrooted<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis)) + "let this: Root<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis)) return CGList([ unwrapThis, self.generate_code() ], "\n") def generate_code(self): @@ -2596,12 +2756,11 @@ class CGAbstractStaticBindingMethod(CGAbstractMethod): Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp'), ] - CGAbstractMethod.__init__(self, descriptor, name, "JSBool", args, extern=True) + CGAbstractMethod.__init__(self, descriptor, name, "u8", args, extern=True) def definition_body(self): preamble = CGGeneric("""\ let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object()); -let global = global.root(); """) return CGList([preamble, self.generate_code()]) @@ -2621,7 +2780,7 @@ class CGGenericMethod(CGAbstractBindingMethod): def generate_code(self): return CGGeneric( "let _info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" - "return CallJitMethodOp(_info, cx, obj, this.unsafe_get() as *mut libc::c_void, argc, vp);") + "return CallJitMethodOp(_info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp);") class CGSpecializedMethod(CGAbstractExternMethod): """ @@ -2631,18 +2790,19 @@ class CGSpecializedMethod(CGAbstractExternMethod): def __init__(self, descriptor, method): self.method = method name = method.identifier.name - args = [Argument('*mut JSContext', 'cx'), Argument('JSHandleObject', '_obj'), + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_obj'), Argument('*const %s' % descriptor.concreteType, 'this'), - Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')] - CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args) + Argument('*const JSJitMethodCallArgs', 'args')] + CGAbstractExternMethod.__init__(self, descriptor, name, 'u8', args) def definition_body(self): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, self.method) return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(), self.descriptor, self.method), - pre="let this = Unrooted::from_raw(this);\n" - "let this = this.root();\n") + pre="let this = &*this;\n" + "let args = &*args;\n" + "let argc = args.argc_;\n") @staticmethod def makeNativeName(descriptor, method): @@ -2661,14 +2821,16 @@ class CGStaticMethod(CGAbstractStaticBindingMethod): def generate_code(self): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, self.method) - return CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method) + setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n") + call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method) + return CGList([setupArgs, call]) class CGGenericGetter(CGAbstractBindingMethod): """ A class for generating the C++ code for an IDL attribute getter. """ def __init__(self, descriptor, lenientThis=False): - args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', '_argc'), + args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')] if lenientThis: name = "genericLenientGetter" @@ -2685,7 +2847,7 @@ class CGGenericGetter(CGAbstractBindingMethod): def generate_code(self): return CGGeneric( "let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" - "return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, vp);") + "return CallJitGetterOp(info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp);") class CGSpecializedGetter(CGAbstractExternMethod): """ @@ -2696,10 +2858,10 @@ class CGSpecializedGetter(CGAbstractExternMethod): self.attr = attr name = 'get_' + attr.identifier.name args = [ Argument('*mut JSContext', 'cx'), - Argument('JSHandleObject', '_obj'), + Argument('HandleObject', '_obj'), Argument('*const %s' % descriptor.concreteType, 'this'), - Argument('*mut JSVal', 'vp') ] - CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) + Argument('JSJitGetterCallArgs', 'args') ] + CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args) def definition_body(self): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, @@ -2707,8 +2869,7 @@ class CGSpecializedGetter(CGAbstractExternMethod): return CGWrapper(CGGetterCall([], self.attr.type, nativeName, self.descriptor, self.attr), - pre="let this = Unrooted::from_raw(this);\n" - "let this = this.root();\n") + pre="let this = &*this;\n") @staticmethod def makeNativeName(descriptor, attr): @@ -2734,8 +2895,10 @@ class CGStaticGetter(CGAbstractStaticBindingMethod): def generate_code(self): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, self.attr) - return CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor, + setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n") + call = CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor, self.attr) + return CGList([setupArgs, call]) class CGGenericSetter(CGAbstractBindingMethod): @@ -2758,10 +2921,8 @@ class CGGenericSetter(CGAbstractBindingMethod): def generate_code(self): return CGGeneric( - "let mut undef = UndefinedValue();\n" - "let argv: *mut JSVal = if argc != 0 { JS_ARGV(cx, vp) } else { &mut undef as *mut JSVal };\n" "let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n" - "if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, argv) == 0 {\n" + "if CallJitSetterOp(info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp) == 0 {\n" " return 0;\n" "}\n" "*vp = UndefinedValue();\n" @@ -2776,18 +2937,17 @@ class CGSpecializedSetter(CGAbstractExternMethod): self.attr = attr name = 'set_' + attr.identifier.name args = [ Argument('*mut JSContext', 'cx'), - Argument('JSHandleObject', 'obj'), + Argument('HandleObject', 'obj'), Argument('*const %s' % descriptor.concreteType, 'this'), - Argument('*mut JSVal', 'argv')] - CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args) + Argument('JSJitSetterCallArgs', 'args')] + CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args) def definition_body(self): nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, self.attr) return CGWrapper(CGSetterCall([], self.attr.type, nativeName, self.descriptor, self.attr), - pre="let this = Unrooted::from_raw(this);\n" - "let this = this.root();\n") + pre="let this = &*this;\n") @staticmethod def makeNativeName(descriptor, attr): @@ -2808,7 +2968,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod): nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, self.attr) checkForArg = CGGeneric( - "let argv = JS_ARGV(cx, vp);\n" + "let args = CallArgs::from_vp(vp, argc);\n" "if (argc == 0) {\n" " throw_type_error(cx, \"Not enough arguments to %s setter.\");\n" " return 0;\n" @@ -2831,17 +2991,17 @@ class CGSpecializedForwardingSetter(CGSpecializedSetter): assert all(ord(c) < 128 for c in attrName) assert all(ord(c) < 128 for c in forwardToAttrName) return CGGeneric("""\ -let mut v = UndefinedValue(); -if JS_GetProperty(cx, *obj.unnamed_field1, b"%s".as_ptr() as *const i8, &mut v) == 0 { - return 0; +let mut v = RootedValue::new(cx, UndefinedValue()); +if JS_GetProperty(cx, obj, %s as *const u8 as *const i8, v.handle_mut()) == 0 { + return JSFalse; } -if !v.is_object() { +if !v.ptr.is_object() { throw_type_error(cx, "Value.%s is not an object."); - return 0; + return JSFalse; } -let target_obj = v.to_object(); -JS_SetProperty(cx, target_obj, b"%s".as_ptr() as *const i8, argv.offset(0)) -""" % (attrName, attrName, forwardToAttrName)) +let target_obj = RootedObject::new(cx, v.ptr.to_object()); +JS_SetProperty(cx, target_obj.handle(), %s as *const u8 as *const i8, args.get(0)) +""" % (str_to_const_array(attrName), attrName, str_to_const_array(forwardToAttrName))) class CGMemberJITInfo(CGThing): """ @@ -2852,52 +3012,253 @@ class CGMemberJITInfo(CGThing): self.member = member self.descriptor = descriptor - def defineJitInfo(self, infoName, opName, infallible): - protoID = "PrototypeList::ID::%s as u32" % self.descriptor.name - depth = self.descriptor.interface.inheritanceDepth() - failstr = "true" if infallible else "false" - return ("const %s: JSJitInfo = JSJitInfo {\n" - " op: %s as *const u8,\n" - " protoID: %s,\n" - " depth: %s,\n" - " isInfallible: %s, /* False in setters. */\n" - " isConstant: false /* Only relevant for getters. */\n" - "};\n" % (infoName, opName, protoID, depth, failstr)) + def defineJitInfo(self, infoName, opName, opType, infallible, movable, + aliasSet, alwaysInSlot, lazilyInSlot, slotIndex, + returnTypes, args): + """ + aliasSet is a JSJitInfo::AliasSet value, without the "JSJitInfo::" bit. + + args is None if we don't want to output argTypes for some + reason (e.g. we have overloads or we're not a method) and + otherwise an iterable of the arguments for this method. + """ + assert(not movable or aliasSet != "AliasEverything") # Can't move write-aliasing things + assert(not alwaysInSlot or movable) # Things always in slots had better be movable + + def jitInfoInitializer(isTypedMethod): + initializer = fill( + """ + JSJitInfo { + _bindgen_data_1_: ${opName} as *const ::libc::c_void, + protoID: PrototypeList::ID::${name} as u16, + depth: ${depth}, + _bitfield_1: ((JSJitInfo_OpType::${opType} as u32) << 0) | + ((JSJitInfo_AliasSet::${aliasSet} as u32) << 4) | + ((JSValueType::${returnType} as u32) << 8) | + ((${isInfallible} as u32) << 16) | + ((${isMovable} as u32) << 17) | + ((${isAlwaysInSlot} as u32) << 18) | + ((${isLazilyCachedInSlot} as u32) << 19) | + ((${isTypedMethod} as u32) << 20) | + ((${slotIndex} as u32) << 21) + } + """, + opName=opName, + name=self.descriptor.name, + depth=self.descriptor.interface.inheritanceDepth(), + opType=opType, + aliasSet=aliasSet, + returnType=reduce(CGMemberJITInfo.getSingleReturnType, returnTypes, + ""), + isInfallible=toStringBool(infallible), + isMovable=toStringBool(movable), + isAlwaysInSlot=toStringBool(alwaysInSlot), + isLazilyCachedInSlot=toStringBool(lazilyInSlot), + isTypedMethod=toStringBool(isTypedMethod), + slotIndex=slotIndex) + return initializer.rstrip() + + return ("\n" + "const %s: JSJitInfo = %s;\n" + % (infoName, jitInfoInitializer(False))) def define(self): if self.member.isAttr(): getterinfo = ("%s_getterinfo" % self.member.identifier.name) getter = ("get_%s" % self.member.identifier.name) getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True) - result = self.defineJitInfo(getterinfo, getter, getterinfal) - if not self.member.readonly or self.member.getExtendedAttribute("PutForwards"): + + movable = self.mayBeMovable() and getterinfal + aliasSet = self.aliasSet() + + isAlwaysInSlot = self.member.getExtendedAttribute("StoreInSlot") + if self.member.slotIndex is not None: + assert isAlwaysInSlot or self.member.getExtendedAttribute("Cached") + isLazilyCachedInSlot = not isAlwaysInSlot + slotIndex = memberReservedSlot(self.member) + # We'll statically assert that this is not too big in + # CGUpdateMemberSlotsMethod, in the case when + # isAlwaysInSlot is true. + else: + isLazilyCachedInSlot = False + slotIndex = "0" + + result = self.defineJitInfo(getterinfo, getter, "Getter", + getterinfal, movable, aliasSet, + isAlwaysInSlot, isLazilyCachedInSlot, + slotIndex, + [self.member.type], None) + if (not self.member.readonly or + self.member.getExtendedAttribute("PutForwards")): setterinfo = ("%s_setterinfo" % self.member.identifier.name) setter = ("set_%s" % self.member.identifier.name) # Setters are always fallible, since they have to do a typed unwrap. - result += "\n" + self.defineJitInfo(setterinfo, setter, False) + result += self.defineJitInfo(setterinfo, setter, "Setter", + False, False, "AliasEverything", + False, False, "0", + [BuiltinTypes[IDLBuiltinType.Types.void]], + None) return result if self.member.isMethod(): methodinfo = ("%s_methodinfo" % self.member.identifier.name) - # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition. method = ("%s" % self.member.identifier.name) # Methods are infallible if they are infallible, have no arguments # to unwrap, and have a return type that's infallible to wrap up for # return. - methodInfal = False sigs = self.member.signatures() - if len(sigs) == 1: + if len(sigs) != 1: # Don't handle overloading. If there's more than one signature, # one of them must take arguments. + methodInfal = False + args = None + movable = False + else: sig = sigs[0] - if len(sig[1]) == 0: - # No arguments and infallible return boxing - methodInfal = True + # For methods that affect nothing, it's OK to set movable to our + # notion of infallible on the C++ side, without considering + # argument conversions, since argument conversions that can + # reliably throw would be effectful anyway and the jit doesn't + # move effectful things. + hasInfallibleImpl = "infallible" in self.descriptor.getExtendedAttributes(self.member) + movable = self.mayBeMovable() and hasInfallibleImpl + # XXXbz can we move the smarts about fallibility due to arg + # conversions into the JIT, using our new args stuff? + if (len(sig[1]) != 0): + # We have arguments or our return-value boxing can fail + methodInfal = False + else: + methodInfal = hasInfallibleImpl + # For now, only bother to output args if we're side-effect-free. + if self.member.affects == "Nothing": + args = sig[1] + else: + args = None - result = self.defineJitInfo(methodinfo, method, methodInfal) + aliasSet = self.aliasSet() + result = self.defineJitInfo(methodinfo, method, "Method", + methodInfal, movable, aliasSet, + False, False, "0", + [s[0] for s in sigs], args) return result raise TypeError("Illegal member type to CGPropertyJITInfo") + def mayBeMovable(self): + """ + Returns whether this attribute or method may be movable, just + based on Affects/DependsOn annotations. + """ + affects = self.member.affects + dependsOn = self.member.dependsOn + assert affects in IDLInterfaceMember.AffectsValues + assert dependsOn in IDLInterfaceMember.DependsOnValues + # Things that are DependsOn=DeviceState are not movable, because we + # don't want them coalesced with each other or loop-hoisted, since + # their return value can change even if nothing is going on from our + # point of view. + return (affects == "Nothing" and + (dependsOn != "Everything" and dependsOn != "DeviceState")) + + def aliasSet(self): + """Returns the alias set to store in the jitinfo. This may not be the + effective alias set the JIT uses, depending on whether we have enough + information about our args to allow the JIT to prove that effectful + argument conversions won't happen. + + """ + dependsOn = self.member.dependsOn + assert dependsOn in IDLInterfaceMember.DependsOnValues + + if dependsOn == "Nothing" or dependsOn == "DeviceState": + assert self.member.affects == "Nothing" + return "AliasNone" + + if dependsOn == "DOMState": + assert self.member.affects == "Nothing" + return "AliasDOMSets" + + return "AliasEverything" + + @staticmethod + def getJSReturnTypeTag(t): + if t.nullable(): + # Sometimes it might return null, sometimes not + return "JSVAL_TYPE_UNKNOWN" + if t.isVoid(): + # No return, every time + return "JSVAL_TYPE_UNDEFINED" + if t.isArray(): + # No idea yet + assert False + if t.isSequence(): + return "JSVAL_TYPE_OBJECT" + if t.isMozMap(): + return "JSVAL_TYPE_OBJECT" + if t.isGeckoInterface(): + return "JSVAL_TYPE_OBJECT" + if t.isString(): + return "JSVAL_TYPE_STRING" + if t.isEnum(): + return "JSVAL_TYPE_STRING" + if t.isCallback(): + return "JSVAL_TYPE_OBJECT" + if t.isAny(): + # The whole point is to return various stuff + return "JSVAL_TYPE_UNKNOWN" + if t.isObject(): + return "JSVAL_TYPE_OBJECT" + if t.isSpiderMonkeyInterface(): + return "JSVAL_TYPE_OBJECT" + if t.isUnion(): + u = t.unroll() + if u.hasNullableType: + # Might be null or not + return "JSVAL_TYPE_UNKNOWN" + return reduce(CGMemberJITInfo.getSingleReturnType, + u.flatMemberTypes, "") + if t.isDictionary(): + return "JSVAL_TYPE_OBJECT" + if t.isDate(): + return "JSVAL_TYPE_OBJECT" + if not t.isPrimitive(): + raise TypeError("No idea what type " + str(t) + " is.") + tag = t.tag() + if tag == IDLType.Tags.bool: + return "JSVAL_TYPE_BOOLEAN" + if tag in [IDLType.Tags.int8, IDLType.Tags.uint8, + IDLType.Tags.int16, IDLType.Tags.uint16, + IDLType.Tags.int32]: + return "JSVAL_TYPE_INT32" + if tag in [IDLType.Tags.int64, IDLType.Tags.uint64, + IDLType.Tags.unrestricted_float, IDLType.Tags.float, + IDLType.Tags.unrestricted_double, IDLType.Tags.double]: + # These all use JS_NumberValue, which can return int or double. + # But TI treats "double" as meaning "int or double", so we're + # good to return JSVAL_TYPE_DOUBLE here. + return "JSVAL_TYPE_DOUBLE" + if tag != IDLType.Tags.uint32: + raise TypeError("No idea what type " + str(t) + " is.") + # uint32 is sometimes int and sometimes double. + return "JSVAL_TYPE_DOUBLE" + + @staticmethod + def getSingleReturnType(existingType, t): + type = CGMemberJITInfo.getJSReturnTypeTag(t) + if existingType == "": + # First element of the list; just return its type + return type + + if type == existingType: + return existingType + if ((type == "JSVAL_TYPE_DOUBLE" and + existingType == "JSVAL_TYPE_INT32") or + (existingType == "JSVAL_TYPE_DOUBLE" and + type == "JSVAL_TYPE_INT32")): + # Promote INT32 to DOUBLE as needed + return "JSVAL_TYPE_DOUBLE" + # Different types + return "JSVAL_TYPE_UNKNOWN" + def getEnumValueName(value): # Some enum values can be empty strings. Others might have weird # characters in them. Deal with the former by returning "_empty", @@ -2933,7 +3294,7 @@ pub enum %s { inner = """\ use dom::bindings::conversions::ToJSValConvertible; -use js::jsapi::JSContext; +use js::jsapi::{JSContext, MutableHandleValue}; use js::jsval::JSVal; pub const strings: &'static [&'static str] = &[ @@ -2941,8 +3302,8 @@ pub const strings: &'static [&'static str] = &[ ]; impl ToJSValConvertible for super::%s { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - strings[*self as usize].to_jsval(cx) + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + strings[*self as usize].to_jsval(cx, rval); } } """ % (",\n ".join(['"%s"' % val for val in enum.values()]), enum.identifier.name) @@ -3047,7 +3408,7 @@ class CGUnionStruct(CGThing): " e%s(%s)," % (v["name"], v["typeName"]) for v in templateVars ] enumConversions = [ - " %s::e%s(ref inner) => inner.to_jsval(cx)," % (self.type, v["name"]) for v in templateVars + " %s::e%s(ref inner) => inner.to_jsval(cx, rval)," % (self.type, v["name"]) for v in templateVars ] # XXXManishearth The following should be #[must_root], # however we currently allow it till #2661 is fixed @@ -3058,7 +3419,7 @@ pub enum %s { } impl ToJSValConvertible for %s { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { match *self { %s } @@ -3147,7 +3508,7 @@ class CGUnionConversionStruct(CGThing): if hasObjectTypes: assert interfaceObject templateBody = CGList([interfaceObject], "\n") - conversions.append(CGIfWrapper(templateBody, "value.is_object()")) + conversions.append(CGIfWrapper(templateBody, "value.get().is_object()")) otherMemberTypes = [ t for t in memberTypes if t.isPrimitive() or t.isString() or t.isEnum() @@ -3173,7 +3534,7 @@ class CGUnionConversionStruct(CGThing): "Err(())" % ", ".join(names))) method = CGWrapper( CGIndenter(CGList(conversions, "\n\n")), - pre="fn from_jsval(cx: *mut JSContext, value: JSVal, _option: ()) -> Result<%s, ()> {\n" % self.type, + pre="fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<%s, ()> {\n" % self.type, post="\n}") return CGWrapper( CGIndenter(CGList([ @@ -3190,7 +3551,7 @@ class CGUnionConversionStruct(CGThing): return CGWrapper( CGIndenter(jsConversion, 4), - pre="fn TryConvertTo%s(cx: *mut JSContext, value: JSVal) -> %s {\n" % (t.name, returnType), + pre="fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" % (t.name, returnType), post="\n}") def define(self): @@ -3236,6 +3597,7 @@ class ClassMethod(ClassItem): override indicates whether to flag the method as MOZ_OVERRIDE """ assert not override or virtual + assert not (override and static) self.returnType = returnType self.args = args self.inline = False @@ -3378,9 +3740,14 @@ class ClassConstructor(ClassItem): def getBody(self, cgClass): initializers = [" parent: %s" % str(self.baseConstructors[0])] return (self.body + ( - "%s {\n" + "let mut ret = Rc::new(%s {\n" "%s\n" - "}") % (cgClass.name, '\n'.join(initializers))) + "});\n" + "match rc::get_mut(&mut ret) {\n" + " Some(ref mut callback) => callback.parent.init(%s),\n" + " None => unreachable!(),\n" + "};\n" + "ret") % (cgClass.name, '\n'.join(initializers), self.args[0].name)) def declare(self, cgClass): args = ', '.join([a.declare() for a in self.args]) @@ -3391,7 +3758,7 @@ class ClassConstructor(ClassItem): body = ' {\n' + body + '}' return string.Template("""\ -pub fn ${decorators}new(${args}) -> ${className}${body} +pub fn ${decorators}new(${args}) -> Rc<${className}>${body} """).substitute({ 'decorators': self.getDecorators(True), 'className': cgClass.getNameString(), 'args': args, @@ -3692,17 +4059,18 @@ class CGProxySpecialOperation(CGPerSignatureCall): argument = arguments[1] info = getJSToNativeConversionInfo( argument.type, descriptor, treatNullAs=argument.treatNullAs, - exceptionCode="return false;") + exceptionCode="return JSFalse;") template = info.template declType = info.declType needsRooting = info.needsRooting templateValues = { - "val": "(*desc).value", + "val": "value.handle()", } self.cgRoot.prepend(instantiateJSToNativeConversionTemplate( template, templateValues, declType, argument.identifier.name, needsRooting)) + self.cgRoot.prepend(CGGeneric("let value = RootedValue::new(cx, desc.get().value);")) elif operation.isGetter(): self.cgRoot.prepend(CGGeneric("let mut found = false;")) @@ -3777,7 +4145,7 @@ class CGProxyNamedDeleter(CGProxySpecialOperation): class CGProxyUnwrap(CGAbstractMethod): def __init__(self, descriptor): - args = [Argument('*mut JSObject', 'obj')] + args = [Argument('HandleObject', 'obj')] CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*const ' + descriptor.concreteType, args, alwaysInline=True) def definition_body(self): @@ -3786,103 +4154,78 @@ class CGProxyUnwrap(CGAbstractMethod): obj = js::UnwrapObject(obj); }*/ //MOZ_ASSERT(IsProxy(obj)); -let box_ = GetProxyPrivate(obj).to_private() as *const %s; +let box_ = GetProxyPrivate(*obj.ptr).to_private() as *const %s; return box_;""" % self.descriptor.concreteType) class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'), - Argument('jsid', 'id'), Argument('bool', 'set'), - Argument('*mut JSPropertyDescriptor', 'desc')] + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), + Argument('HandleId', 'id'), + Argument('MutableHandle<JSPropertyDescriptor>', 'desc')] CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor", - "bool", args) + "u8", args) self.descriptor = descriptor def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] indexedSetter = self.descriptor.operations['IndexedSetter'] - setOrIndexedGet = "" + get = "" if indexedGetter or indexedSetter: - setOrIndexedGet += "let index = get_array_index_from_id(cx, id);\n" + get = "let index = get_array_index_from_id(cx, id);\n" if indexedGetter: readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None) - fillDescriptor = "fill_property_descriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly - templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor} - get = ("if index.is_some() {\n" + - " let index = index.unwrap();\n" + - " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + - CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" + - "}\n") - - if indexedSetter or self.descriptor.operations['NamedSetter']: - setOrIndexedGet += "if set {\n" - if indexedSetter: - setOrIndexedGet += (" if index.is_some() {\n" + - " let index = index.unwrap();\n") - if not 'IndexedCreator' in self.descriptor.operations: - # FIXME need to check that this is a 'supported property index' - assert False - setOrIndexedGet += (" fill_property_descriptor(&mut *desc, proxy, false);\n" + - " return true;\n" + - " }\n") - if self.descriptor.operations['NamedSetter']: - setOrIndexedGet += " if RUST_JSID_IS_STRING(id) != 0 {\n" - if not 'NamedCreator' in self.descriptor.operations: - # FIXME need to check that this is a 'supported property name' - assert False - setOrIndexedGet += (" fill_property_descriptor(&mut *desc, proxy, false);\n" + - " return true;\n" + - " }\n") - setOrIndexedGet += "}" - if indexedGetter: - setOrIndexedGet += (" else {\n" + - CGIndenter(CGGeneric(get)).define() + - "}") - setOrIndexedGet += "\n\n" - elif indexedGetter: - setOrIndexedGet += ("if !set {\n" + - CGIndenter(CGGeneric(get)).define() + - "}\n\n") + fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly + templateValues = { + 'jsvalRef': 'result_root.handle_mut()', + 'successCode': fillDescriptor, + 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());' + } + get += ("if index.is_some() {\n" + + " let index = index.unwrap();\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = &*this;\n" + + CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" + + "}\n") namedGetter = self.descriptor.operations['NamedGetter'] if namedGetter: readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None) - fillDescriptor = "fill_property_descriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly - templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor} + fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly + templateValues = { + 'jsvalRef': 'result_root.handle_mut()', + 'successCode': fillDescriptor, + 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());' + } # Once we start supporting OverrideBuiltins we need to make # ResolveOwnProperty or EnumerateOwnProperties filter out named # properties that shadow prototype properties. namedGet = ("\n" + - "if !set && RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" + + "if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" + " let name = jsid_to_str(cx, id);\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" + "}\n") else: namedGet = "" - return setOrIndexedGet + """\ -let expando: *mut JSObject = get_expando_object(proxy); + return get + """\ +let expando = RootedObject::new(cx, get_expando_object(proxy)); //if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) { -if !expando.is_null() { - let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED; - if JS_GetPropertyDescriptorById(cx, expando, id, flags, desc) == 0 { - return false; +if !expando.ptr.is_null() { + if JS_GetPropertyDescriptorById(cx, expando.handle(), id, desc) == 0 { + return JSFalse; } - if !(*desc).obj.is_null() { + if !desc.get().obj.is_null() { // Pretend the property lives on the wrapper. - (*desc).obj = proxy; - return true; + desc.get().obj = *proxy.ptr; + return JSTrue; } } """ + namedGet + """\ -(*desc).obj = ptr::null_mut(); -return true;""" +desc.get().obj = ptr::null_mut(); +return JSTrue;""" def definition_body(self): return CGGeneric(self.getBody()) @@ -3890,10 +4233,11 @@ return true;""" # TODO(Issue 5876) class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'), - Argument('jsid', 'id'), - Argument('*mut JSPropertyDescriptor', 'desc')] - CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "bool", args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), + Argument('HandleId', 'id'), + Argument('Handle<JSPropertyDescriptor>', 'desc'), + Argument('*mut ObjectOpResult', 'opresult')] + CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "u8", args) self.descriptor = descriptor def getBody(self): set = "" @@ -3906,14 +4250,13 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): "if index.is_some() {\n" + " let index = index.unwrap();\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() + - " return true;\n" + + " return JSTrue;\n" + "}\n") elif self.descriptor.operations['IndexedGetter']: set += ("if get_array_index_from_id(cx, id).is_some() {\n" + - " return false;\n" + + " return JSFalse;\n" + " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" + "}\n") % self.descriptor.name @@ -3924,30 +4267,30 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" + " let name = jsid_to_str(cx, id);\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + - " return true;\n" + + " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" + + " return JSTrue;\n" + "} else {\n" + - " return false;\n" + + " return JSFalse;\n" + "}\n") else: - if self.descriptor.operations['NamedGetter']: - set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" + - " let name = jsid_to_str(cx, id);\n" + - " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + - CGProxyNamedPresenceChecker(self.descriptor).define() + - " if (found) {\n" + - # TODO(Issue 5876) - " //return js::IsInNonStrictPropertySet(cx)\n" + - " // ? opresult.succeed()\n" + - " // : ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"${name}\");\n" + - " return true;\n" + - " }\n" + - "}" - ) % (self.descriptor.name, self.descriptor.name) + set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" + + " let name = jsid_to_str(cx, id);\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = &*this;\n" + + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + + " if (found) {\n" + # TODO(Issue 5876) + " //return js::IsInNonStrictPropertySet(cx)\n" + + " // ? opresult.succeed()\n" + + " // : ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"${name}\");\n" + + " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" + + " return JSTrue;\n" + + " }\n" + + " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" + + " return JSTrue;\n" + "}\n") % (self.descriptor.name, self.descriptor.name) set += "return proxyhandler::define_property(%s);" % ", ".join(a.name for a in self.args) return set @@ -3956,10 +4299,10 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'), - Argument('jsid', 'id'), - Argument('*mut bool', 'bp')] - CGAbstractExternMethod.__init__(self, descriptor, "delete", "bool", args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), + Argument('HandleId', 'id'), + Argument('*mut ObjectOpResult', 'res')] + CGAbstractExternMethod.__init__(self, descriptor, "delete", "u8", args) self.descriptor = descriptor def getBody(self): @@ -3967,10 +4310,9 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): if self.descriptor.operations['NamedDeleter']: set += ("let name = jsid_to_str(cx, id);\n" + "let this = UnwrapProxy(proxy);\n" + - "let this = Unrooted::from_raw(this);\n" + - "let this = this.root();\n" + + "let this = &*this;\n" + "%s") % (CGProxyNamedDeleter(self.descriptor).define()) - set += "return proxyhandler::delete(%s);" % ", ".join(a.name for a in self.args) + set += "return proxyhandler::delete(%s) as u8;" % ", ".join(a.name for a in self.args) return set def definition_body(self): @@ -3978,9 +4320,9 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'), - Argument('jsid', 'id'), Argument('*mut bool', 'bp')] - CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "bool", args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), + Argument('HandleId', 'id'), Argument('*mut u8', 'bp')] + CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "u8", args) self.descriptor = descriptor def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] @@ -3989,11 +4331,10 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): "if index.is_some() {\n" + " let index = index.unwrap();\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" + - " *bp = found;\n" + - " return true;\n" + + " *bp = found as u8;\n" + + " return JSTrue;\n" + "}\n\n") else: indexed = "" @@ -4003,57 +4344,56 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): named = ("if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" + " let name = jsid_to_str(cx, id);\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" + - " *bp = found;\n" - " return true;\n" + " *bp = found as u8;\n" + " return JSTrue;\n" "}\n" + "\n") else: named = "" return indexed + """\ -let expando: *mut JSObject = get_expando_object(proxy); -if !expando.is_null() { - let mut b: JSBool = 1; - let ok = JS_HasPropertyById(cx, expando, id, &mut b) != 0; - *bp = b != 0; - if !ok || *bp { - return ok; +let expando = RootedObject::new(cx, get_expando_object(proxy)); +if !expando.ptr.is_null() { + let mut b: u8 = 1; + let ok = JS_HasPropertyById(cx, expando.handle(), id, &mut b) != 0; + *bp = (b != 0) as u8; + if !ok || *bp != 0 { + return ok as u8; } } """ + named + """\ -*bp = false; -return true;""" +*bp = JSFalse; +return JSTrue;""" def definition_body(self): return CGGeneric(self.getBody()) class CGDOMJSProxyHandler_get(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'), - Argument('*mut JSObject', '_receiver'), Argument('jsid', 'id'), - Argument('*mut JSVal', 'vp')] - CGAbstractExternMethod.__init__(self, descriptor, "get", "bool", args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'), + Argument('HandleObject', '_receiver'), Argument('HandleId', 'id'), + Argument('MutableHandleValue', 'vp')] + CGAbstractExternMethod.__init__(self, descriptor, "get", "u8", args) self.descriptor = descriptor def getBody(self): getFromExpando = """\ -let expando = get_expando_object(proxy); -if !expando.is_null() { +let expando = RootedObject::new(cx, get_expando_object(proxy)); +if !expando.ptr.is_null() { let mut hasProp = 0; - if JS_HasPropertyById(cx, expando, id, &mut hasProp) == 0 { - return false; + if JS_HasPropertyById(cx, expando.handle(), id, &mut hasProp) == 0 { + return JSFalse; } if hasProp != 0 { - return JS_GetPropertyById(cx, expando, id, vp) != 0; + return (JS_GetPropertyById(cx, expando.handle(), id, vp) != 0) as u8; } }""" templateValues = { - 'jsvalRef': '*vp', - 'successCode': 'return true;', + 'jsvalRef': 'vp', + 'successCode': 'return JSTrue;', } indexedGetter = self.descriptor.operations['IndexedGetter'] @@ -4062,8 +4402,7 @@ if !expando.is_null() { "if index.is_some() {\n" + " let index = index.unwrap();\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define()) getIndexedOrExpando += """\ // Even if we don't have this index, we don't forward the @@ -4080,8 +4419,7 @@ if !expando.is_null() { getNamed = ("if (RUST_JSID_IS_STRING(id) != 0) {\n" + " let name = jsid_to_str(cx, id);\n" + " let this = UnwrapProxy(proxy);\n" + - " let this = Unrooted::from_raw(this);\n" + - " let this = this.root();\n" + + " let this = &*this;\n" + CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "}\n") else: @@ -4094,26 +4432,26 @@ if !expando.is_null() { %s let mut found = false; if !get_property_on_prototype(cx, proxy, id, &mut found, vp) { - return false; + return JSFalse; } if found { - return true; + return JSTrue; } %s -*vp = UndefinedValue(); -return true;""" % (getIndexedOrExpando, getNamed) +*vp.ptr = UndefinedValue(); +return JSTrue;""" % (getIndexedOrExpando, getNamed) def definition_body(self): return CGGeneric(self.getBody()) -class CGDOMJSProxyHandler_obj_toString(CGAbstractExternMethod): +class CGDOMJSProxyHandler_className(CGAbstractExternMethod): def __init__(self, descriptor): - args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', '_proxy')] - CGAbstractExternMethod.__init__(self, descriptor, "obj_toString", "*mut JSString", args) + args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_proxy')] + CGAbstractExternMethod.__init__(self, descriptor, "className", "*const i8", args) self.descriptor = descriptor def getBody(self): - return """proxyhandler::object_to_string(cx, "%s")""" % self.descriptor.name + return '%s as *const u8 as *const i8' % str_to_const_array(self.descriptor.name) def definition_body(self): return CGGeneric(self.getBody()) @@ -4165,7 +4503,8 @@ class CGClassTraceHook(CGAbstractClassHook): self.traceGlobal = descriptor.isGlobal() def generate_code(self): - body = [CGGeneric("(*this).trace(%s);" % self.args[0].name)] + body = [CGGeneric("if this.is_null() { return; } // GC during obj creation\n" + "(*this).trace(%s);" % self.args[0].name)] if self.traceGlobal: body += [CGGeneric("trace_global(trc, obj);")] return CGList(body, "\n") @@ -4177,7 +4516,7 @@ class CGClassConstructHook(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')] CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME, - 'JSBool', args) + 'u8', args) self._ctor = self.descriptor.interface.ctor() def define(self): @@ -4188,7 +4527,7 @@ class CGClassConstructHook(CGAbstractExternMethod): def definition_body(self): preamble = CGGeneric("""\ let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object()); -let global = global.root(); +let args = CallArgs::from_vp(vp, argc); """) name = self._ctor.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNameFor(name)) @@ -4201,7 +4540,7 @@ class CGClassFinalizeHook(CGAbstractClassHook): A hook for finalize, used to release our native object. """ def __init__(self, descriptor): - args = [Argument('*mut JSFreeOp', '_fop'), Argument('*mut JSObject', 'obj')] + args = [Argument('*mut FreeOp', '_fop'), Argument('*mut JSObject', 'obj')] CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME, 'void', args) @@ -4391,7 +4730,7 @@ class CGDescriptor(CGThing): cgThings.append(CGProxyUnwrap(descriptor)) cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor)) cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)) - cgThings.append(CGDOMJSProxyHandler_obj_toString(descriptor)) + cgThings.append(CGDOMJSProxyHandler_className(descriptor)) cgThings.append(CGDOMJSProxyHandler_get(descriptor)) cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor)) @@ -4427,7 +4766,7 @@ class CGDescriptor(CGThing): return self.cgRoot.define() class CGNonNamespacedEnum(CGThing): - def __init__(self, enumName, names, values, comment="", deriving=""): + def __init__(self, enumName, names, values, comment="", deriving="", repr=""): if not values: values = [] @@ -4449,6 +4788,8 @@ class CGNonNamespacedEnum(CGThing): # Build the enum body. enumstr = comment + 'pub enum %s {\n%s\n}\n' % (enumName, ',\n'.join(entries)) + if repr: + enumstr = ('#[repr(%s)]\n' % repr) + enumstr if deriving: enumstr = ('#[derive(%s)]\n' % deriving) + enumstr curr = CGGeneric(enumstr) @@ -4523,13 +4864,13 @@ class CGDictionary(CGThing): def memberInit(memberInfo): member, _ = memberInfo name = self.makeMemberName(member.identifier.name) - conversion = self.getMemberConversion(memberInfo) + conversion = self.getMemberConversion(memberInfo, member.type) return CGGeneric("%s: %s,\n" % (name, conversion.define())) def memberInsert(memberInfo): member, _ = memberInfo name = self.makeMemberName(member.identifier.name) - insertion = ("set_dictionary_property(cx, obj, \"%s\", &mut self.%s.to_jsval(cx)).unwrap();" % (name, name)) + insertion = ("let mut %s = RootedValue::new(cx, UndefinedValue());\nself.%s.to_jsval(cx, %s.handle_mut());\nset_dictionary_property(cx, obj.handle(), \"%s\", %s.handle()).unwrap();" % (name, name, name, name, name)) return CGGeneric("%s\n" % insertion) memberInits = CGList([memberInit(m) for m in self.memberInfo]) @@ -4537,14 +4878,14 @@ class CGDictionary(CGThing): return string.Template( "impl ${selfName} {\n" - " pub fn empty() -> ${selfName} {\n" - " ${selfName}::new(ptr::null_mut(), NullValue()).unwrap()\n" + " pub fn empty(cx: *mut JSContext) -> ${selfName} {\n" + " ${selfName}::new(cx, HandleValue::null()).unwrap()\n" " }\n" - " pub fn new(cx: *mut JSContext, val: JSVal) -> Result<${selfName}, ()> {\n" - " let object = if val.is_null_or_undefined() {\n" - " ptr::null_mut()\n" - " } else if val.is_object() {\n" - " val.to_object()\n" + " pub fn new(cx: *mut JSContext, val: HandleValue) -> Result<${selfName}, ()> {\n" + " let object = if val.get().is_null_or_undefined() {\n" + " RootedObject::new(cx, ptr::null_mut())\n" + " } else if val.get().is_object() {\n" + " RootedObject::new(cx, val.get().to_object())\n" " } else {\n" " throw_type_error(cx, \"Value not an object.\");\n" " return Err(());\n" @@ -4557,10 +4898,10 @@ class CGDictionary(CGThing): "}\n" "\n" "impl ToJSValConvertible for ${selfName} {\n" - " fn to_jsval(&self, cx: *mut JSContext) -> JSVal {\n" - " let obj = unsafe { JS_NewObject(cx, 0 as *const JSClass, 0 as *const JSObject, 0 as *const JSObject) };\n" + " fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {\n" + " let obj = unsafe { RootedObject::new(cx, JS_NewObject(cx, ptr::null())) };\n" "${insertMembers}" - " ObjectOrNullValue(obj)\n" + " rval.set(ObjectOrNullValue(obj.ptr))\n" " }\n" "}\n").substitute({ "selfName": self.makeClassName(d), @@ -4587,7 +4928,7 @@ class CGDictionary(CGThing): declType = CGWrapper(info.declType, pre="Option<", post=">") return declType.define() - def getMemberConversion(self, memberInfo): + def getMemberConversion(self, memberInfo, memberType): def indent(s): return CGIndenter(CGGeneric(s), 8).define() @@ -4595,8 +4936,10 @@ class CGDictionary(CGThing): templateBody = info.template default = info.default declType = info.declType - replacements = { "val": "value" } + replacements = { "val": "rval.handle()" } conversion = string.Template(templateBody).substitute(replacements) + if memberType.isAny(): + conversion = "%s.get()" % conversion assert (member.defaultValue is None) == (default is None) if not default: @@ -4604,14 +4947,16 @@ class CGDictionary(CGThing): conversion = "Some(%s)" % conversion conversion = ( - "match try!(get_dictionary_property(cx, object, \"%s\")) {\n" - " Some(value) => {\n" + "{\n" + "let mut rval = RootedValue::new(cx, UndefinedValue());\n" + "match try!(get_dictionary_property(cx, object.handle(), \"%s\", rval.handle_mut())) {\n" + " true => {\n" "%s\n" " },\n" - " None => {\n" + " false => {\n" "%s\n" " },\n" - "}") % (member.identifier.name, indent(conversion), indent(default)) + "}\n}") % (member.identifier.name, indent(conversion), indent(default)) return CGGeneric(conversion) @@ -4641,7 +4986,7 @@ class CGRegisterProtos(CGAbstractMethod): def __init__(self, config): arguments = [ Argument('*mut JSContext', 'cx'), - Argument('*mut JSObject', 'global'), + Argument('HandleObject', 'global'), ] CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments, unsafe=False, pub=True) @@ -4732,38 +5077,41 @@ class CGBindingRoot(CGThing): # Add imports curr = CGImports(curr, descriptors + callbackDescriptors, mainCallbacks, [ 'js', - 'js::{JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}', - 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}', + 'js::JS_CALLEE', + 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS, JSCLASS_IMPLEMENTS_BARRIERS}', 'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}', - 'js::{JSCLASS_RESERVED_SLOTS_MASK, JSID_VOID, JSJitInfo}', - 'js::{JSPROP_ENUMERATE, JSPROP_NATIVE_ACCESSORS, JSPROP_SHARED}', - 'js::{JSRESOLVE_ASSIGNING, JSRESOLVE_QUALIFIED}', + 'js::{JSCLASS_RESERVED_SLOTS_MASK}', + 'js::{JSPROP_ENUMERATE, JSPROP_SHARED}', 'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}', 'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}', 'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}', 'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_IsExceptionPending}', - 'js::jsapi::{JS_NewObject, JS_ObjectIsCallable, JS_SetProperty, JS_SetPrototype}', - 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSBool, JSContext}', - 'js::jsapi::{JSClass, JSFreeOp, JSFunctionSpec, JSHandleObject, jsid}', - 'js::jsapi::{JSNativeWrapper, JSObject, JSPropertyDescriptor, JS_ArrayIterator}', - 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec, JS_PropertyStub}', - 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer, JS_ConvertStub}', - 'js::jsapi::{JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub}', - 'js::jsapi::{JSMutableHandleValue, JSHandleId, JSType}', + 'js::jsapi::{JS_NewObjectWithGivenProto, JS_NewObject, IsCallable, JS_SetProperty, JS_SetPrototype}', + 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSContext}', + 'js::jsapi::{JSClass, FreeOp, JSFreeOp, JSFunctionSpec, jsid}', + 'js::jsapi::{MutableHandleValue, MutableHandleObject, HandleObject, HandleValue, RootedObject, RootedValue}', + 'js::jsapi::{JSNativeWrapper, JSNative, JSObject, JSPropertyDescriptor}', + 'js::jsapi::{JSPropertySpec}', + 'js::jsapi::{JSString, JSTracer, JSJitInfo, JSJitInfo_OpType, JSJitInfo_AliasSet}', + 'js::jsapi::{MutableHandle, Handle, HandleId, JSType, JSValueType}', + 'js::jsapi::{SymbolCode, ObjectOpResult, HandleValueArray}', + 'js::jsapi::{JSJitGetterCallArgs, JSJitSetterCallArgs, JSJitMethodCallArgs, CallArgs}', + 'js::jsapi::{JSAutoCompartment, JSAutoRequest, JS_ComputeThis}', + 'js::jsapi::GetGlobalForObjectCrossCompartment', 'js::jsval::JSVal', 'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}', 'js::jsval::{NullValue, UndefinedValue}', - 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}', - 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps, AutoIdVector}', + 'js::glue::{CallJitMethodOp, CallJitGetterOp, CallJitSetterOp, CreateProxyHandler}', + 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}', 'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}', 'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}', - 'js::rust::with_compartment', + 'js::rust::GCMethods', + 'js::{JSTrue, JSFalse}', 'dom::bindings', 'dom::bindings::global::GlobalRef', 'dom::bindings::global::global_object_for_js_object', - 'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary, Unrooted}', - 'dom::bindings::js::{OptionalOptionalRootable, OptionalRootable}', - 'dom::bindings::js::{OptionalRootedReference, ResultRootable, Rootable}', + 'dom::bindings::js::{JS, Root, RootedReference}', + 'dom::bindings::js::{OptionalRootedReference}', 'dom::bindings::utils::{create_dom_global, do_create_interface_objects}', 'dom::bindings::utils::ConstantSpec', 'dom::bindings::utils::{DOMClass}', @@ -4780,16 +5128,16 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{NativeProperties, NativePropertyHooks}', 'dom::bindings::utils::ConstantVal::{IntVal, UintVal}', 'dom::bindings::utils::NonNullJSNative', - 'dom::bindings::trace::JSTraceable', + 'dom::bindings::trace::{JSTraceable, RootedTraceable}', 'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', 'dom::bindings::callback::wrap_call_this_object', 'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}', - 'dom::bindings::conversions::{native_from_reflector, native_from_reflector_jsmanaged}', + 'dom::bindings::conversions::{native_from_reflector, native_from_handlevalue, native_from_handleobject}', 'dom::bindings::conversions::DOM_OBJECT_SLOT', 'dom::bindings::conversions::IDLInterface', 'dom::bindings::conversions::jsid_to_str', - 'dom::bindings::conversions::StringificationBehavior::{Default, Empty}', + 'dom::bindings::conversions::StringificationBehavior', 'dom::bindings::codegen::{PrototypeList, RegisterBindings, UnionTypes}', 'dom::bindings::codegen::Bindings::*', 'dom::bindings::error::{Fallible, Error, ErrorResult}', @@ -4812,6 +5160,10 @@ class CGBindingRoot(CGThing): 'std::num', 'std::ptr', 'std::str', + 'std::rc', + 'std::rc::Rc', + 'std::default::Default', + 'std::ffi::CString', ]) # Add the auto-generated comment. @@ -4918,7 +5270,7 @@ class CGCallback(CGClass): bases=[ClassBase(baseName)], constructors=self.getConstructors(), methods=realMethods+getters+setters, - decorators="#[derive(PartialEq,Copy,Clone)]#[jstraceable]") + decorators="#[derive(PartialEq)]#[jstraceable]") def getConstructors(self): return [ClassConstructor( @@ -4927,7 +5279,7 @@ class CGCallback(CGClass): visibility="pub", explicit=False, baseConstructors=[ - "%s::new(aCallback)" % self.baseName + "%s::new()" % self.baseName ])] def getMethodImpls(self, method): @@ -4936,13 +5288,13 @@ class CGCallback(CGClass): # Strip out the JSContext*/JSObject* args # that got added. assert args[0].name == "cx" and args[0].argType == "*mut JSContext" - assert args[1].name == "aThisObj" and args[1].argType == "*mut JSObject" + assert args[1].name == "aThisObj" and args[1].argType == "HandleObject" args = args[2:] # Record the names of all the arguments, so we can use them when we call # the private method. argnames = [arg.name for arg in args] - argnamesWithThis = ["s.get_context()", "thisObjJS"] + argnames - argnamesWithoutThis = ["s.get_context()", "ptr::null_mut()"] + argnames + argnamesWithThis = ["s.get_context()", "thisObjJS.handle()"] + argnames + argnamesWithoutThis = ["s.get_context()", "thisObjJS.handle()"] + argnames # Now that we've recorded the argnames for our call to our private # method, insert our optional argument for deciding whether the # CallSetup should re-throw exceptions on aRv. @@ -4951,12 +5303,12 @@ class CGCallback(CGClass): # And now insert our template argument. argsWithoutThis = list(args) - args.insert(0, Argument("JSRef<T>", "thisObj")) + args.insert(0, Argument("&T", "thisObj")) # And the self argument - method.args.insert(0, Argument(None, "self")) - args.insert(0, Argument(None, "self")) - argsWithoutThis.insert(0, Argument(None, "self")) + method.args.insert(0, Argument(None, "&self")) + args.insert(0, Argument(None, "&self")) + argsWithoutThis.insert(0, Argument(None, "&self")) setupCall = ("let s = CallSetup::new(self, aExceptionHandling);\n" "if s.get_context().is_null() {\n" @@ -4965,8 +5317,9 @@ class CGCallback(CGClass): bodyWithThis = string.Template( setupCall+ - "let thisObjJS = wrap_call_this_object(s.get_context(), thisObj);\n" - "if thisObjJS.is_null() {\n" + "let mut thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());\n" + "wrap_call_this_object(s.get_context(), thisObj, thisObjJS.handle_mut());\n" + "if thisObjJS.ptr.is_null() {\n" " return Err(JSFailed);\n" "}\n" "return ${methodName}(${callArgs});").substitute({ @@ -4975,6 +5328,7 @@ class CGCallback(CGClass): }) bodyWithoutThis = string.Template( setupCall + + "let thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());" "return ${methodName}(${callArgs});").substitute({ "callArgs" : ", ".join(argnamesWithoutThis), "methodName": 'self.' + method.name, @@ -5017,7 +5371,7 @@ class CGCallbackFunctionImpl(CGGeneric): def __init__(self, callback): impl = string.Template("""\ impl CallbackContainer for ${type} { - fn new(callback: *mut JSObject) -> ${type} { + fn new(callback: *mut JSObject) -> Rc<${type}> { ${type}::new(callback) } @@ -5027,8 +5381,8 @@ impl CallbackContainer for ${type} { } impl ToJSValConvertible for ${type} { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - self.callback().to_jsval(cx) + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + self.callback().to_jsval(cx, rval); } }\ """).substitute({"type": callback.name}) @@ -5127,14 +5481,12 @@ class CallbackMember(CGNativeMember): "${returnResult}").substitute(replacements) return CGList([ CGGeneric(pre), - CGWrapper(CGIndenter(CGGeneric(body)), - pre="with_compartment(cx, self.parent.callback(), || {\n", - post="})") + CGGeneric(body), ], "\n").define() def getResultConversion(self): replacements = { - "val": "rval", + "val": "rval.handle()", } info = getJSToNativeConversionInfo( @@ -5153,6 +5505,8 @@ class CallbackMember(CGNativeMember): if self.retvalType is None or self.retvalType.isVoid(): retval = "()" + elif self.retvalType.isAny(): + retval = "rvalDecl.get()" else: retval = "rvalDecl" @@ -5177,16 +5531,17 @@ class CallbackMember(CGNativeMember): argval = arg.identifier.name if arg.variadic: - argval = argval + "[idx]" + argval = argval + "[idx].get()" jsvalIndex = "%d + idx" % i else: jsvalIndex = "%d" % i if arg.optional and not arg.defaultValue: argval += ".clone().unwrap()" - conversion = wrapForType("argv[%s]" % jsvalIndex, - result=argval, - successCode="") + conversion = wrapForType( + "argv_root.handle_mut()", result=argval, + successCode="argv[%s] = argv_root.ptr;" % jsvalIndex, + pre="let mut argv_root = RootedValue::new(cx, UndefinedValue());") if arg.variadic: conversion = string.Template( "for idx in 0..${arg}.len() {\n" + @@ -5216,7 +5571,7 @@ class CallbackMember(CGNativeMember): # We want to allow the caller to pass in a "this" object, as # well as a JSContext. return [Argument("*mut JSContext", "cx"), - Argument("*mut JSObject", "aThisObj")] + args + Argument("HandleObject", "aThisObj")] + args def getCallSetup(self): if self.needThisHandling: @@ -5230,7 +5585,7 @@ class CallbackMember(CGNativeMember): "}\n") def getArgcDecl(self): - return CGGeneric("let mut argc = %s as u32;" % self.argCountStr); + return CGGeneric("let mut argc = %s;" % self.argCountStr); @staticmethod def ensureASCIIName(idlObject): @@ -5252,7 +5607,7 @@ class CallbackMethod(CallbackMember): CallbackMember.__init__(self, sig, name, descriptorProvider, needThisHandling) def getRvalDecl(self): - return "let mut rval = UndefinedValue();\n" + return "let mut rval = RootedValue::new(cx, UndefinedValue());\n" def getCall(self): replacements = { @@ -5260,15 +5615,16 @@ class CallbackMethod(CallbackMember): "getCallable": self.getCallableDecl() } if self.argCount > 0: - replacements["argv"] = "argv.as_mut_ptr()" + replacements["argv"] = "argv.as_ptr()" replacements["argc"] = "argc" else: replacements["argv"] = "ptr::null_mut()" replacements["argc"] = "0" return string.Template("${getCallable}" "let ok = unsafe {\n" - " JS_CallFunctionValue(cx, ${thisObj}, callable,\n" - " ${argc}, ${argv}, &mut rval)\n" + " let rootedThis = RootedObject::new(cx, ${thisObj});\n" + " JS_CallFunctionValue(cx, rootedThis.handle(), callable.handle(),\n" + " &HandleValueArray { length_: ${argc} as ::libc::size_t, elements_: ${argv} }, rval.handle_mut())\n" "};\n" "if ok == 0 {\n" " return Err(JSFailed);\n" @@ -5280,10 +5636,10 @@ class CallCallback(CallbackMethod): descriptorProvider, needThisHandling=True) def getThisObj(self): - return "aThisObj" + return "aThisObj.get()" def getCallableDecl(self): - return "let callable = ObjectValue(unsafe {&*self.parent.callback()});\n" + return "let callable = RootedValue::new(cx, ObjectValue(unsafe {&*self.parent.callback()}));\n" class CallbackOperationBase(CallbackMethod): """ @@ -5300,23 +5656,23 @@ class CallbackOperationBase(CallbackMethod): # This relies on getCallableDecl declaring a boolean # isCallable in the case when we're a single-operation # interface. - return "if isCallable { aThisObj } else { self.parent.callback() }" + return "if isCallable { aThisObj.get() } else { self.parent.callback() }" def getCallableDecl(self): replacements = { "methodName": self.methodName } getCallableFromProp = string.Template( - 'try!(self.parent.get_callable_property(cx, "${methodName}"))' + 'RootedValue::new(cx, try!(self.parent.get_callable_property(cx, "${methodName}")))' ).substitute(replacements) if not self.singleOperation: return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp return ( - 'let isCallable = unsafe { JS_ObjectIsCallable(cx, self.parent.callback()) != 0 };\n' + 'let isCallable = unsafe { IsCallable(self.parent.callback()) != 0 };\n' 'let callable =\n' + CGIndenter( CGIfElseWrapper('isCallable', - CGGeneric('unsafe { ObjectValue(&*self.parent.callback()) }'), + CGGeneric('unsafe { RootedValue::new(cx, ObjectValue(&*self.parent.callback())) }'), CGGeneric(getCallableFromProp))).define() + ';\n') class CallbackOperation(CallbackOperationBase): @@ -5399,7 +5755,7 @@ class GlobalGenRoots(): return CGList([ CGGeneric(AUTOGENERATED_WARNING_COMMENT), CGGeneric("pub const MAX_PROTO_CHAIN_LENGTH: usize = %d;\n\n" % config.maxProtoChainLength), - CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy, Clone"), + CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy, Clone", repr="u16"), CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq, Copy, Clone"), ]) @@ -5416,7 +5772,7 @@ class GlobalGenRoots(): 'dom::bindings::codegen', 'dom::bindings::codegen::PrototypeList::Proxies', 'js::jsapi::JSContext', - 'js::jsapi::JSObject', + 'js::jsapi::HandleObject', 'libc', ], ignored_warnings=[]) @@ -5442,7 +5798,7 @@ class GlobalGenRoots(): descriptors = config.getDescriptors(register=True, isCallback=False) allprotos = [CGGeneric("use dom::types::*;\n"), - CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary};\n"), + CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"), CGGeneric("use dom::bindings::trace::JSTraceable;\n"), CGGeneric("use dom::bindings::utils::Reflectable;\n"), CGGeneric("use js::jsapi::JSTracer;\n\n"), @@ -5476,7 +5832,7 @@ impl ${selfName} for ${baseName} { pub struct ${name}Cast; impl ${name}Cast { #[inline] - pub fn to_ref<'a, T: ${toBound}+Reflectable>(base: JSRef<'a, T>) -> Option<JSRef<'a, ${name}>> { + pub fn to_ref<'a, T: ${toBound}+Reflectable>(base: &'a T) -> Option<&'a ${name}> { match base.${checkFn}() { true => Some(unsafe { mem::transmute(base) }), false => None @@ -5484,7 +5840,7 @@ impl ${name}Cast { } #[inline] - pub fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, ${name}>> { + pub fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a &'b T) -> Option<&'a &'b ${name}> { match base.${checkFn}() { true => Some(unsafe { mem::transmute(base) }), false => None @@ -5503,20 +5859,20 @@ impl ${name}Cast { } #[inline] - pub fn to_temporary<T: ${toBound}+Reflectable>(base: Temporary<T>) -> Option<Temporary<${name}>> { - match base.root().r().${checkFn}() { + pub fn to_root<T: ${toBound}+Reflectable>(base: Root<T>) -> Option<Root<${name}>> { + match base.r().${checkFn}() { true => Some(unsafe { mem::transmute(base) }), false => None } } #[inline] - pub fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, ${name}> { + pub fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: &'a T) -> &'a ${name} { unsafe { mem::transmute(derived) } } #[inline] - pub fn from_borrowed_ref<'a, 'b, T: ${fromBound}+Reflectable>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, ${name}> { + pub fn from_borrowed_ref<'a, 'b, T: ${fromBound}+Reflectable>(derived: &'a &'b T) -> &'a &'b ${name} { unsafe { mem::transmute(derived) } } @@ -5527,7 +5883,7 @@ impl ${name}Cast { } #[inline] - pub fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<${name}> { + pub fn from_root<T: ${fromBound}+Reflectable>(derived: Root<T>) -> Root<${name}> { unsafe { mem::transmute(derived) } } diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 8741cb9eacf..6e4bcbed34c 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -148,16 +148,16 @@ class Descriptor(DescriptorProvider): if self.interface.isCallback(): self.needsRooting = False ty = "%sBinding::%s" % (ifaceName, ifaceName) - self.returnType = ty + self.returnType = "Rc<%s>"% ty self.argumentType = "???" self.memberType = "???" self.nativeType = ty else: self.needsRooting = True - self.returnType = "Temporary<%s>" % ifaceName - self.argumentType = "JSRef<%s>" % ifaceName + self.returnType = "Root<%s>" % ifaceName + self.argumentType = "&%s" % ifaceName self.memberType = "Root<%s>" % ifaceName - self.nativeType = "Unrooted<%s>" % ifaceName + self.nativeType = "Root<%s>" % ifaceName self.concreteType = ifaceName self.register = desc.get('register', True) diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 089193cca43..317744907c7 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -24,17 +24,17 @@ //! | USVString | `USVString` | //! | ByteString | `ByteString` | //! | object | `*mut JSObject` | -//! | interface types | `JSRef<T>` | `Temporary<T>` | +//! | interface types | `&T` | `Root<T>` | //! | dictionary types | `&T` | *unsupported* | //! | enumeration types | `T` | -//! | callback function types | `T` | +//! | callback function types | `Rc<T>` | //! | nullable types | `Option<T>` | //! | sequences | `Vec<T>` | //! | union types | `T` | use dom::bindings::codegen::PrototypeList; use dom::bindings::error::throw_type_error; -use dom::bindings::js::{JSRef, Root, Unrooted}; +use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::str::{ByteString, USVString}; use dom::bindings::utils::{Reflectable, Reflector, DOMClass}; @@ -43,14 +43,15 @@ use util::str::DOMString; use js; use js::glue::{RUST_JSID_TO_STRING, RUST_JSID_IS_STRING}; use js::glue::RUST_JS_NumberValue; -use js::jsapi::{JSBool, JSContext, JSObject, JSString, jsid}; -use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64}; -use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32}; -use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean}; -use js::jsapi::{JS_ValueToString, JS_GetStringCharsAndLength}; +use js::rust::{ToUint64, ToInt64}; +use js::rust::{ToUint32, ToInt32}; +use js::rust::{ToUint16, ToNumber, ToBoolean, ToString}; +use js::jsapi::{JSContext, JSObject, JSString}; +use js::jsapi::{JS_StringHasLatin1Chars, JS_GetLatin1StringCharsAndLength, JS_GetTwoByteStringCharsAndLength}; use js::jsapi::{JS_NewUCStringCopyN, JS_NewStringCopyN}; use js::jsapi::{JS_WrapValue}; use js::jsapi::{JSClass, JS_GetClass}; +use js::jsapi::{HandleId, HandleValue, HandleObject, MutableHandleValue}; use js::jsval::JSVal; use js::jsval::{UndefinedValue, NullValue, BooleanValue, Int32Value, UInt32Value}; use js::jsval::{StringValue, ObjectValue, ObjectOrNullValue}; @@ -60,6 +61,9 @@ use num::Float; use std::borrow::ToOwned; use std::default; use std::slice; +use std::ptr; +use std::rc::Rc; +use core::nonzero::NonZero; /// A trait to retrieve the constants necessary to check if a `JSObject` /// implements a given interface. @@ -74,7 +78,7 @@ pub trait IDLInterface { /// A trait to convert Rust types to `JSVal`s. pub trait ToJSValConvertible { /// Convert `self` to a `JSVal`. JSAPI failure causes a task failure. - fn to_jsval(&self, cx: *mut JSContext) -> JSVal; + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue); } /// A trait to convert `JSVal`s to Rust types. @@ -85,206 +89,201 @@ pub trait FromJSValConvertible { /// Optional configuration of type `T` can be passed as the `option` /// argument. /// If it returns `Err(())`, a JSAPI exception is pending. - fn from_jsval(cx: *mut JSContext, val: JSVal, option: Self::Config) -> Result<Self, ()>; + fn from_jsval(cx: *mut JSContext, val: HandleValue, option: Self::Config) -> Result<Self, ()>; } impl ToJSValConvertible for () { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - UndefinedValue() + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(UndefinedValue()); } } impl ToJSValConvertible for JSVal { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - let mut value = *self; - if unsafe { JS_WrapValue(cx, &mut value) } == 0 { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(*self); + if unsafe { JS_WrapValue(cx, rval) } == 0 { panic!("JS_WrapValue failed."); } - value } } -unsafe fn convert_from_jsval<T: default::Default>( - cx: *mut JSContext, value: JSVal, - convert_fn: unsafe extern "C" fn(*mut JSContext, JSVal, *mut T) -> JSBool) -> Result<T, ()> { - let mut ret = default::Default::default(); - if convert_fn(cx, value, &mut ret) == 0 { - Err(()) - } else { - Ok(ret) +impl ToJSValConvertible for HandleValue { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(self.get()); + if unsafe { JS_WrapValue(cx, rval) } == 0 { + panic!("JS_WrapValue failed."); + } } } - impl ToJSValConvertible for bool { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - BooleanValue(*self) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(BooleanValue(*self)); } } impl FromJSValConvertible for bool { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<bool, ()> { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToBoolean) }; - result.map(|b| b != 0) + fn from_jsval(_cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<bool, ()> { + Ok(ToBoolean(val)) } } impl ToJSValConvertible for i8 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - Int32Value(*self as i32) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(Int32Value(*self as i32)); } } impl FromJSValConvertible for i8 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i8, ()> { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i8, ()> { + let result = ToInt32(cx, val); result.map(|v| v as i8) } } impl ToJSValConvertible for u8 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - Int32Value(*self as i32) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(Int32Value(*self as i32)); } } impl FromJSValConvertible for u8 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u8, ()> { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u8, ()> { + let result = ToInt32(cx, val); result.map(|v| v as u8) } } impl ToJSValConvertible for i16 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - Int32Value(*self as i32) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(Int32Value(*self as i32)); } } impl FromJSValConvertible for i16 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i16, ()> { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) }; + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i16, ()> { + let result = ToInt32(cx, val); result.map(|v| v as i16) } } impl ToJSValConvertible for u16 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - Int32Value(*self as i32) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(Int32Value(*self as i32)); } } impl FromJSValConvertible for u16 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u16, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToUint16) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u16, ()> { + ToUint16(cx, val) } } impl ToJSValConvertible for i32 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - Int32Value(*self) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(Int32Value(*self)); } } impl FromJSValConvertible for i32 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i32, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToECMAInt32) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i32, ()> { + ToInt32(cx, val) } } impl ToJSValConvertible for u32 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { - UInt32Value(*self) + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(UInt32Value(*self)); } } impl FromJSValConvertible for u32 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u32, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToECMAUint32) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u32, ()> { + ToUint32(cx, val) } } impl ToJSValConvertible for i64 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { unsafe { - RUST_JS_NumberValue(*self as f64) + rval.set(RUST_JS_NumberValue(*self as f64)); } } } impl FromJSValConvertible for i64 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<i64, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToInt64) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<i64, ()> { + ToInt64(cx, val) } } impl ToJSValConvertible for u64 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { unsafe { - RUST_JS_NumberValue(*self as f64) + rval.set(RUST_JS_NumberValue(*self as f64)); } } } impl FromJSValConvertible for u64 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<u64, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToUint64) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<u64, ()> { + ToUint64(cx, val) } } impl ToJSValConvertible for f32 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { unsafe { - RUST_JS_NumberValue(*self as f64) + rval.set(RUST_JS_NumberValue(*self as f64)); } } } impl FromJSValConvertible for f32 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<f32, ()> { - let result = unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) }; + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f32, ()> { + let result = ToNumber(cx, val); result.map(|f| f as f32) } } impl ToJSValConvertible for f64 { - fn to_jsval(&self, _cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, _cx: *mut JSContext, rval: MutableHandleValue) { unsafe { - RUST_JS_NumberValue(*self) + rval.set(RUST_JS_NumberValue(*self)); } } } impl FromJSValConvertible for f64 { type Config = (); - fn from_jsval(cx: *mut JSContext, val: JSVal, _option: ()) -> Result<f64, ()> { - unsafe { convert_from_jsval(cx, val, JS_ValueToNumber) } + fn from_jsval(cx: *mut JSContext, val: HandleValue, _option: ()) -> Result<f64, ()> { + ToNumber(cx, val) } } impl<T: Float + ToJSValConvertible> ToJSValConvertible for Finite<T> { #[inline] - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { let value = **self; - value.to_jsval(cx) + value.to_jsval(cx, rval); } } impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite<T> { type Config = (); - fn from_jsval(cx: *mut JSContext, value: JSVal, option: ()) -> Result<Finite<T>, ()> { + fn from_jsval(cx: *mut JSContext, value: HandleValue, option: ()) -> Result<Finite<T>, ()> { let result = try!(FromJSValConvertible::from_jsval(cx, value, option)); match Finite::new(result) { Some(v) => Ok(v), @@ -297,21 +296,22 @@ impl<T: Float + FromJSValConvertible<Config=()>> FromJSValConvertible for Finite } impl ToJSValConvertible for str { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { unsafe { let string_utf16: Vec<u16> = self.utf16_units().collect(); - let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr(), string_utf16.len() as libc::size_t); + let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr() as *const i16, + string_utf16.len() as libc::size_t); if jsstr.is_null() { panic!("JS_NewUCStringCopyN failed"); } - StringValue(&*jsstr) + rval.set(StringValue(&*jsstr)); } } } impl ToJSValConvertible for DOMString { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - (**self).to_jsval(cx) + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + (**self).to_jsval(cx, rval); } } @@ -333,18 +333,36 @@ impl default::Default for StringificationBehavior { /// Convert the given `JSString` to a `DOMString`. Fails if the string does not /// contain valid UTF-16. pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString { - unsafe { - let mut length = 0; - let chars = JS_GetStringCharsAndLength(cx, s, &mut length); + let mut length = 0; + let latin1 = unsafe { JS_StringHasLatin1Chars(s) != 0 }; + if latin1 { + let chars = unsafe { + JS_GetLatin1StringCharsAndLength(cx, ptr::null(), s, &mut length) + }; + assert!(!chars.is_null()); + + let mut buf = String::with_capacity(length as usize); + for i in 0..(length as isize) { + unsafe { + buf.push(*chars.offset(i) as char); + } + } + buf + } else { + let chars = unsafe { + JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), s, &mut length) + }; assert!(!chars.is_null()); - let char_vec = slice::from_raw_parts(chars, length as usize); + let char_vec = unsafe { + slice::from_raw_parts(chars as *const u16, length as usize) + }; String::from_utf16(char_vec).unwrap() } } /// Convert the given `jsid` to a `DOMString`. Fails if the `jsid` is not a /// string, or if the string does not contain valid UTF-16. -pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString { +pub fn jsid_to_str(cx: *mut JSContext, id: HandleId) -> DOMString { unsafe { assert!(RUST_JSID_IS_STRING(id) != 0); jsstring_to_str(cx, RUST_JSID_TO_STRING(id)) @@ -353,15 +371,16 @@ pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString { impl FromJSValConvertible for DOMString { type Config = StringificationBehavior; - fn from_jsval(cx: *mut JSContext, value: JSVal, + fn from_jsval(cx: *mut JSContext, value: HandleValue, null_behavior: StringificationBehavior) -> Result<DOMString, ()> { - if null_behavior == StringificationBehavior::Empty && value.is_null() { + if null_behavior == StringificationBehavior::Empty && + value.get().is_null() { Ok("".to_owned()) } else { - let jsstr = unsafe { JS_ValueToString(cx, value) }; + let jsstr = ToString(cx, value); if jsstr.is_null() { - debug!("JS_ValueToString failed"); + debug!("ToString failed"); Err(()) } else { Ok(jsstring_to_str(cx, jsstr)) @@ -371,56 +390,75 @@ impl FromJSValConvertible for DOMString { } impl ToJSValConvertible for USVString { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - self.0.to_jsval(cx) + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + self.0.to_jsval(cx, rval); } } impl FromJSValConvertible for USVString { type Config = (); - fn from_jsval(cx: *mut JSContext, value: JSVal, _: ()) + fn from_jsval(cx: *mut JSContext, value: HandleValue, _: ()) -> Result<USVString, ()> { - let jsstr = unsafe { JS_ValueToString(cx, value) }; + let jsstr = ToString(cx, value); if jsstr.is_null() { - debug!("JS_ValueToString failed"); - Err(()) - } else { - unsafe { - let mut length = 0; - let chars = JS_GetStringCharsAndLength(cx, jsstr, &mut length); - assert!(!chars.is_null()); - let char_vec = slice::from_raw_parts(chars, length as usize); - Ok(USVString(String::from_utf16_lossy(char_vec))) - } + debug!("ToString failed"); + return Err(()); + } + let latin1 = unsafe { JS_StringHasLatin1Chars(jsstr) != 0 }; + if latin1 { + return Ok(USVString(jsstring_to_str(cx, jsstr))); + } + unsafe { + let mut length = 0; + let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), jsstr, &mut length); + assert!(!chars.is_null()); + let char_vec = slice::from_raw_parts(chars as *const u16, length as usize); + Ok(USVString(String::from_utf16_lossy(char_vec))) } } } impl ToJSValConvertible for ByteString { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { unsafe { let jsstr = JS_NewStringCopyN(cx, self.as_ptr() as *const libc::c_char, self.len() as libc::size_t); if jsstr.is_null() { panic!("JS_NewStringCopyN failed"); } - StringValue(&*jsstr) + rval.set(StringValue(&*jsstr)); } } } impl FromJSValConvertible for ByteString { type Config = (); - fn from_jsval(cx: *mut JSContext, value: JSVal, _option: ()) -> Result<ByteString, ()> { - unsafe { - let string = JS_ValueToString(cx, value); - if string.is_null() { - debug!("JS_ValueToString failed"); - return Err(()); - } + fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<ByteString, ()> { + let string = ToString(cx, value); + if string.is_null() { + debug!("ToString failed"); + return Err(()); + } + + let latin1 = unsafe { JS_StringHasLatin1Chars(string) != 0 }; + if latin1 { + let mut length = 0; + let chars = unsafe { + JS_GetLatin1StringCharsAndLength(cx, ptr::null(), + string, &mut length) + }; + assert!(!chars.is_null()); + + let char_vec = unsafe { + Vec::from_raw_buf(chars as *mut u8, length as usize) + }; + + return Ok(ByteString::new(char_vec)); + } + unsafe { let mut length = 0; - let chars = JS_GetStringCharsAndLength(cx, string, &mut length); + let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), string, &mut length); let char_vec = slice::from_raw_parts(chars, length as usize); if char_vec.iter().any(|&c| c > 0xFF) { @@ -434,14 +472,13 @@ impl FromJSValConvertible for ByteString { } impl ToJSValConvertible for Reflector { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - let obj = self.get_jsobject(); + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + let obj = self.get_jsobject().get(); assert!(!obj.is_null()); - let mut value = ObjectValue(unsafe { &*obj }); - if unsafe { JS_WrapValue(cx, &mut value) } == 0 { + rval.set(ObjectValue(unsafe { &*obj })); + if unsafe { JS_WrapValue(cx, rval) } == 0 { panic!("JS_WrapValue failed."); } - value } } @@ -454,11 +491,10 @@ pub fn is_dom_class(clasp: *const JSClass) -> bool { /// Returns whether `obj` is a DOM object implemented as a proxy. pub fn is_dom_proxy(obj: *mut JSObject) -> bool { - use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily}; - + use js::glue::IsProxyHandlerFamily; unsafe { - (js_IsObjectProxyClass(obj) || js_IsFunctionProxyClass(obj)) && - IsProxyHandlerFamily(obj) + let clasp = JS_GetClass(obj); + ((*clasp).flags & js::JSCLASS_IS_PROXY) != 0 && IsProxyHandlerFamily(obj) != 0 } } @@ -467,29 +503,24 @@ pub fn is_dom_proxy(obj: *mut JSObject) -> bool { // We use slot 0 for holding the raw object. This is safe for both // globals and non-globals. pub const DOM_OBJECT_SLOT: u32 = 0; -const DOM_PROXY_OBJECT_SLOT: u32 = js::JSSLOT_PROXY_PRIVATE; - -/// Returns the index of the slot wherein a pointer to the reflected DOM object -/// is stored. -/// -/// Fails if `obj` is not a DOM object. -pub unsafe fn dom_object_slot(obj: *mut JSObject) -> u32 { - let clasp = JS_GetClass(obj); - if is_dom_class(&*clasp) { - DOM_OBJECT_SLOT - } else { - assert!(is_dom_proxy(obj)); - DOM_PROXY_OBJECT_SLOT - } -} /// Get the DOM object from the given reflector. pub unsafe fn native_from_reflector<T>(obj: *mut JSObject) -> *const T { use js::jsapi::JS_GetReservedSlot; + use js::glue::GetProxyPrivate; - let slot = dom_object_slot(obj); - let value = JS_GetReservedSlot(obj, slot); - value.to_private() as *const T + let clasp = JS_GetClass(obj); + let value = if is_dom_class(clasp) { + JS_GetReservedSlot(obj, DOM_OBJECT_SLOT) + } else { + assert!(is_dom_proxy(obj)); + GetProxyPrivate(obj) + }; + if value.is_undefined() { + ptr::null() + } else { + value.to_private() as *const T + } } /// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object. @@ -518,17 +549,16 @@ unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> { /// Returns Err(()) if `obj` is an opaque security wrapper or if the object is /// not a reflector for a DOM object of the given type (as defined by the /// proto_id and proto_depth). -pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unrooted<T>, ()> +pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Root<T>, ()> where T: Reflectable + IDLInterface { use js::glue::{IsWrapper, UnwrapObject}; - use std::ptr; unsafe { let dom_class = try!(get_dom_class(obj).or_else(|_| { if IsWrapper(obj) == 1 { debug!("found wrapper"); - obj = UnwrapObject(obj, /* stopAtOuter = */ 0, ptr::null_mut()); + obj = UnwrapObject(obj, /* stopAtOuter = */ 0); if obj.is_null() { debug!("unwrapping security wrapper failed"); Err(()) @@ -547,7 +577,9 @@ pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unro let proto_depth = <T as IDLInterface>::get_prototype_depth(); if dom_class.interface_chain[proto_depth] == proto_id { debug!("good prototype"); - Ok(Unrooted::from_raw(native_from_reflector(obj))) + let native = native_from_reflector(obj); + assert!(!native.is_null()); + Ok(Root::new(NonZero::new(native))) } else { debug!("bad prototype"); Err(()) @@ -555,37 +587,54 @@ pub fn native_from_reflector_jsmanaged<T>(mut obj: *mut JSObject) -> Result<Unro } } +/// Get a Rooted<T> for a DOM object accessible from a HandleValue +pub fn native_from_handlevalue<T>(v: HandleValue) -> Result<Root<T>, ()> + where T: Reflectable + IDLInterface +{ + native_from_reflector_jsmanaged(v.get().to_object()) +} + +/// Get a Rooted<T> for a DOM object accessible from a HandleObject +pub fn native_from_handleobject<T>(obj: HandleObject) -> Result<Root<T>, ()> + where T: Reflectable + IDLInterface +{ + native_from_reflector_jsmanaged(obj.get()) +} + impl<T: Reflectable> ToJSValConvertible for Root<T> { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - self.r().reflector().to_jsval(cx) + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + self.r().reflector().to_jsval(cx, rval); } } -impl<'a, T: Reflectable> ToJSValConvertible for JSRef<'a, T> { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - self.reflector().to_jsval(cx) +impl<'a, T: Reflectable> ToJSValConvertible for &'a T { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + self.reflector().to_jsval(cx, rval); } } -impl<'a, T: Reflectable> ToJSValConvertible for Unrooted<T> { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - self.reflector().to_jsval(cx) +impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + match self { + &Some(ref value) => value.to_jsval(cx, rval), + &None => rval.set(NullValue()), + } } } -impl<T: ToJSValConvertible> ToJSValConvertible for Option<T> { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { +impl<T: ToJSValConvertible> ToJSValConvertible for Option<Rc<T>> { + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { match self { - &Some(ref value) => value.to_jsval(cx), - &None => NullValue(), + &Some(ref value) => (**value).to_jsval(cx, rval), + &None => rval.set(NullValue()), } } } impl<X: default::Default, T: FromJSValConvertible<Config=X>> FromJSValConvertible for Option<T> { type Config = (); - fn from_jsval(cx: *mut JSContext, value: JSVal, _: ()) -> Result<Option<T>, ()> { - if value.is_null_or_undefined() { + fn from_jsval(cx: *mut JSContext, value: HandleValue, _: ()) -> Result<Option<T>, ()> { + if value.get().is_null_or_undefined() { Ok(None) } else { let option: X = default::Default::default(); @@ -596,11 +645,10 @@ impl<X: default::Default, T: FromJSValConvertible<Config=X>> FromJSValConvertibl } impl ToJSValConvertible for *mut JSObject { - fn to_jsval(&self, cx: *mut JSContext) -> JSVal { - let mut wrapped = ObjectOrNullValue(*self); + fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + rval.set(ObjectOrNullValue(*self)); unsafe { - assert!(JS_WrapValue(cx, &mut wrapped) != 0); + assert!(JS_WrapValue(cx, rval) != 0); } - wrapped } } diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs index 7d1e7ecbdd6..d228679631a 100644 --- a/components/script/dom/bindings/error.rs +++ b/components/script/dom/bindings/error.rs @@ -6,20 +6,22 @@ use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::Rootable; use dom::domexception::{DOMException, DOMErrorName}; use util::str::DOMString; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JSContext, JSObject, RootedValue}; use js::jsapi::{JS_IsExceptionPending, JS_SetPendingException, JS_ReportPendingException}; -use js::jsapi::{JS_ReportErrorNumber, JSErrorFormatString, JSEXN_TYPEERR, JSEXN_RANGEERR}; +use js::jsapi::{JS_ReportErrorNumber1, JSErrorFormatString, JSExnType}; use js::jsapi::{JS_SaveFrameChain, JS_RestoreFrameChain}; -use js::rust::with_compartment; +use js::jsapi::JSAutoCompartment; +use js::jsval::UndefinedValue; +use js::JSFalse; use libc; use std::ffi::CString; use std::ptr; +use std::mem; /// DOM exceptions that can be thrown by a native DOM method. #[derive(Debug, Clone)] @@ -116,10 +118,11 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, }; assert!(unsafe { JS_IsExceptionPending(cx) } == 0); - let exception = DOMException::new(global, code).root(); - let thrown = exception.to_jsval(cx); + let exception = DOMException::new(global, code); + let mut thrown = RootedValue::new(cx, UndefinedValue()); + exception.to_jsval(cx, thrown.handle_mut()); unsafe { - JS_SetPendingException(cx, thrown); + JS_SetPendingException(cx, thrown.handle()); } } @@ -128,9 +131,10 @@ pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) { unsafe { if JS_IsExceptionPending(cx) != 0 { let saved = JS_SaveFrameChain(cx); - with_compartment(cx, obj, || { + { + let _ac = JSAutoCompartment::new(cx, obj); JS_ReportPendingException(cx); - }); + } if saved != 0 { JS_RestoreFrameChain(cx); } @@ -158,25 +162,26 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char; 4] = [ static mut TYPE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, argCount: 1, - exnType: JSEXN_TYPEERR as i16, + exnType: JSExnType::JSEXN_TYPEERR as i16, }; /// Format string struct used to throw `RangeError`s. static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, argCount: 1, - exnType: JSEXN_RANGEERR as i16, + exnType: JSExnType::JSEXN_RANGEERR as i16, }; /// Callback used to throw javascript errors. /// See throw_js_error for info about error_number. unsafe extern fn get_error_message(_user_ref: *mut libc::c_void, - _locale: *const libc::c_char, - error_number: libc::c_uint) -> *const JSErrorFormatString + error_number: libc::c_uint) + -> *const JSErrorFormatString { - match error_number as i32 { - JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString, - JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString, + let num: JSExnType = mem::transmute(error_number); + match num { + JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString, + JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString, _ => panic!("Bad js error number given to get_error_message: {}", error_number) } } @@ -188,20 +193,18 @@ unsafe extern fn get_error_message(_user_ref: *mut libc::c_void, fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) { let error = CString::new(error).unwrap(); unsafe { - JS_ReportErrorNumber(cx, - Some(get_error_message as - unsafe extern "C" fn(*mut libc::c_void, *const libc::c_char, - libc::c_uint) -> *const JSErrorFormatString), + JS_ReportErrorNumber1(cx, + Some(get_error_message), ptr::null_mut(), error_number, error.as_ptr()); } } /// Throw a `TypeError` with the given message. pub fn throw_type_error(cx: *mut JSContext, error: &str) { - throw_js_error(cx, error, JSEXN_TYPEERR as u32); + throw_js_error(cx, error, JSExnType::JSEXN_TYPEERR as u32); } /// Throw a `RangeError` with the given message. pub fn throw_range_error(cx: *mut JSContext, error: &str) { - throw_js_error(cx, error, JSEXN_RANGEERR as u32); + throw_js_error(cx, error, JSExnType::JSEXN_RANGEERR as u32); } diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index d1294173dd1..a6924fbb281 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::native_from_reflector_jsmanaged; -use dom::bindings::js::{JS, JSRef, Rootable, Root, Unrooted}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::DocumentHelpers; use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers}; @@ -21,7 +21,7 @@ use msg::constellation_msg::{PipelineId, WorkerId}; use net_traits::ResourceTask; use js::{JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS}; -use js::glue::{GetGlobalForObjectCrossCompartment}; +use js::jsapi::{GetGlobalForObjectCrossCompartment}; use js::jsapi::{JSContext, JSObject}; use js::jsapi::{JS_GetClass}; use url::Url; @@ -30,9 +30,9 @@ use url::Url; #[derive(Copy, Clone)] pub enum GlobalRef<'a> { /// A reference to a `Window` object. - Window(JSRef<'a, window::Window>), + Window(&'a window::Window), /// A reference to a `WorkerGlobalScope` object. - Worker(JSRef<'a, WorkerGlobalScope>), + Worker(&'a WorkerGlobalScope), } /// A stack-based rooted reference to a global object. @@ -55,15 +55,6 @@ pub enum GlobalField { Worker(JS<WorkerGlobalScope>), } -/// An unrooted reference to a global object. -#[must_root] -pub enum GlobalUnrooted { - /// An unrooted reference to a `Window` object. - Window(Unrooted<window::Window>), - /// An unrooted reference to a `WorkerGlobalScope` object. - Worker(Unrooted<WorkerGlobalScope>), -} - impl<'a> GlobalRef<'a> { /// Get the `JSContext` for the `JSRuntime` associated with the thread /// this global object is on. @@ -76,7 +67,7 @@ impl<'a> GlobalRef<'a> { /// Extract a `Window`, causing task failure if the global object is not /// a `Window`. - pub fn as_window<'b>(&'b self) -> JSRef<'b, window::Window> { + pub fn as_window<'b>(&'b self) -> &'b window::Window { match *self { GlobalRef::Window(window) => window, GlobalRef::Worker(_) => panic!("expected a Window scope"), @@ -104,7 +95,7 @@ impl<'a> GlobalRef<'a> { pub fn resource_task(&self) -> ResourceTask { match *self { GlobalRef::Window(ref window) => { - let doc = window.Document().root(); + let doc = window.Document(); let doc = doc.r(); let loader = doc.loader(); loader.resource_task.clone() @@ -182,8 +173,8 @@ impl GlobalField { /// Create a new `GlobalField` from a rooted reference. pub fn from_rooted(global: &GlobalRef) -> GlobalField { match *global { - GlobalRef::Window(window) => GlobalField::Window(JS::from_rooted(window)), - GlobalRef::Worker(worker) => GlobalField::Worker(JS::from_rooted(worker)), + GlobalRef::Window(window) => GlobalField::Window(JS::from_ref(window)), + GlobalRef::Worker(worker) => GlobalField::Worker(JS::from_ref(worker)), } } @@ -196,30 +187,20 @@ impl GlobalField { } } -impl GlobalUnrooted { - /// Create a stack-bounded root for this reference. - pub fn root(&self) -> GlobalRoot { - match *self { - GlobalUnrooted::Window(ref window) => GlobalRoot::Window(window.root()), - GlobalUnrooted::Worker(ref worker) => GlobalRoot::Worker(worker.root()), - } - } -} - /// Returns the global object of the realm that the given JS object was created in. #[allow(unrooted_must_root)] -pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalUnrooted { +pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalRoot { unsafe { let global = GetGlobalForObjectCrossCompartment(obj); let clasp = JS_GetClass(global); assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); match native_from_reflector_jsmanaged(global) { - Ok(window) => return GlobalUnrooted::Window(window), + Ok(window) => return GlobalRoot::Window(window), Err(_) => (), } match native_from_reflector_jsmanaged(global) { - Ok(worker) => return GlobalUnrooted::Worker(worker), + Ok(worker) => return GlobalRoot::Worker(worker), Err(_) => (), } diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index fc22078360f..400200c3df3 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -11,178 +11,32 @@ //! //! Here is a brief overview of the important types: //! -//! - `JSRef<T>`: a freely-copyable reference to a rooted DOM object. //! - `Root<T>`: a stack-based reference to a rooted DOM object. //! - `JS<T>`: a reference to a DOM object that can automatically be traced by //! the GC when encountered as a field of a Rust structure. -//! - `Temporary<T>`: a reference to a DOM object that will remain rooted for -//! the duration of its lifetime. //! -//! The rule of thumb is as follows: +//! `JS<T>` does not allow access to their inner value without explicitly +//! creating a stack-based root via the `root` method. This returns a `Root<T>`, +//! which causes the JS-owned value to be uncollectable for the duration of the +//! `Root` object's lifetime. A reference to the object can then be obtained +//! from the `Root` object. These references are not allowed to outlive their +//! originating `Root<T>`. //! -//! - All methods return `Temporary<T>`, to ensure the value remains alive -//! until it is stored somewhere that is reachable by the GC. -//! - All functions take `JSRef<T>` arguments, to ensure that they will remain -//! uncollected for the duration of their usage. -//! - All DOM structs contain `JS<T>` fields and derive the `JSTraceable` -//! trait, to ensure that they are transitively marked as reachable by the GC -//! if the enclosing value is reachable. -//! - All methods for type `T` are implemented for `JSRef<T>`, to ensure that -//! the self value will not be collected for the duration of the method call. -//! -//! Both `Temporary<T>` and `JS<T>` do not allow access to their inner value -//! without explicitly creating a stack-based root via the `root` method -//! through the `Rootable<T>` trait. This returns a `Root<T>`, which causes the -//! JS-owned value to be uncollectable for the duration of the `Root` object's -//! lifetime. A `JSRef<T>` can be obtained from a `Root<T>` by calling the `r` -//! method. These `JSRef<T>` values are not allowed to outlive their -//! originating `Root<T>`, to ensure that all interactions with the enclosed -//! value only occur when said value is uncollectable, and will cause static -//! lifetime errors if misused. -//! -//! Other miscellaneous helper traits: -//! -//! - `OptionalRootable` and `OptionalOptionalRootable`: make rooting `Option` -//! values easy via a `root` method -//! - `ResultRootable`: make rooting successful `Result` values easy -//! - `TemporaryPushable`: allows mutating vectors of `JS<T>` with new elements -//! of `JSRef`/`Temporary` -//! - `RootedReference`: makes obtaining an `Option<JSRef<T>>` from an -//! `Option<Root<T>>` easy use dom::bindings::trace::JSTraceable; -use dom::bindings::trace::RootedVec; +use dom::bindings::trace::trace_reflector; use dom::bindings::utils::{Reflector, Reflectable}; use dom::node::Node; -use js::jsapi::JSObject; -use js::jsval::JSVal; +use js::jsapi::{JSObject, Heap, JSTracer}; +use js::jsval::{JSVal, UndefinedValue}; use layout_interface::TrustedNodeAddress; use script_task::STACK_ROOTS; use core::nonzero::NonZero; -use libc; use std::cell::{Cell, UnsafeCell}; use std::default::Default; -use std::intrinsics::return_address; -use std::marker::PhantomData; use std::ops::Deref; -/// An unrooted, JS-owned value. Must not be held across a GC. -/// -/// This is used in particular to wrap pointers extracted from a reflector. -#[must_root] -pub struct Unrooted<T> { - ptr: NonZero<*const T> -} - -impl<T: Reflectable> Unrooted<T> { - /// Create a new JS-owned value wrapped from a raw Rust pointer. - pub unsafe fn from_raw(raw: *const T) -> Unrooted<T> { - assert!(!raw.is_null()); - Unrooted { - ptr: NonZero::new(raw) - } - } - - /// Create a new unrooted value from a `JS<T>`. - #[allow(unrooted_must_root)] - pub fn from_js(ptr: JS<T>) -> Unrooted<T> { - Unrooted { - ptr: ptr.ptr - } - } - - /// Create a new unrooted value from a `Temporary<T>`. - #[allow(unrooted_must_root)] - pub fn from_temporary(ptr: Temporary<T>) -> Unrooted<T> { - Unrooted::from_js(ptr.inner) - } - - /// Get the `Reflector` for this pointer. - pub fn reflector<'a>(&'a self) -> &'a Reflector { - unsafe { - (**self.ptr).reflector() - } - } - - /// Returns an unsafe pointer to the interior of this object. - pub unsafe fn unsafe_get(&self) -> *const T { - *self.ptr - } -} - -impl<T: Reflectable> Rootable<T> for Unrooted<T> { - /// Create a stack-bounded root for this value. - fn root(&self) -> Root<T> { - STACK_ROOTS.with(|ref collection| { - let RootCollectionPtr(collection) = collection.get().unwrap(); - unsafe { - Root::new(&*collection, self.ptr) - } - }) - } -} - -impl<T> Copy for Unrooted<T> {} -impl<T> Clone for Unrooted<T> { - fn clone(&self) -> Unrooted<T> { *self } -} - -/// A type that represents a JS-owned value that is rooted for the lifetime of -/// this value. Importantly, it requires explicit rooting in order to interact -/// with the inner value. Can be assigned into JS-owned member fields (i.e. -/// `JS<T>` types) safely via the `JS<T>::assign` method or -/// `OptionalSettable::assign` (for `Option<JS<T>>` fields). -#[allow(unrooted_must_root)] -pub struct Temporary<T> { - inner: JS<T>, - /// On-stack JS pointer to assuage conservative stack scanner - _js_ptr: *mut JSObject, -} - -impl<T> Clone for Temporary<T> { - fn clone(&self) -> Temporary<T> { - Temporary { - inner: self.inner, - _js_ptr: self._js_ptr, - } - } -} - -impl<T> PartialEq for Temporary<T> { - fn eq(&self, other: &Temporary<T>) -> bool { - self.inner == other.inner - } -} - -impl<T: Reflectable> Temporary<T> { - /// Create a new `Temporary` value from an unrooted value. - #[allow(unrooted_must_root)] - pub fn from_unrooted(unrooted: Unrooted<T>) -> Temporary<T> { - Temporary { - inner: JS { ptr: unrooted.ptr }, - _js_ptr: unrooted.reflector().get_jsobject(), - } - } - - /// Create a new `Temporary` value from a rooted value. - #[allow(unrooted_must_root)] - pub fn from_rooted<U: Assignable<T>>(root: U) -> Temporary<T> { - let inner = JS::from_rooted(root); - Temporary { - inner: inner, - _js_ptr: inner.reflector().get_jsobject(), - } - } -} - -impl<T: Reflectable> Rootable<T> for Temporary<T> { - /// Create a stack-bounded root for this value. - fn root(&self) -> Root<T> { - self.inner.root() - } -} - /// A traced reference to a DOM object. Must only be used as a field in other /// DOM objects. #[must_root] @@ -198,6 +52,32 @@ impl<T> JS<T> { } } } +impl<T: Reflectable> JS<T> { + /// Root this JS-owned value to prevent its collection as garbage. + pub fn root(&self) -> Root<T> { + Root::new(self.ptr) + } + /// Create a JS<T> from a Root<T> + /// XXX Not a great API. Should be a call on Root<T> instead + pub fn from_rooted(root: &Root<T>) -> JS<T> { + JS { + ptr: unsafe { NonZero::new(&**root) } + } + } + /// Create a JS<T> from a &T + pub fn from_ref(obj: &T) -> JS<T> { + JS { + ptr: unsafe { NonZero::new(&*obj) } + } + } + /// Store an rooted value in this field. This is safe under the + /// assumption that JS<T> values are only used as fields in DOM types that + /// are reachable in the GC graph, so this unrooted value becomes + /// transitively rooted for the lifetime of its new owner. + pub fn assign(&mut self, val: Root<T>) { + self.ptr = val.ptr.clone(); + } +} /// An unrooted reference to a DOM object for use in layout. `Layout*Helpers` /// traits must be implemented on this. @@ -208,7 +88,7 @@ pub struct LayoutJS<T> { impl<T: Reflectable> LayoutJS<T> { /// Get the reflector. pub unsafe fn get_jsobject(&self) -> *mut JSObject { - (**self.ptr).reflector().get_jsobject() + (**self.ptr).reflector().get_jsobject().get() } } @@ -217,14 +97,12 @@ impl<T> Copy for JS<T> {} impl<T> Copy for LayoutJS<T> {} impl<T> PartialEq for JS<T> { - #[allow(unrooted_must_root)] fn eq(&self, other: &JS<T>) -> bool { self.ptr == other.ptr } } impl<T> PartialEq for LayoutJS<T> { - #[allow(unrooted_must_root)] fn eq(&self, other: &LayoutJS<T>) -> bool { self.ptr == other.ptr } @@ -260,29 +138,6 @@ impl LayoutJS<Node> { } } -impl<T: Reflectable> Rootable<T> for JS<T> { - /// Root this JS-owned value to prevent its collection as garbage. - fn root(&self) -> Root<T> { - STACK_ROOTS.with(|ref collection| { - let RootCollectionPtr(collection) = collection.get().unwrap(); - unsafe { - Root::new(&*collection, self.ptr) - } - }) - } -} - -impl<U: Reflectable> JS<U> { - /// Create a `JS<T>` from any JS-managed pointer. - pub fn from_rooted<T: Assignable<U>>(root: T) -> JS<U> { - unsafe { - root.get_js() - } - } -} - -//XXXjdm This is disappointing. This only gets called from trace hooks, in theory, -// so it's safe to assume that self is rooted and thereby safe to access. impl<T: Reflectable> Reflectable for JS<T> { fn reflector<'a>(&'a self) -> &'a Reflector { unsafe { @@ -298,19 +153,50 @@ impl<T: Reflectable> Reflectable for JS<T> { pub trait HeapGCValue: JSTraceable { } -impl HeapGCValue for JSVal { +impl HeapGCValue for Heap<JSVal> { } impl<T: Reflectable> HeapGCValue for JS<T> { } -/// A holder that provides interior mutability for GC-managed values such as -/// `JSVal` and `JS<T>`. +/// A holder that provides interior mutability for GC-managed JSVals. /// /// Must be used in place of traditional interior mutability to ensure proper /// GC barriers are enforced. #[must_root] #[jstraceable] +pub struct MutHeapJSVal { + val: UnsafeCell<Heap<JSVal>>, +} + +impl MutHeapJSVal { + /// Create a new `MutHeapJSVal`. + pub fn new() -> MutHeapJSVal { + MutHeapJSVal { + val: UnsafeCell::new(Heap::default()), + } + } + + /// Set this `MutHeapJSVal` to the given value, calling write barriers as + /// appropriate. + pub fn set(&self, val: JSVal) { + unsafe { + let cell = self.val.get(); + (*cell).set(val); + } + } + + /// Set the value in this `MutHeapJSVal`, calling read barriers as appropriate. + pub fn get(&self) -> JSVal { + unsafe { (*self.val.get()).get() } + } +} + + +/// A holder that provides interior mutability for GC-managed values such as +/// `JS<T>`. +#[must_root] +#[jstraceable] pub struct MutHeap<T: HeapGCValue+Copy> { val: Cell<T>, } @@ -323,13 +209,12 @@ impl<T: HeapGCValue+Copy> MutHeap<T> { } } - /// Set this `MutHeap` to the given value, calling write barriers as - /// appropriate. + /// Set this `MutHeap` to the given value. pub fn set(&self, val: T) { self.val.set(val) } - /// Set the value in this `MutHeap`, calling read barriers as appropriate. + /// Set the value in this `MutHeap`. pub fn get(&self) -> T { self.val.get() } @@ -353,8 +238,7 @@ impl<T: HeapGCValue+Copy> MutNullableHeap<T> { } } - /// Set this `MutNullableHeap` to the given value, calling write barriers - /// as appropriate. + /// Set this `MutNullableHeap` to the given value. pub fn set(&self, val: Option<T>) { self.ptr.set(val); } @@ -368,14 +252,14 @@ impl<T: HeapGCValue+Copy> MutNullableHeap<T> { impl<T: Reflectable> MutNullableHeap<JS<T>> { /// Retrieve a copy of the current inner value. If it is `None`, it is /// initialized with the result of `cb` first. - pub fn or_init<F>(&self, cb: F) -> Temporary<T> - where F: FnOnce() -> Temporary<T> + pub fn or_init<F>(&self, cb: F) -> Root<T> + where F: FnOnce() -> Root<T> { match self.get() { - Some(inner) => Temporary::from_rooted(inner), + Some(inner) => Root::from_rooted(inner), None => { let inner = cb(); - self.set(Some(JS::from_rooted(inner.clone()))); + self.set(Some(JS::from_rooted(&inner))); inner }, } @@ -396,16 +280,6 @@ impl<T: HeapGCValue+Copy> Default for MutNullableHeap<T> { } } -impl<T: Reflectable> JS<T> { - /// Store an unrooted value in this field. This is safe under the - /// assumption that JS<T> values are only used as fields in DOM types that - /// are reachable in the GC graph, so this unrooted value becomes - /// transitively rooted for the lifetime of its new owner. - pub fn assign(&mut self, val: Temporary<T>) { - *self = val.inner.clone(); - } -} - impl<T: Reflectable> LayoutJS<T> { /// Returns an unsafe pointer to the interior of this JS object. This is /// the only method that be safely accessed from layout. (The fact that @@ -419,129 +293,36 @@ impl<T: Reflectable> LayoutJS<T> { pub trait RootedReference<T> { /// Obtain a safe optional reference to the wrapped JS owned-value that /// cannot outlive the lifetime of this root. - fn r<'a>(&'a self) -> Option<JSRef<'a, T>>; + fn r<'a>(&'a self) -> Option<&'a T>; } impl<T: Reflectable> RootedReference<T> for Option<Root<T>> { - fn r<'a>(&'a self) -> Option<JSRef<'a, T>> { + fn r<'a>(&'a self) -> Option<&'a T> { self.as_ref().map(|root| root.r()) } } -/// Get an `Option<Option<JSRef<T>>>` out of an `Option<Option<Root<T>>>` +/// Get an `Option<Option<&T>>` out of an `Option<Option<Root<T>>>` pub trait OptionalRootedReference<T> { /// Obtain a safe optional optional reference to the wrapped JS owned-value /// that cannot outlive the lifetime of this root. - fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>>; + fn r<'a>(&'a self) -> Option<Option<&'a T>>; } impl<T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<T>>> { - fn r<'a>(&'a self) -> Option<Option<JSRef<'a, T>>> { + fn r<'a>(&'a self) -> Option<Option<&'a T>> { self.as_ref().map(|inner| inner.r()) } } -/// Trait that allows extracting a `JS<T>` value from a variety of -/// rooting-related containers, which in general is an unsafe operation since -/// they can outlive the rooted lifetime of the original value. -pub trait Assignable<T> { - /// Extract an unrooted `JS<T>`. - unsafe fn get_js(&self) -> JS<T>; -} - -impl<T> Assignable<T> for JS<T> { - unsafe fn get_js(&self) -> JS<T> { - self.clone() - } -} - -impl<'a, T: Reflectable> Assignable<T> for JSRef<'a, T> { - unsafe fn get_js(&self) -> JS<T> { - JS { - ptr: self.ptr - } - } -} - -impl<T: Reflectable> Assignable<T> for Temporary<T> { - unsafe fn get_js(&self) -> JS<T> { - self.inner.clone() - } -} - - -/// Root a rootable `Option` type (used for `Option<Temporary<T>>`) -pub trait OptionalRootable<T> { - /// Root the inner value, if it exists. - fn root(&self) -> Option<Root<T>>; -} - -impl<T: Reflectable, U: Rootable<T>> OptionalRootable<T> for Option<U> { - fn root(&self) -> Option<Root<T>> { - self.as_ref().map(|inner| inner.root()) - } -} - -/// Root a rootable `Option<Option>` type (used for `Option<Option<JS<T>>>`) -pub trait OptionalOptionalRootable<T> { - /// Root the inner value, if it exists. - fn root(&self) -> Option<Option<Root<T>>>; -} - -impl<T: Reflectable, U: OptionalRootable<T>> OptionalOptionalRootable<T> for Option<U> { - fn root(&self) -> Option<Option<Root<T>>> { - self.as_ref().map(|inner| inner.root()) - } -} - -/// Root a rootable `Result` type (any of `Temporary<T>` or `JS<T>`) -pub trait ResultRootable<T,U> { - /// Root the inner value, if it exists. - fn root(self) -> Result<Root<T>, U>; -} - -impl<T: Reflectable, U, V: Rootable<T>> ResultRootable<T, U> for Result<V, U> { - fn root(self) -> Result<Root<T>, U> { - self.map(|inner| inner.root()) - } -} - -/// Root a rootable type. -pub trait Rootable<T> { - /// Root the value. - fn root(&self) -> Root<T>; -} - - -/// Provides a facility to push unrooted values onto lists of rooted values. -/// This is safe under the assumption that said lists are reachable via the GC -/// graph, and therefore the new values are transitively rooted for the -/// lifetime of their new owner. -pub trait TemporaryPushable<T> { - /// Push a new value onto this container. - fn push_unrooted(&mut self, val: &T); - /// Insert a new value into this container. - fn insert_unrooted(&mut self, index: usize, val: &T); -} - -impl<T: Assignable<U>, U: Reflectable> TemporaryPushable<T> for Vec<JS<U>> { - fn push_unrooted(&mut self, val: &T) { - self.push(unsafe { val.get_js() }); - } - - fn insert_unrooted(&mut self, index: usize, val: &T) { - self.insert(index, unsafe { val.get_js() }); - } -} - -/// An opaque, LIFO rooting mechanism. This tracks roots and ensures that they -/// are destructed in a LIFO order. +/// A rooting mechanism for reflectors on the stack. +/// LIFO is not required. /// /// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*] /// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting). #[no_move] pub struct RootCollection { - roots: UnsafeCell<RootedVec<*mut JSObject>>, + roots: UnsafeCell<Vec<*const Reflector>>, } /// A pointer to a RootCollection, for use in global variables. @@ -555,142 +336,114 @@ impl Clone for RootCollectionPtr { impl RootCollection { /// Create an empty collection of roots pub fn new() -> RootCollection { - let addr = unsafe { - return_address() as *const libc::c_void - }; - RootCollection { - roots: UnsafeCell::new(RootedVec::new_with_destination_address(addr)), + roots: UnsafeCell::new(vec!()), } } - /// Track a stack-based root as a pointer to ensure LIFO root ordering. - fn root<'b>(&self, untracked_js_ptr: *mut JSObject) { + /// Start tracking a stack-based root + fn root<'b>(&self, untracked_reflector: *const Reflector) { unsafe { - let roots = self.roots.get(); - (*roots).push(untracked_js_ptr); - debug!(" rooting {:?}", untracked_js_ptr); + let mut roots = &mut *self.roots.get(); + roots.push(untracked_reflector); + assert!(!(*untracked_reflector).get_jsobject().is_null()) } } - /// Stop tracking a stack-based root, asserting if LIFO root ordering has - /// been violated + /// Stop tracking a stack-based root, asserting if the reflector isn't found fn unroot<'b, T: Reflectable>(&self, rooted: &Root<T>) { unsafe { - let roots = self.roots.get(); - let unrooted = (*roots).pop().unwrap(); - debug!("unrooted {:?} (expecting {:?}", unrooted, rooted.js_ptr); - assert!(unrooted == rooted.js_ptr); + let mut roots = &mut *self.roots.get(); + let old_reflector = &*rooted.r().reflector(); + match roots.iter().rposition(|r| *r == old_reflector) { + Some(idx) => { + roots.remove(idx); + }, + None => panic!("Can't remove a root that was never rooted!") + } } } } +/// SM Callback that traces the rooted reflectors +pub unsafe fn trace_roots(tracer: *mut JSTracer) { + STACK_ROOTS.with(|ref collection| { + let RootCollectionPtr(collection) = collection.get().unwrap(); + let collection = &*(*collection).roots.get(); + for root in collection.iter() { + trace_reflector(tracer, "reflector", &**root); + } + }); +} + /// A rooted reference to a DOM object. /// /// The JS value is pinned for the duration of this object's lifetime; roots /// are additive, so this object's destruction will not invalidate other roots /// for the same JS value. `Root`s cannot outlive the associated -/// `RootCollection` object. Attempts to transfer ownership of a `Root` via -/// moving will trigger dynamic unrooting failures due to incorrect ordering. -#[no_move] +/// `RootCollection` object. pub struct Root<T: Reflectable> { - /// List that ensures correct dynamic root ordering - root_list: &'static RootCollection, /// Reference to rooted value that must not outlive this container ptr: NonZero<*const T>, - /// On-stack JS pointer to assuage conservative stack scanner - js_ptr: *mut JSObject, + /// List that ensures correct dynamic root ordering + root_list: *const RootCollection, } impl<T: Reflectable> Root<T> { /// Create a new stack-bounded root for the provided JS-owned value. - /// It cannot not outlive its associated `RootCollection`, and it contains - /// a `JSRef` which cannot outlive this new `Root`. - #[inline] - fn new(roots: &'static RootCollection, unrooted: NonZero<*const T>) - -> Root<T> { - let js_ptr = unsafe { - (**unrooted).reflector().get_jsobject() - }; - roots.root(js_ptr); - Root { - root_list: roots, - ptr: unrooted, - js_ptr: js_ptr, - } + /// It cannot not outlive its associated `RootCollection`, and it gives + /// out references which cannot outlive this new `Root`. + pub fn new(unrooted: NonZero<*const T>) + -> Root<T> { + STACK_ROOTS.with(|ref collection| { + let RootCollectionPtr(collection) = collection.get().unwrap(); + unsafe { (*collection).root(&*(**unrooted).reflector()) } + Root { + ptr: unrooted, + root_list: collection, + } + }) } - /// Obtain a safe reference to the wrapped JS owned-value that cannot - /// outlive the lifetime of this root. - pub fn r<'b>(&'b self) -> JSRef<'b, T> { - JSRef { - ptr: self.ptr, - chain: PhantomData, - } + /// Generate a new root from a reference + pub fn from_ref(unrooted: &T) -> Root<T> { + Root::new(unsafe { NonZero::new(&*unrooted) }) } - /// Obtain an unsafe reference to the wrapped JS owned-value that can + /// Obtain a safe reference to the wrapped JS owned-value that cannot /// outlive the lifetime of this root. - /// - /// DO NOT CALL. - pub fn get_unsound_ref_forever<'b>(&self) -> JSRef<'b, T> { - JSRef { - ptr: self.ptr, - chain: PhantomData, - } + pub fn r<'a>(&'a self) -> &'a T { + &**self } -} -impl<T: Reflectable> Drop for Root<T> { - fn drop(&mut self) { - self.root_list.unroot(self); + /// Don't use this. Don't make me find you. + pub fn get_unsound_ref_forever<'a, 'b>(&'a self) -> &'b T { + unsafe { &**self.ptr } } -} -impl<'a, T: Reflectable> Deref for JSRef<'a, T> { - type Target = T; - fn deref<'b>(&'b self) -> &'b T { - unsafe { - &**self.ptr - } + /// Generate a new root from a JS<T> reference + #[allow(unrooted_must_root)] + pub fn from_rooted(js: JS<T>) -> Root<T> { + js.root() } } -/// A reference to a DOM object that is guaranteed to be alive. This is freely -/// copyable. -pub struct JSRef<'a, T> { - ptr: NonZero<*const T>, - chain: PhantomData<&'a ()>, -} - -impl<'a, T> Copy for JSRef<'a, T> {} - -impl<'a, T> Clone for JSRef<'a, T> { - fn clone(&self) -> JSRef<'a, T> { - JSRef { - ptr: self.ptr.clone(), - chain: self.chain, - } +impl<T: Reflectable> Deref for Root<T> { + type Target = T; + fn deref<'a>(&'a self) -> &'a T { + unsafe { &**self.ptr.deref() } } } -impl<'a, 'b, T> PartialEq<JSRef<'b, T>> for JSRef<'a, T> { - fn eq(&self, other: &JSRef<T>) -> bool { +impl<T: Reflectable> PartialEq for Root<T> { + fn eq(&self, other: &Root<T>) -> bool { self.ptr == other.ptr } } -impl<'a, T: Reflectable> JSRef<'a, T> { - /// Returns the inner pointer directly. - pub fn extended_deref(self) -> &'a T { - unsafe { - &**self.ptr - } +impl<T: Reflectable> Drop for Root<T> { + fn drop(&mut self) { + unsafe { (*self.root_list).unroot(self); } } } -impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> { - fn reflector<'b>(&'b self) -> &'b Reflector { - (**self).reflector() - } -} diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs index 4441bdf2335..b7800ddc83e 100644 --- a/components/script/dom/bindings/proxyhandler.rs +++ b/components/script/dom/bindings/proxyhandler.rs @@ -8,18 +8,19 @@ use dom::bindings::conversions::is_dom_proxy; use dom::bindings::utils::delete_property_by_id; -use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString}; +use js::jsapi::{JSContext, JSPropertyDescriptor, JSObject, JSString}; use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewStringCopyN}; -use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto}; -use js::jsapi::{JS_ReportErrorFlagsAndNumber, JS_StrictPropertyStub}; -use js::jsapi::{JSREPORT_WARNING, JSREPORT_STRICT, JSREPORT_STRICT_MODE_ERROR}; +use js::jsapi::{JS_DefinePropertyById6, JS_NewObjectWithGivenProto}; +use js::jsapi::{JS_StrictPropertyStub, JSErrNum}; +use js::jsapi::{Handle, HandleObject, HandleId, MutableHandle, RootedObject, ObjectOpResult}; +use js::jsapi::AutoIdVector; +use js::jsapi::GetObjectProto; use js::jsval::ObjectValue; use js::glue::GetProxyExtra; -use js::glue::{GetObjectProto, GetObjectParent, SetProxyExtra, GetProxyHandler}; +use js::glue::{SetProxyExtra, GetProxyHandler}; use js::glue::InvokeGetOwnPropertyDescriptor; -use js::glue::RUST_js_GetErrorMessage; -use js::glue::AutoIdVector; -use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY, JSRESOLVE_QUALIFIED}; +use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY}; +use js::{JSTrue, JSFalse}; use libc; use std::mem; @@ -32,60 +33,78 @@ static JSPROXYSLOT_EXPANDO: u32 = 0; /// Otherwise, walk along the prototype chain to find a property with that /// name. pub unsafe extern fn get_property_descriptor(cx: *mut JSContext, - proxy: *mut JSObject, - id: jsid, set: bool, - desc: *mut JSPropertyDescriptor) - -> bool { - let handler = GetProxyHandler(proxy); - if !InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) { - return false; + proxy: HandleObject, + id: HandleId, + desc: MutableHandle<JSPropertyDescriptor>) + -> u8 { + let handler = GetProxyHandler(proxy.get()); + if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, desc) == 0 { + return JSFalse; } - if !(*desc).obj.is_null() { - return true; + if !desc.get().obj.is_null() { + return JSTrue; } - //let proto = JS_GetPrototype(proxy); - let proto = GetObjectProto(proxy); - if proto.is_null() { - (*desc).obj = ptr::null_mut(); - return true; + let mut proto = RootedObject::new(cx, ptr::null_mut()); + if GetObjectProto(cx, proxy, proto.handle_mut()) == 0 { + desc.get().obj = ptr::null_mut(); + return JSTrue; } - JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc) != 0 + JS_GetPropertyDescriptorById(cx, proto.handle(), id, desc) } /// Defines an expando on the given `proxy`. -pub unsafe extern fn define_property(cx: *mut JSContext, proxy: *mut JSObject, - id: jsid, desc: *mut JSPropertyDescriptor) - -> bool { - static JSMSG_GETTER_ONLY: libc::c_uint = 160; - +pub unsafe extern fn define_property(cx: *mut JSContext, proxy: HandleObject, + id: HandleId, desc: Handle<JSPropertyDescriptor>, + result: *mut ObjectOpResult) + -> u8 { //FIXME: Workaround for https://github.com/mozilla/rust/issues/13385 - let setter: *const libc::c_void = mem::transmute((*desc).setter); + let setter: *const libc::c_void = mem::transmute(desc.get().setter); let setter_stub: *const libc::c_void = mem::transmute(JS_StrictPropertyStub); - if ((*desc).attrs & JSPROP_GETTER) != 0 && setter == setter_stub { - return JS_ReportErrorFlagsAndNumber(cx, - JSREPORT_WARNING | JSREPORT_STRICT | - JSREPORT_STRICT_MODE_ERROR, - Some(RUST_js_GetErrorMessage), ptr::null_mut(), - JSMSG_GETTER_ONLY) != 0; + if (desc.get().attrs & JSPROP_GETTER) != 0 && setter == setter_stub { + (*result).code_ = JSErrNum::JSMSG_GETTER_ONLY as u32; + return JSTrue; } - let expando = ensure_expando_object(cx, proxy); - return JS_DefinePropertyById(cx, expando, id, (*desc).value, (*desc).getter, - (*desc).setter, (*desc).attrs) != 0; + let expando = RootedObject::new(cx, ensure_expando_object(cx, proxy)); + JS_DefinePropertyById6(cx, expando.handle(), id, desc, result) } /// Deletes an expando off the given `proxy`. -pub unsafe extern fn delete(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, - bp: *mut bool) -> bool { - let expando = get_expando_object(proxy); - if expando.is_null() { - *bp = true; - return true; +pub unsafe extern fn delete(cx: *mut JSContext, proxy: HandleObject, id: HandleId, + bp: *mut ObjectOpResult) -> u8 { + let expando = RootedObject::new(cx, get_expando_object(proxy)); + if expando.ptr.is_null() { + (*bp).code_ = 0 /* OkCode */; + return JSTrue; } - return delete_property_by_id(cx, expando, id, &mut *bp); + delete_property_by_id(cx, expando.handle(), id, bp) +} + +/// Stub for ownPropertyKeys +pub unsafe extern fn own_property_keys(cx: *mut JSContext, + proxy: HandleObject, + props: *mut AutoIdVector) -> u8 { + // FIXME: implement this + // https://github.com/servo/servo/issues/6390 + JSTrue +} + +/// Controls whether the Extensible bit can be changed +pub unsafe extern fn prevent_extensions(_cx: *mut JSContext, + _proxy: HandleObject, + result: *mut ObjectOpResult) -> u8 { + (*result).code_ = JSErrNum::JSMSG_CANT_PREVENT_EXTENSIONS as u32; + return JSTrue; +} + +/// Reports whether the object is Extensible +pub unsafe extern fn is_extensible(_cx: *mut JSContext, _proxy: HandleObject, + succeeded: *mut u8) -> u8 { + *succeeded = JSTrue; + return JSTrue; } /// Returns the stringification of an object with class `name`. @@ -103,10 +122,10 @@ pub fn object_to_string(cx: *mut JSContext, name: &str) -> *mut JSString { } /// Get the expando object, or null if there is none. -pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject { +pub fn get_expando_object(obj: HandleObject) -> *mut JSObject { unsafe { - assert!(is_dom_proxy(obj)); - let val = GetProxyExtra(obj, JSPROXYSLOT_EXPANDO); + assert!(is_dom_proxy(obj.get())); + let val = GetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO); if val.is_undefined() { ptr::null_mut() } else { @@ -117,18 +136,16 @@ pub fn get_expando_object(obj: *mut JSObject) -> *mut JSObject { /// Get the expando object, or create it if it doesn't exist yet. /// Fails on JSAPI failure. -pub fn ensure_expando_object(cx: *mut JSContext, obj: *mut JSObject) +pub fn ensure_expando_object(cx: *mut JSContext, obj: HandleObject) -> *mut JSObject { unsafe { - assert!(is_dom_proxy(obj)); + assert!(is_dom_proxy(obj.get())); let mut expando = get_expando_object(obj); if expando.is_null() { - expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), - ptr::null_mut(), - GetObjectParent(obj)); + expando = JS_NewObjectWithGivenProto(cx, ptr::null_mut(), HandleObject::null()); assert!(!expando.is_null()); - SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(&*expando)); + SetProxyExtra(obj.get(), JSPROXYSLOT_EXPANDO, ObjectValue(&*expando)); } return expando; } @@ -142,18 +159,4 @@ pub fn fill_property_descriptor(desc: &mut JSPropertyDescriptor, desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE; desc.getter = None; desc.setter = None; - desc.shortid = 0; -} - -/// No-op required hook. -pub unsafe extern fn get_own_property_names(_cx: *mut JSContext, - _obj: *mut JSObject, - _v: *mut AutoIdVector) -> bool { - true -} - -/// No-op required hook. -pub unsafe extern fn enumerate(_cx: *mut JSContext, _obj: *mut JSObject, - _v: *mut AutoIdVector) -> bool { - true } diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index 046ae913b50..ad7f9239eae 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -22,11 +22,12 @@ //! is rooted when a hashmap entry is first created, and unrooted when the hashmap entry //! is removed. -use dom::bindings::js::{Temporary, JSRef, Unrooted}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, Reflectable}; +use dom::bindings::trace::trace_reflector; use script_task::{ScriptMsg, ScriptChan}; -use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSContext}; +use js::jsapi::{JSContext, JSTracer}; use libc; use std::cell::RefCell; @@ -35,6 +36,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied}; use std::marker::PhantomData; use std::rc::Rc; use std::sync::{Arc, Mutex}; +use core::nonzero::NonZero; thread_local!(pub static LIVE_REFERENCES: Rc<RefCell<Option<LiveDOMReferences>>> = Rc::new(RefCell::new(None))); @@ -63,7 +65,7 @@ impl<T: Reflectable> Trusted<T> { /// Create a new `Trusted<T>` instance from an existing DOM pointer. The DOM object will /// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's /// lifetime. - pub fn new(cx: *mut JSContext, ptr: JSRef<T>, script_chan: Box<ScriptChan + Send>) -> Trusted<T> { + pub fn new(cx: *mut JSContext, ptr: &T, script_chan: Box<ScriptChan + Send>) -> Trusted<T> { LIVE_REFERENCES.with(|ref r| { let r = r.borrow(); let live_references = r.as_ref().unwrap(); @@ -81,14 +83,14 @@ impl<T: Reflectable> Trusted<T> { /// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on /// a different thread than the original value from which this `Trusted<T>` was /// obtained. - pub fn to_temporary(&self) -> Temporary<T> { + pub fn root(&self) -> Root<T> { assert!(LIVE_REFERENCES.with(|ref r| { let r = r.borrow(); let live_references = r.as_ref().unwrap(); self.owner_thread == (&*live_references) as *const _ as *const libc::c_void })); unsafe { - Temporary::from_unrooted(Unrooted::from_raw(self.ptr as *const T)) + Root::new(NonZero::new(self.ptr as *const T)) } } } @@ -151,10 +153,6 @@ impl LiveDOMReferences { refcount.clone() } Vacant(entry) => { - unsafe { - let rootable = (*ptr).reflector().rootable(); - JS_AddObjectRoot(cx, rootable); - } let refcount = Arc::new(Mutex::new(1)); entry.insert(refcount.clone()); refcount @@ -168,7 +166,6 @@ impl LiveDOMReferences { LIVE_REFERENCES.with(|ref r| { let r = r.borrow(); let live_references = r.as_ref().unwrap(); - let reflectable = raw_reflectable as *const Reflector; let mut table = live_references.table.borrow_mut(); match table.entry(raw_reflectable) { Occupied(entry) => { @@ -178,9 +175,6 @@ impl LiveDOMReferences { return; } - unsafe { - JS_RemoveObjectRoot(cx, (*reflectable).rootable()); - } let _ = entry.remove(); } Vacant(_) => { @@ -194,3 +188,16 @@ impl LiveDOMReferences { }) } } + +/// A JSTraceDataOp for tracing reflectors held in LIVE_REFERENCES +pub unsafe extern fn trace_refcounted_objects(tracer: *mut JSTracer, _data: *mut libc::c_void) { + LIVE_REFERENCES.with(|ref r| { + let r = r.borrow(); + let live_references = r.as_ref().unwrap(); + let table = live_references.table.borrow(); + for obj in table.keys() { + let reflectable = &*(*obj as *const Reflector); + trace_reflector(tracer, "LIVE_REFERENCES", reflectable); + } + }); +} diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index bdcdc140028..5697c7eb7dc 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -13,7 +13,7 @@ use js::glue::JS_STRUCTURED_CLONE_VERSION; use js::jsapi::JSContext; use js::jsapi::{JS_WriteStructuredClone, JS_ClearPendingException}; use js::jsapi::JS_ReadStructuredClone; -use js::jsval::{JSVal, UndefinedValue}; +use js::jsapi::{HandleValue, MutableHandleValue}; use libc::size_t; use std::ptr; @@ -26,13 +26,14 @@ pub struct StructuredCloneData { impl StructuredCloneData { /// Writes a structured clone. Returns a `DataClone` error if that fails. - pub fn write(cx: *mut JSContext, message: JSVal) + pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible<StructuredCloneData> { let mut data = ptr::null_mut(); let mut nbytes = 0; let result = unsafe { JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes, - ptr::null(), ptr::null_mut()) + ptr::null(), ptr::null_mut(), + HandleValue::undefined()) }; if result == 0 { unsafe { JS_ClearPendingException(cx); } @@ -47,15 +48,13 @@ impl StructuredCloneData { /// Reads a structured clone. /// /// Panics if `JS_ReadStructuredClone` fails. - pub fn read(self, global: GlobalRef) -> JSVal { - let mut message = UndefinedValue(); + pub fn read(self, global: GlobalRef, rval: MutableHandleValue) { unsafe { assert!(JS_ReadStructuredClone( - global.get_cx(), self.data as *const u64, self.nbytes, - JS_STRUCTURED_CLONE_VERSION, &mut message, + global.get_cx(), self.data, self.nbytes, + JS_STRUCTURED_CLONE_VERSION, rval, ptr::null(), ptr::null_mut()) != 0); } - message } } diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 6a0f72412de..f401e278498 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -44,7 +44,8 @@ use euclid::size::Size2D; use html5ever::tree_builder::QuirksMode; use hyper::header::Headers; use hyper::method::Method; -use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSGCTraceKind}; +use js::jsapi::{JSObject, JSTracer, JSGCTraceKind, JS_CallValueTracer, JS_CallObjectTracer, GCTraceKindToAscii, Heap}; +use js::jsapi::JS_CallUnbarrieredObjectTracer; use js::jsval::JSVal; use js::rust::Runtime; use layout_interface::{LayoutRPC, LayoutChan}; @@ -59,7 +60,7 @@ use msg::compositor_msg::ScriptListener; use msg::constellation_msg::ConstellationChan; use net_traits::image::base::Image; use util::str::{LengthOrPercentageOrAuto}; -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, UnsafeCell, RefCell}; use std::collections::{HashMap, HashSet}; use std::collections::hash_state::HashState; use std::ffi::CString; @@ -91,36 +92,46 @@ no_jsmanaged_fields!(EncodingRef); no_jsmanaged_fields!(Reflector); /// Trace a `JSVal`. -pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { - if !val.is_markable() { - return; - } - +pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) { unsafe { + if !val.get().is_markable() { + return; + } + let name = CString::new(description).unwrap(); - (*tracer).debugPrinter = None; - (*tracer).debugPrintIndex = !0; - (*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void; + (*tracer).debugPrinter_ = None; + (*tracer).debugPrintIndex_ = !0; + (*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void; debug!("tracing value {}", description); - JS_CallTracer(tracer, val.to_gcthing(), val.trace_kind()); + JS_CallValueTracer(tracer, val.ptr.get() as *mut _, + GCTraceKindToAscii(val.get().trace_kind())); } } /// Trace the `JSObject` held by `reflector`. #[allow(unrooted_must_root)] pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) { - trace_object(tracer, description, reflector.get_jsobject()) + unsafe { + let name = CString::new(description).unwrap(); + (*tracer).debugPrinter_ = None; + (*tracer).debugPrintIndex_ = !0; + (*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void; + debug!("tracing reflector {}", description); + JS_CallUnbarrieredObjectTracer(tracer, reflector.rootable(), + GCTraceKindToAscii(JSGCTraceKind::JSTRACE_OBJECT)); + } } /// Trace a `JSObject`. -pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject) { +pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: &Heap<*mut JSObject>) { unsafe { let name = CString::new(description).unwrap(); - (*tracer).debugPrinter = None; - (*tracer).debugPrintIndex = !0; - (*tracer).debugPrintArg = name.as_ptr() as *const libc::c_void; + (*tracer).debugPrinter_ = None; + (*tracer).debugPrintIndex_ = !0; + (*tracer).debugPrintArg_ = name.as_ptr() as *const libc::c_void; debug!("tracing {}", description); - JS_CallTracer(tracer, obj as *mut libc::c_void, JSGCTraceKind::JSTRACE_OBJECT); + JS_CallObjectTracer(tracer, obj.ptr.get() as *mut _, + GCTraceKindToAscii(JSGCTraceKind::JSTRACE_OBJECT)); } } @@ -168,15 +179,26 @@ impl<T: JSTraceable+Copy> JSTraceable for Cell<T> { } } -impl JSTraceable for *mut JSObject { +impl<T: JSTraceable> JSTraceable for UnsafeCell<T> { fn trace(&self, trc: *mut JSTracer) { - trace_object(trc, "object", *self); + unsafe { (*self.get()).trace(trc) } } } -impl JSTraceable for JSVal { + +impl JSTraceable for Heap<*mut JSObject> { fn trace(&self, trc: *mut JSTracer) { - trace_jsval(trc, "val", *self); + if self.get().is_null() { + return; + } + trace_object(trc, "object", self); + } +} + + +impl JSTraceable for Heap<JSVal> { + fn trace(&self, trc: *mut JSTracer) { + trace_jsval(trc, "val", self); } } @@ -324,115 +346,101 @@ impl JSTraceable for () { } } -/// Holds a set of vectors that need to be rooted -pub struct RootedCollectionSet { - set: Vec<HashSet<*const RootedVec<Void>>> +/// Homemade trait object for JSTraceable things +struct TraceableInfo { + pub ptr: *const libc::c_void, + pub trace: fn(obj: *const libc::c_void, tracer: *mut JSTracer) } -/// TLV Holds a set of vectors that need to be rooted -thread_local!(pub static ROOTED_COLLECTIONS: Rc<RefCell<RootedCollectionSet>> = - Rc::new(RefCell::new(RootedCollectionSet::new()))); - -/// Type of `RootedVec` -pub enum CollectionType { - /// DOM objects - DOMObjects, - /// `JSVal`s - JSVals, - /// `*mut JSObject`s - JSObjects, +/// Holds a set of JSTraceables that need to be rooted +pub struct RootedTraceableSet { + set: Vec<TraceableInfo> } +/// TLV Holds a set of JSTraceables that need to be rooted +thread_local!(pub static ROOTED_TRACEABLES: Rc<RefCell<RootedTraceableSet>> = + Rc::new(RefCell::new(RootedTraceableSet::new()))); -impl RootedCollectionSet { - fn new() -> RootedCollectionSet { - RootedCollectionSet { - set: vec!(HashSet::new(), HashSet::new(), HashSet::new()) +impl RootedTraceableSet { + fn new() -> RootedTraceableSet { + RootedTraceableSet { + set: vec!() } } - fn remove<T: VecRootableType>(collection: &RootedVec<T>) { - ROOTED_COLLECTIONS.with(|ref collections| { - let type_ = VecRootableType::tag(None::<T>); - let mut collections = collections.borrow_mut(); - assert!(collections.set[type_ as usize].remove(&(collection as *const _ as *const _))); + fn remove<T: JSTraceable>(traceable: &T) { + ROOTED_TRACEABLES.with(|ref traceables| { + let mut traceables = traceables.borrow_mut(); + let idx = + match traceables.set.iter() + .rposition(|x| x.ptr == traceable as *const T as *const _) { + Some(idx) => idx, + None => unreachable!(), + }; + traceables.set.remove(idx); }); } - fn add<T: VecRootableType>(collection: &RootedVec<T>) { - ROOTED_COLLECTIONS.with(|ref collections| { - let type_ = VecRootableType::tag(None::<T>); - let mut collections = collections.borrow_mut(); - collections.set[type_ as usize].insert(collection as *const _ as *const _); + fn add<T: JSTraceable>(traceable: &T) { + ROOTED_TRACEABLES.with(|ref traceables| { + fn trace<T: JSTraceable>(obj: *const libc::c_void, tracer: *mut JSTracer) { + let obj: &T = unsafe { &*(obj as *const T) }; + obj.trace(tracer); + } + + let mut traceables = traceables.borrow_mut(); + let info = TraceableInfo { + ptr: traceable as *const T as *const libc::c_void, + trace: trace::<T>, + }; + traceables.set.push(info); }) } unsafe fn trace(&self, tracer: *mut JSTracer) { - fn trace_collection_type<T>(tracer: *mut JSTracer, - collections: &HashSet<*const RootedVec<Void>>) - where T: JSTraceable + VecRootableType - { - for collection in collections { - let collection: *const RootedVec<Void> = *collection; - let collection = collection as *const RootedVec<T>; - unsafe { - let _ = (*collection).trace(tracer); - } - } + for info in self.set.iter() { + (info.trace)(info.ptr, tracer); } - - let dom_collections = - &self.set[CollectionType::DOMObjects as usize] as *const _ as *const HashSet<*const RootedVec<JS<Void>>>; - for dom_collection in (*dom_collections).iter() { - for reflector in (**dom_collection).iter() { - trace_reflector(tracer, "", reflector.reflector()); - } - } - - trace_collection_type::<JSVal>(tracer, &self.set[CollectionType::JSVals as usize]); - trace_collection_type::<*mut JSObject>(tracer, &self.set[CollectionType::JSObjects as usize]); } } - -/// Trait implemented by all types that can be used with RootedVec -pub trait VecRootableType { - /// Return the type tag used to determine how to trace RootedVec - fn tag(_a: Option<Self>) -> CollectionType; -} - -impl<T: Reflectable> VecRootableType for JS<T> { - fn tag(_a: Option<JS<T>>) -> CollectionType { CollectionType::DOMObjects } +/// Roots any JSTraceable thing +/// +/// If you have a valid Reflectable, use Root. +/// If you have GC things like *mut JSObject or JSVal, use jsapi::Rooted. +/// If you have an arbitrary number of Reflectables to root, use RootedVec<JS<T>> +/// If you know what you're doing, use this. +#[jstraceable] +pub struct RootedTraceable<'a, T: 'a + JSTraceable> { + ptr: &'a T } -impl VecRootableType for JSVal { - fn tag(_a: Option<JSVal>) -> CollectionType { CollectionType::JSVals } -} - -impl VecRootableType for *mut JSObject { - fn tag(_a: Option<*mut JSObject>) -> CollectionType { CollectionType::JSObjects } -} - -enum Void {} - -impl VecRootableType for Void { - fn tag(_a: Option<Void>) -> CollectionType { unreachable!() } +impl<'a, T: JSTraceable> RootedTraceable<'a, T> { + /// Root a JSTraceable thing for the life of this RootedTraceable + pub fn new(traceable: &'a T) -> RootedTraceable<'a, T> { + RootedTraceableSet::add(traceable); + RootedTraceable { ptr: traceable } + } } -impl Reflectable for Void { - fn reflector<'a>(&'a self) -> &'a Reflector { unreachable!() } +impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> { + fn drop(&mut self) { + RootedTraceableSet::remove(self.ptr); + } } /// A vector of items that are rooted for the lifetime -/// of this struct +/// of this struct. +/// Must be a reflectable #[allow(unrooted_must_root)] #[no_move] -pub struct RootedVec<T: VecRootableType> { +#[jstraceable] +pub struct RootedVec<T: JSTraceable + Reflectable> { v: Vec<T> } -impl<T: VecRootableType> RootedVec<T> { +impl<T: JSTraceable + Reflectable> RootedVec<T> { /// Create a vector of items of type T that is rooted for /// the lifetime of this struct pub fn new() -> RootedVec<T> { @@ -444,39 +452,38 @@ impl<T: VecRootableType> RootedVec<T> { } /// Create a vector of items of type T. This constructor is specific - /// for RootCollection. + /// for RootTraceableSet. pub fn new_with_destination_address(addr: *const libc::c_void) -> RootedVec<T> { unsafe { - RootedCollectionSet::add::<T>(&*(addr as *const _)); + RootedTraceableSet::add::<RootedVec<T>>(&*(addr as *const _)); } RootedVec::<T> { v: vec!() } } } -impl<T: VecRootableType> Drop for RootedVec<T> { +impl<T: JSTraceable + Reflectable> Drop for RootedVec<T> { fn drop(&mut self) { - RootedCollectionSet::remove(self); + RootedTraceableSet::remove(self); } } -impl<T: VecRootableType> Deref for RootedVec<T> { +impl<T: JSTraceable + Reflectable> Deref for RootedVec<T> { type Target = Vec<T>; fn deref(&self) -> &Vec<T> { &self.v } } -impl<T: VecRootableType> DerefMut for RootedVec<T> { +impl<T: JSTraceable + Reflectable> DerefMut for RootedVec<T> { fn deref_mut(&mut self) -> &mut Vec<T> { &mut self.v } } - -/// SM Callback that traces the rooted collections -pub unsafe fn trace_collections(tracer: *mut JSTracer) { - ROOTED_COLLECTIONS.with(|ref collections| { - let collections = collections.borrow(); - collections.trace(tracer); +/// SM Callback that traces the rooted traceables +pub unsafe fn trace_traceables(tracer: *mut JSTracer) { + ROOTED_TRACEABLES.with(|ref traceables| { + let traceables = traceables.borrow(); + traceables.trace(tracer); }); } diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index bee42bbe2d3..fa7204f7dc8 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -6,10 +6,10 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; -use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class}; +use dom::bindings::conversions::{native_from_handleobject, is_dom_class, jsstring_to_str}; use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, Root, Rootable}; +use dom::bindings::js::Root; use dom::bindings::trace::trace_object; use dom::browsercontext; use dom::window; @@ -19,30 +19,39 @@ use util::str::DOMString; use libc; use libc::c_uint; use std::boxed; -use std::cell::Cell; use std::ffi::CString; use std::ptr; +use std::cmp::PartialEq; +use std::default::Default; +use std::cell::UnsafeCell; use js::glue::UnwrapObject; use js::glue::{IsWrapper, RUST_JSID_IS_INT, RUST_JSID_TO_INT}; -use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction}; +use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction, JSTraceOp}; use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo}; -use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAndLength}; -use js::jsapi::{JSHandleObject, JSTracer}; +use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype}; +use js::jsapi::{HandleObject, HandleId, HandleValue, MutableHandleValue}; use js::jsapi::JS_GetFunctionObject; use js::jsapi::{JS_HasPropertyById, JS_GetPrototype}; use js::jsapi::{JS_GetProperty, JS_HasProperty, JS_SetProperty}; -use js::jsapi::{JS_DefineFunctions, JS_DefineProperty}; -use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; -use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass}; +use js::jsapi::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperty1}; +use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot}; +use js::jsapi::{JSContext, JSObject, JSClass, JSTracer}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; -use js::jsapi::JS_DeletePropertyById2; -use js::jsfriendapi::JS_ObjectToOuterObject; -use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; +use js::jsapi::{OnNewGlobalHookOption, CompartmentOptions}; +use js::jsapi::{JS_FireOnNewGlobalObject, JSVersion}; +use js::jsapi::JS_DeletePropertyById1; +use js::jsapi::JS_ObjectToOuterObject; +use js::jsapi::JS_NewObjectWithUniqueType; +use js::jsapi::{ObjectOpResult, RootedObject, RootedValue, Heap, MutableHandleObject}; +use js::jsapi::PropertyDefinitionBehavior; +use js::jsapi::JSAutoCompartment; +use js::jsapi::{DOMCallbacks, JSWrapObjectCallbacks}; use js::jsval::JSVal; -use js::jsval::{PrivateValue, ObjectValue, NullValue}; -use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue, UndefinedValue}; -use js::rust::with_compartment; +use js::jsval::{PrivateValue, NullValue}; +use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue}; +use js::rust::{GCMethods, ToString}; +use js::glue::{WrapperNew, GetCrossCompartmentWrapper}; use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT}; use js::JSFUN_CONSTRUCTOR; use js; @@ -145,7 +154,7 @@ unsafe impl Sync for DOMClass {} #[derive(Copy)] pub struct DOMJSClass { /// The actual JSClass. - pub base: js::Class, + pub base: js::jsapi::Class, /// Associated data for DOM object reflectors. pub dom_class: DOMClass } @@ -181,95 +190,93 @@ unsafe impl Sync for NativeProperties {} /// A JSNative that cannot be null. pub type NonNullJSNative = - unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool; + unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> u8; /// Creates the *interface prototype object* (if a `proto_class` is given) /// and the *interface object* (if a `constructor` is given). /// Fails on JSAPI failure. -pub fn do_create_interface_objects(cx: *mut JSContext, global: *mut JSObject, - receiver: *mut JSObject, - proto_proto: *mut JSObject, +pub fn do_create_interface_objects(cx: *mut JSContext, + receiver: HandleObject, + proto_proto: HandleObject, proto_class: Option<&'static JSClass>, constructor: Option<(NonNullJSNative, &'static str, u32)>, dom_class: *const DOMClass, - members: &'static NativeProperties) - -> *mut JSObject { + members: &'static NativeProperties, + rval: MutableHandleObject) { + if let Some(proto_class) = proto_class { + create_interface_prototype_object(cx, proto_proto, + proto_class, members, rval); + } + unsafe { - let proto = match proto_class { - Some(proto_class) => { - let proto = create_interface_prototype_object(cx, global, proto_proto, - proto_class, members); - JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, - PrivateValue(dom_class as *const libc::c_void)); - proto - }, - None => ptr::null_mut() - }; - - if let Some((native, name, nargs)) = constructor { - let s = CString::new(name).unwrap(); - create_interface_object(cx, global, receiver, - native, nargs, proto, - members, s.as_ptr()) + if !rval.get().is_null() { + JS_SetReservedSlot(rval.get(), DOM_PROTO_INSTANCE_CLASS_SLOT, + PrivateValue(dom_class as *const libc::c_void)); } + } - proto + if let Some((native, name, nargs)) = constructor { + let s = CString::new(name).unwrap(); + create_interface_object(cx, receiver, + native, nargs, rval.handle(), + members, s.as_ptr()) } } /// Creates the *interface object*. /// Fails on JSAPI failure. -fn create_interface_object(cx: *mut JSContext, global: *mut JSObject, - receiver: *mut JSObject, +fn create_interface_object(cx: *mut JSContext, + receiver: HandleObject, constructor_native: NonNullJSNative, - ctor_nargs: u32, proto: *mut JSObject, + ctor_nargs: u32, proto: HandleObject, members: &'static NativeProperties, name: *const libc::c_char) { unsafe { let fun = JS_NewFunction(cx, Some(constructor_native), ctor_nargs, - JSFUN_CONSTRUCTOR, global, name); + JSFUN_CONSTRUCTOR, name); assert!(!fun.is_null()); - let constructor = JS_GetFunctionObject(fun); - assert!(!constructor.is_null()); + let constructor = RootedObject::new(cx, JS_GetFunctionObject(fun)); + assert!(!constructor.ptr.is_null()); if let Some(static_methods) = members.static_methods { - define_methods(cx, constructor, static_methods); + define_methods(cx, constructor.handle(), static_methods); } if let Some(static_properties) = members.static_attrs { - define_properties(cx, constructor, static_properties); + define_properties(cx, constructor.handle(), static_properties); } if let Some(constants) = members.consts { - define_constants(cx, constructor, constants); + define_constants(cx, constructor.handle(), constants); } - if !proto.is_null() { - assert!(JS_LinkConstructorAndPrototype(cx, constructor, proto) != 0); + if !proto.get().is_null() { + assert!(JS_LinkConstructorAndPrototype(cx, constructor.handle(), proto) != 0); } let mut already_defined = 0; assert!(JS_AlreadyHasOwnProperty(cx, receiver, name, &mut already_defined) != 0); if already_defined == 0 { - assert!(JS_DefineProperty(cx, receiver, name, - ObjectValue(&*constructor), - None, None, 0) != 0); + assert!(JS_DefineProperty1(cx, receiver, name, + constructor.handle(), + 0, None, None) != 0); } } } /// Defines constants on `obj`. /// Fails on JSAPI failure. -fn define_constants(cx: *mut JSContext, obj: *mut JSObject, +fn define_constants(cx: *mut JSContext, obj: HandleObject, constants: &'static [ConstantSpec]) { for spec in constants.iter() { + let value = RootedValue::new(cx, spec.get_value()); unsafe { assert!(JS_DefineProperty(cx, obj, spec.name.as_ptr() as *const libc::c_char, - spec.get_value(), None, None, + value.handle(), JSPROP_ENUMERATE | JSPROP_READONLY | - JSPROP_PERMANENT) != 0); + JSPROP_PERMANENT, None, None) != 0); } } } @@ -277,17 +284,17 @@ fn define_constants(cx: *mut JSContext, obj: *mut JSObject, /// Defines methods on `obj`. The last entry of `methods` must contain zeroed /// memory. /// Fails on JSAPI failure. -fn define_methods(cx: *mut JSContext, obj: *mut JSObject, +fn define_methods(cx: *mut JSContext, obj: HandleObject, methods: &'static [JSFunctionSpec]) { unsafe { - assert!(JS_DefineFunctions(cx, obj, methods.as_ptr()) != 0); + assert!(JS_DefineFunctions(cx, obj, methods.as_ptr(), PropertyDefinitionBehavior::DefineAllProperties) != 0); } } /// Defines attributes on `obj`. The last entry of `properties` must contain /// zeroed memory. /// Fails on JSAPI failure. -fn define_properties(cx: *mut JSContext, obj: *mut JSObject, +fn define_properties(cx: *mut JSContext, obj: HandleObject, properties: &'static [JSPropertySpec]) { unsafe { assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0); @@ -296,36 +303,32 @@ fn define_properties(cx: *mut JSContext, obj: *mut JSObject, /// Creates the *interface prototype object*. /// Fails on JSAPI failure. -fn create_interface_prototype_object(cx: *mut JSContext, global: *mut JSObject, - parent_proto: *mut JSObject, +fn create_interface_prototype_object(cx: *mut JSContext, global: HandleObject, proto_class: &'static JSClass, - members: &'static NativeProperties) - -> *mut JSObject { + members: &'static NativeProperties, + rval: MutableHandleObject) { unsafe { - let our_proto = JS_NewObjectWithUniqueType(cx, proto_class, - &*parent_proto, &*global); - assert!(!our_proto.is_null()); + rval.set(JS_NewObjectWithUniqueType(cx, proto_class, global)); + assert!(!rval.get().is_null()); if let Some(methods) = members.methods { - define_methods(cx, our_proto, methods); + define_methods(cx, rval.handle(), methods); } if let Some(properties) = members.attrs { - define_properties(cx, our_proto, properties); + define_properties(cx, rval.handle(), properties); } if let Some(constants) = members.consts { - define_constants(cx, our_proto, constants); + define_constants(cx, rval.handle(), constants); } - - return our_proto; } } /// A throwing constructor, for those interfaces that have neither /// `NoInterfaceObject` nor `Constructor`. pub unsafe extern fn throwing_constructor(cx: *mut JSContext, _argc: c_uint, - _vp: *mut JSVal) -> JSBool { + _vp: *mut JSVal) -> u8 { throw_type_error(cx, "Illegal constructor."); return 0; } @@ -351,6 +354,10 @@ pub fn initialize_global(global: *mut JSObject) { pub trait Reflectable { /// Returns the receiver's reflector. fn reflector<'a>(&'a self) -> &'a Reflector; + /// Initializes the Reflector + fn init_reflector(&mut self, _obj: *mut JSObject) { + panic!("Cannot call init on this Reflectable"); + } } /// Create the reflector for a new DOM object and yield ownership to the @@ -358,47 +365,56 @@ pub trait Reflectable { pub fn reflect_dom_object<T: Reflectable> (obj: Box<T>, global: GlobalRef, - wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Temporary<T>) - -> Temporary<T> { + wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>) + -> Root<T> { wrap_fn(global.get_cx(), global, obj) } /// A struct to store a reference to the reflector of a DOM object. // Allowing unused_attribute because the lint sometimes doesn't run in order #[allow(raw_pointer_derive, unrooted_must_root, unused_attributes)] -#[derive(PartialEq)] #[must_root] #[servo_lang = "reflector"] // If you're renaming or moving this field, update the path in plugins::reflector as well pub struct Reflector { - object: Cell<*mut JSObject>, + object: UnsafeCell<*mut JSObject>, +} + +#[allow(unrooted_must_root)] +impl PartialEq for Reflector { + fn eq(&self, other: &Reflector) -> bool { + unsafe { *self.object.get() == *other.object.get() } + } } impl Reflector { /// Get the reflector. #[inline] - pub fn get_jsobject(&self) -> *mut JSObject { - self.object.get() + pub fn get_jsobject(&self) -> HandleObject { + HandleObject { ptr: self.object.get() } } /// Initialize the reflector. (May be called only once.) - pub fn set_jsobject(&self, object: *mut JSObject) { - assert!(self.object.get().is_null()); - assert!(!object.is_null()); - self.object.set(object); + pub fn set_jsobject(&mut self, object: *mut JSObject) { + unsafe { + let obj = self.object.get(); + assert!((*obj).is_null()); + assert!(!object.is_null()); + *obj = object; + } } /// Return a pointer to the memory location at which the JS reflector - /// object is stored. Used by Temporary values to root the reflector, as + /// object is stored. Used to root the reflector, as /// required by the JSAPI rooting APIs. - pub unsafe fn rootable(&self) -> *mut *mut JSObject { - self.object.as_unsafe_cell().get() + pub fn rootable(&self) -> *mut *mut JSObject { + self.object.get() } /// Create an uninitialized `Reflector`. pub fn new() -> Reflector { Reflector { - object: Cell::new(ptr::null_mut()), + object: UnsafeCell::new(ptr::null_mut()) } } } @@ -407,33 +423,34 @@ impl Reflector { /// set to true and `*vp` to the value, otherwise `*found` is set to false. /// /// Returns false on JSAPI failure. -pub fn get_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject, - id: jsid, found: *mut bool, vp: *mut JSVal) +pub fn get_property_on_prototype(cx: *mut JSContext, proxy: HandleObject, + id: HandleId, found: *mut bool, vp: MutableHandleValue) -> bool { unsafe { //let proto = GetObjectProto(proxy); - let proto = JS_GetPrototype(proxy); - if proto.is_null() { + let mut proto = RootedObject::new(cx, ptr::null_mut()); + if JS_GetPrototype(cx, proxy, proto.handle_mut()) == 0 || + proto.ptr.is_null() { *found = false; return true; } let mut has_property = 0; - if JS_HasPropertyById(cx, proto, id, &mut has_property) == 0 { + if JS_HasPropertyById(cx, proto.handle(), id, &mut has_property) == 0 { return false; } *found = has_property != 0; - let no_output = vp.is_null(); + let no_output = vp.ptr.is_null(); if has_property == 0 || no_output { return true; } - JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp) != 0 + JS_ForwardGetPropertyTo(cx, proto.handle(), id, proxy, vp) != 0 } } /// Get an array index from the given `jsid`. Returns `None` if the given /// `jsid` is not an integer. -pub fn get_array_index_from_id(_cx: *mut JSContext, id: jsid) -> Option<u32> { +pub fn get_array_index_from_id(_cx: *mut JSContext, id: HandleId) -> Option<u32> { unsafe { if RUST_JSID_IS_INT(id) != 0 { return Some(RUST_JSID_TO_INT(id) as u32); @@ -460,28 +477,16 @@ pub fn get_array_index_from_id(_cx: *mut JSContext, id: jsid) -> Option<u32> { /// Returns `Err(())` on JSAPI failure (there is a pending exception), and /// `Ok(None)` if there was no matching string. pub fn find_enum_string_index(cx: *mut JSContext, - v: JSVal, + v: HandleValue, values: &[&'static str]) -> Result<Option<usize>, ()> { - unsafe { - let jsstr = JS_ValueToString(cx, v); - if jsstr.is_null() { - return Err(()); - } - - let mut length = 0; - let chars = JS_GetStringCharsAndLength(cx, jsstr, &mut length); - if chars.is_null() { - return Err(()); - } - - Ok(values.iter().position(|value| { - value.len() == length as usize && - (0..length as usize).all(|j| { - value.as_bytes()[j] as u16 == *chars.offset(j as isize) - }) - })) + let jsstr = ToString(cx, v); + if jsstr.is_null() { + return Err(()); } + + let search = jsstring_to_str(cx, jsstr); + Ok(values.iter().position(|value| value == &search)) } /// Returns wether `obj` is a platform object @@ -495,7 +500,7 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool { } // Now for simplicity check for security wrappers before anything else if IsWrapper(obj) == 1 { - let unwrapped_obj = UnwrapObject(obj, /* stopAtOuter = */ 0, ptr::null_mut()); + let unwrapped_obj = UnwrapObject(obj, /* stopAtOuter = */ 0); if unwrapped_obj.is_null() { return false; } @@ -508,53 +513,54 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool { /// Get the property with name `property` from `object`. /// Returns `Err(())` on JSAPI failure (there is a pending exception), and -/// `Ok(None)` if there was no property with the given name. +/// `Ok(false)` if there was no property with the given name. pub fn get_dictionary_property(cx: *mut JSContext, - object: *mut JSObject, - property: &str) -> Result<Option<JSVal>, ()> { - fn has_property(cx: *mut JSContext, object: *mut JSObject, property: &CString, - found: &mut JSBool) -> bool { + object: HandleObject, + property: &str, + rval: MutableHandleValue) + -> Result<bool, ()> { + fn has_property(cx: *mut JSContext, object: HandleObject, property: &CString, + found: &mut u8) -> bool { unsafe { JS_HasProperty(cx, object, property.as_ptr(), found) != 0 } } - fn get_property(cx: *mut JSContext, object: *mut JSObject, property: &CString, - value: &mut JSVal) -> bool { + fn get_property(cx: *mut JSContext, object: HandleObject, property: &CString, + value: MutableHandleValue) -> bool { unsafe { JS_GetProperty(cx, object, property.as_ptr(), value) != 0 } } let property = CString::new(property).unwrap(); - if object.is_null() { - return Ok(None); + if object.get().is_null() { + return Ok(false); } - let mut found: JSBool = 0; + let mut found: u8 = 0; if !has_property(cx, object, &property, &mut found) { return Err(()); } if found == 0 { - return Ok(None); + return Ok(false); } - let mut value = NullValue(); - if !get_property(cx, object, &property, &mut value) { + if !get_property(cx, object, &property, rval) { return Err(()); } - Ok(Some(value)) + Ok(true) } /// Set the property with name `property` from `object`. /// Returns `Err(())` on JSAPI failure, or null object, /// and Ok(()) otherwise pub fn set_dictionary_property(cx: *mut JSContext, - object: *mut JSObject, + object: HandleObject, property: &str, - value: &mut JSVal) -> Result<(), ()> { - if object.is_null() { + value: HandleValue) -> Result<(), ()> { + if object.get().is_null() { return Err(()); } @@ -569,79 +575,99 @@ pub fn set_dictionary_property(cx: *mut JSContext, } /// Returns whether `proxy` has a property `id` on its prototype. -pub fn has_property_on_prototype(cx: *mut JSContext, proxy: *mut JSObject, - id: jsid) -> bool { +pub fn has_property_on_prototype(cx: *mut JSContext, proxy: HandleObject, + id: HandleId) -> bool { // MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler); let mut found = false; - return !get_property_on_prototype(cx, proxy, id, &mut found, ptr::null_mut()) || found; + return !get_property_on_prototype(cx, proxy, id, &mut found, + MutableHandleValue { ptr: ptr::null_mut() }) || found; } /// Create a DOM global object with the given class. -pub fn create_dom_global(cx: *mut JSContext, class: *const JSClass) +pub fn create_dom_global(cx: *mut JSContext, class: *const JSClass, + trace: JSTraceOp) -> *mut JSObject { unsafe { - let obj = JS_NewGlobalObject(cx, class, ptr::null_mut()); - if obj.is_null() { + let mut options = CompartmentOptions::default(); + options.version_ = JSVersion::JSVERSION_LATEST; + options.traceGlobal_ = trace; + + let obj = + RootedObject::new(cx, + JS_NewGlobalObject(cx, class, ptr::null_mut(), + OnNewGlobalHookOption::DontFireOnNewGlobalHook, &options)); + if obj.ptr.is_null() { return ptr::null_mut(); } - with_compartment(cx, obj, || { - JS_InitStandardClasses(cx, obj); - }); - initialize_global(obj); - obj + let _ac = JSAutoCompartment::new(cx, obj.ptr); + JS_InitStandardClasses(cx, obj.handle()); + initialize_global(obj.ptr); + JS_FireOnNewGlobalObject(cx, obj.handle()); + obj.ptr } } /// Drop the resources held by reserved slots of a global object pub unsafe fn finalize_global(obj: *mut JSObject) { + let protolist = get_proto_or_iface_array(obj); + let list = (*protolist).as_mut_ptr(); + for idx in 0..(PrototypeList::ID::Count as isize) { + let entry = list.offset(idx); + let value = *entry; + if <*mut JSObject>::needs_post_barrier(value) { + <*mut JSObject>::relocate(entry); + } + } let _: Box<ProtoOrIfaceArray> = - Box::from_raw(get_proto_or_iface_array(obj)); + Box::from_raw(protolist); } /// Trace the resources held by reserved slots of a global object pub unsafe fn trace_global(tracer: *mut JSTracer, obj: *mut JSObject) { let array = get_proto_or_iface_array(obj); - for &proto in (*array).iter() { + for proto in (&*array).iter() { if !proto.is_null() { - trace_object(tracer, "prototype", proto); + trace_object(tracer, "prototype", &*(proto as *const *mut JSObject as *const Heap<*mut JSObject>)); } } } -/// Callback to outerize windows when wrapping. -pub unsafe extern fn wrap_for_same_compartment(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObject { - JS_ObjectToOuterObject(cx, obj) +unsafe extern fn wrap(cx: *mut JSContext, + existing: HandleObject, + obj: HandleObject) + -> *mut JSObject { + // FIXME terrible idea. need security wrappers + // https://github.com/servo/servo/issues/2382 + WrapperNew(cx, obj, GetCrossCompartmentWrapper()) } -/// Callback to outerize windows before wrapping. -pub unsafe extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject, - obj: *mut JSObject, _flags: c_uint) -> *mut JSObject { +unsafe extern fn pre_wrap(cx: *mut JSContext, _existing: HandleObject, + obj: HandleObject, _object_passed_to_wrap: HandleObject) + -> *mut JSObject { + let _ac = JSAutoCompartment::new(cx, obj.get()); JS_ObjectToOuterObject(cx, obj) } +/// Callback table for use with JS_SetWrapObjectCallbacks +pub static WRAP_CALLBACKS: JSWrapObjectCallbacks = JSWrapObjectCallbacks { + wrap: Some(wrap), + preWrap: Some(pre_wrap), +}; + /// Callback to outerize windows. -pub extern fn outerize_global(_cx: *mut JSContext, obj: JSHandleObject) -> *mut JSObject { - unsafe { - debug!("outerizing"); - let obj = *obj.unnamed_field1; - let win: Root<window::Window> = native_from_reflector_jsmanaged(obj).unwrap().root(); - // FIXME(https://github.com/rust-lang/rust/issues/23338) - let win = win.r(); - let context = win.browser_context(); - context.as_ref().unwrap().window_proxy() - } +pub unsafe extern fn outerize_global(_cx: *mut JSContext, obj: HandleObject) -> *mut JSObject { + debug!("outerizing"); + let win: Root<window::Window> = native_from_handleobject(obj).unwrap(); + // FIXME(https://github.com/rust-lang/rust/issues/23338) + let win = win.r(); + let context = win.browser_context(); + context.as_ref().unwrap().window_proxy() } /// Deletes the property `id` from `object`. -pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: *mut JSObject, - id: jsid, bp: &mut bool) -> bool { - let mut value = UndefinedValue(); - if JS_DeletePropertyById2(cx, object, id, &mut value) == 0 { - return false; - } - - *bp = value.to_boolean(); - return true; +pub unsafe fn delete_property_by_id(cx: *mut JSContext, object: HandleObject, + id: HandleId, bp: *mut ObjectOpResult) -> u8 { + JS_DeletePropertyById1(cx, object, id, bp) } /// Validate a qualified name. See https://dom.spec.whatwg.org/#validate for details. @@ -659,6 +685,18 @@ pub fn validate_qualified_name(qualified_name: &str) -> ErrorResult { } } +unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::Class, + proto_id: u32, + depth: u32) -> u8 { + let domclass: *const DOMJSClass = clasp as *const _; + let domclass = &*domclass; + (domclass.dom_class.interface_chain[depth as usize] as u32 == proto_id) as u8 +} + +pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks { + instanceClassMatchesProto: Some(instance_class_has_proto_at_depth), +}; + /// Validate a namespace and qualified name and extract their parts. /// See https://dom.spec.whatwg.org/#validate-and-extract for details. pub fn validate_and_extract(namespace: Option<DOMString>, qualified_name: &str) diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 63536fdd296..a727e3d3c74 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::InheritTypes::FileDerived; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::error::Fallible; use dom::bindings::codegen::Bindings::BlobBinding; @@ -54,20 +54,20 @@ impl Blob { } pub fn new(global: GlobalRef, bytes: Option<Vec<u8>>, - typeString: &str) -> Temporary<Blob> { + typeString: &str) -> Root<Blob> { reflect_dom_object(box Blob::new_inherited(global, BlobTypeId::Blob, bytes, typeString), global, BlobBinding::Wrap) } // http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<Blob>> { + pub fn Constructor(global: GlobalRef) -> Fallible<Root<Blob>> { Ok(Blob::new(global, None, "")) } // http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob pub fn Constructor_(global: GlobalRef, blobParts: DOMString, - blobPropertyBag: &BlobBinding::BlobPropertyBag) -> Fallible<Temporary<Blob>> { + blobPropertyBag: &BlobBinding::BlobPropertyBag) -> Fallible<Root<Blob>> { //TODO: accept other blobParts types - ArrayBuffer or ArrayBufferView or Blob let bytes: Option<Vec<u8>> = Some(blobParts.into_bytes()); let typeString = if is_ascii_printable(&blobPropertyBag.type_) { @@ -79,7 +79,7 @@ impl Blob { } } -impl<'a> BlobMethods for JSRef<'a, Blob> { +impl<'a> BlobMethods for &'a Blob { // http://dev.w3.org/2006/webapi/FileAPI/#dfn-size fn Size(self) -> u64{ match self.bytes { @@ -95,7 +95,7 @@ impl<'a> BlobMethods for JSRef<'a, Blob> { // http://dev.w3.org/2006/webapi/FileAPI/#slice-method-algo fn Slice(self, start: Option<i64>, end: Option<i64>, - contentType: Option<DOMString>) -> Temporary<Blob> { + contentType: Option<DOMString>) -> Root<Blob> { let size: i64 = self.Size().to_i64().unwrap(); let relativeStart: i64 = match start { None => 0, diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs index f51930f3f63..d4d13c1e4aa 100644 --- a/components/script/dom/browsercontext.rs +++ b/components/script/dom/browsercontext.rs @@ -2,11 +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::conversions::native_from_reflector_jsmanaged; +use dom::bindings::conversions::native_from_handleobject; use dom::bindings::conversions::{ToJSValConvertible}; -use dom::bindings::js::{JS, JSRef, Temporary, Root}; -use dom::bindings::js::{OptionalRootable, OptionalOptionalRootable}; -use dom::bindings::js::{ResultRootable, Rootable}; +use dom::bindings::js::{JS, Root}; use dom::bindings::proxyhandler::{get_property_descriptor, fill_property_descriptor}; use dom::bindings::utils::{Reflectable, WindowProxyHandler}; use dom::bindings::utils::get_array_index_from_id; @@ -15,73 +13,72 @@ use dom::element::Element; use dom::window::Window; use dom::window::WindowHelpers; -use js::jsapi::{JSContext, JSObject, jsid, JSPropertyDescriptor}; +use js::jsapi::{JSContext, JSObject, JSPropertyDescriptor, JSErrNum}; +use js::jsapi::{HandleObject, HandleId, MutableHandle, MutableHandleValue}; use js::jsapi::{JS_AlreadyHasOwnPropertyById, JS_ForwardGetPropertyTo}; -use js::jsapi::{JS_GetPropertyDescriptorById, JS_DefinePropertyById}; -use js::jsapi::{JS_SetPropertyById}; -use js::jsval::JSVal; +use js::jsapi::{JS_GetPropertyDescriptorById, JS_DefinePropertyById6}; +use js::jsapi::{JS_ForwardSetPropertyTo, ObjectOpResult, RootedObject, RootedValue, Handle, HandleValue, Heap}; +use js::jsapi::{JSAutoRequest, JSAutoCompartment}; +use js::jsval::{ObjectValue, UndefinedValue}; use js::glue::{GetProxyPrivate}; use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps}; -use js::rust::with_compartment; -use js::{JSRESOLVE_QUALIFIED, JSRESOLVE_ASSIGNING}; +use js::{JSTrue, JSFalse}; use std::ptr; +use std::default::Default; -#[allow(raw_pointer_derive)] #[jstraceable] #[privatize] pub struct BrowserContext { history: Vec<SessionHistoryEntry>, active_index: usize, - window_proxy: *mut JSObject, + window_proxy: Heap<*mut JSObject>, frame_element: Option<JS<Element>>, } impl BrowserContext { - pub fn new(document: JSRef<Document>, frame_element: Option<JSRef<Element>>) -> BrowserContext { - let mut context = BrowserContext { + pub fn new(document: &Document, frame_element: Option<&Element>) -> BrowserContext { + BrowserContext { history: vec!(SessionHistoryEntry::new(document)), active_index: 0, - window_proxy: ptr::null_mut(), - frame_element: frame_element.map(JS::from_rooted), - }; - context.create_window_proxy(); - context + window_proxy: Heap::default(), + frame_element: frame_element.map(JS::from_ref), + } } - pub fn active_document(&self) -> Temporary<Document> { - Temporary::from_rooted(self.history[self.active_index].document.clone()) + pub fn active_document(&self) -> Root<Document> { + self.history[self.active_index].document.root() } - pub fn active_window(&self) -> Temporary<Window> { - let doc = self.active_document().root(); + pub fn active_window(&self) -> Root<Window> { + let doc = self.active_document(); doc.r().window() } - pub fn frame_element(&self) -> Option<Temporary<Element>> { - self.frame_element.map(Temporary::from_rooted) + pub fn frame_element(&self) -> Option<Root<Element>> { + self.frame_element.map(Root::from_rooted) } pub fn window_proxy(&self) -> *mut JSObject { - assert!(!self.window_proxy.is_null()); - self.window_proxy + assert!(!self.window_proxy.get().is_null()); + self.window_proxy.get() } #[allow(unsafe_code)] - fn create_window_proxy(&mut self) { - let win = self.active_window().root(); + pub fn create_window_proxy(&mut self) { + let win = self.active_window(); let win = win.r(); let WindowProxyHandler(handler) = win.windowproxy_handler(); assert!(!handler.is_null()); - let parent = win.reflector().get_jsobject(); let cx = win.get_cx(); - let wrapper = with_compartment(cx, parent, || unsafe { - WrapperNew(cx, parent, handler) - }); + let _ar = JSAutoRequest::new(cx); + let parent = win.reflector().get_jsobject(); + let _ac = JSAutoCompartment::new(cx, parent.get()); + let wrapper = unsafe { WrapperNew(cx, parent, handler) }; assert!(!wrapper.is_null()); - self.window_proxy = wrapper; + self.window_proxy.set(wrapper); } } @@ -96,20 +93,20 @@ pub struct SessionHistoryEntry { } impl SessionHistoryEntry { - fn new(document: JSRef<Document>) -> SessionHistoryEntry { + fn new(document: &Document) -> SessionHistoryEntry { SessionHistoryEntry { - document: JS::from_rooted(document), + document: JS::from_ref(document), children: vec!() } } } #[allow(unsafe_code)] -unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: *mut JSObject, id: jsid) -> Option<Temporary<Window>> { +unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: HandleObject, id: HandleId) -> Option<Root<Window>> { let index = get_array_index_from_id(cx, id); if let Some(index) = index { - let target = GetProxyPrivate(proxy).to_object(); - let win: Root<Window> = native_from_reflector_jsmanaged(target).unwrap().root(); + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); + let win: Root<Window> = native_from_handleobject(target.handle()).unwrap(); let mut found = false; return win.r().IndexedGetter(index, &mut found); } @@ -118,132 +115,133 @@ unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: *mut JSObject, id: jsid) } #[allow(unsafe_code)] -unsafe extern fn getOwnPropertyDescriptor(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, - set: bool, desc: *mut JSPropertyDescriptor) -> bool { +unsafe extern fn getOwnPropertyDescriptor(cx: *mut JSContext, proxy: HandleObject, id: HandleId, + desc: MutableHandle<JSPropertyDescriptor>) -> u8 { let window = GetSubframeWindow(cx, proxy, id); if let Some(window) = window { - let window = window.root(); - (*desc).value = window.to_jsval(cx); - fill_property_descriptor(&mut *desc, proxy, true); - return true; + let mut val = RootedValue::new(cx, UndefinedValue()); + window.to_jsval(cx, val.handle_mut()); + (*desc.ptr).value = val.ptr; + fill_property_descriptor(&mut *desc.ptr, *proxy.ptr, true); + return JSTrue; } - let target = GetProxyPrivate(proxy).to_object(); - let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED; + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); // XXX This should be JS_GetOwnPropertyDescriptorById - if JS_GetPropertyDescriptorById(cx, target, id, flags, desc) == 0 { - return false; + if JS_GetPropertyDescriptorById(cx, target.handle(), id, desc) == 0 { + return JSFalse; } - if (*desc).obj != target { + if (*desc.ptr).obj != target.ptr { // Not an own property - (*desc).obj = ptr::null_mut(); + (*desc.ptr).obj = ptr::null_mut(); } else { - (*desc).obj = proxy; + (*desc.ptr).obj = *proxy.ptr; } - true + JSTrue } #[allow(unsafe_code)] -unsafe extern fn defineProperty(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, - desc: *mut JSPropertyDescriptor) -> bool { +unsafe extern fn defineProperty(cx: *mut JSContext, + proxy: HandleObject, + id: HandleId, + desc: Handle<JSPropertyDescriptor>, + res: *mut ObjectOpResult) -> u8 { if get_array_index_from_id(cx, id).is_some() { // Spec says to Reject whether this is a supported index or not, // since we have no indexed setter or indexed creator. That means // throwing in strict mode (FIXME: Bug 828137), doing nothing in // non-strict mode. - return true; + (*res).code_ = JSErrNum::JSMSG_CANT_DEFINE_WINDOW_ELEMENT as u32; + return JSTrue; } - let target = GetProxyPrivate(proxy).to_object(); - JS_DefinePropertyById(cx, target, id, (*desc).value, (*desc).getter, - (*desc).setter, (*desc).attrs) != 0 + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); + JS_DefinePropertyById6(cx, target.handle(), id, desc, res) } #[allow(unsafe_code)] -unsafe extern fn hasOwn(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, bp: *mut bool) -> bool { +unsafe extern fn hasOwn(cx: *mut JSContext, proxy: HandleObject, id: HandleId, bp: *mut u8) -> u8 { let window = GetSubframeWindow(cx, proxy, id); if window.is_some() { - *bp = true; - return true; + *bp = JSTrue; + return JSTrue; } - let target = GetProxyPrivate(proxy).to_object(); + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); let mut found = 0; - if JS_AlreadyHasOwnPropertyById(cx, target, id, &mut found) == 0 { - return false; + if JS_AlreadyHasOwnPropertyById(cx, target.handle(), id, &mut found) == 0 { + return JSFalse; } - *bp = found != 0; - return true; + *bp = (found != 0) as u8; + return JSTrue; } #[allow(unsafe_code)] -unsafe extern fn get(cx: *mut JSContext, proxy: *mut JSObject, receiver: *mut JSObject, id: jsid, - vp: *mut JSVal) -> bool { +unsafe extern fn get(cx: *mut JSContext, + proxy: HandleObject, + receiver: HandleObject, + id: HandleId, + vp: MutableHandleValue) -> u8 { let window = GetSubframeWindow(cx, proxy, id); if let Some(window) = window { - let window = window.root(); - *vp = window.to_jsval(cx); - return true; + window.to_jsval(cx, vp); + return JSTrue; } - let target = GetProxyPrivate(proxy).to_object(); - JS_ForwardGetPropertyTo(cx, target, id, receiver, vp) != 0 + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); + JS_ForwardGetPropertyTo(cx, target.handle(), id, receiver, vp) } #[allow(unsafe_code)] -unsafe extern fn set(cx: *mut JSContext, proxy: *mut JSObject, _receiver: *mut JSObject, - id: jsid, _strict: bool, vp: *mut JSVal) -> bool { +unsafe extern fn set(cx: *mut JSContext, + proxy: HandleObject, + receiver: HandleObject, + id: HandleId, + vp: MutableHandleValue, + res: *mut ObjectOpResult) -> u8 { if get_array_index_from_id(cx, id).is_some() { // Reject (which means throw if and only if strict) the set. - // FIXME: Throw - return true; + (*res).code_ = JSErrNum::JSMSG_READ_ONLY as u32; + return JSTrue; } - // FIXME: The receiver should be used, we need something like JS_ForwardSetPropertyTo. - let target = GetProxyPrivate(proxy).to_object(); - JS_SetPropertyById(cx, target, id, vp) != 0 + let target = RootedObject::new(cx, GetProxyPrivate(*proxy.ptr).to_object()); + let receiver = RootedValue::new(cx, ObjectValue(&**receiver.ptr)); + JS_ForwardSetPropertyTo(cx, target.handle(), id, HandleValue { ptr: vp.ptr }, receiver.handle(), res) } static PROXY_HANDLER: ProxyTraps = ProxyTraps { - getPropertyDescriptor: Some(get_property_descriptor - as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, - *mut JSPropertyDescriptor) -> bool), - getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor - as unsafe extern "C" fn(*mut JSContext, *mut JSObject, - jsid, bool, *mut JSPropertyDescriptor) - -> bool), - defineProperty: Some(defineProperty as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, - *mut JSPropertyDescriptor) -> bool), - getOwnPropertyNames: None, + enter: None, + getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), + defineProperty: Some(defineProperty), + ownPropertyKeys: None, delete_: None, enumerate: None, - + preventExtensions: None, + isExtensible: None, has: None, - hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool), - get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool), - set: Some(set as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, - jsid, bool, *mut JSVal) -> bool), - keys: None, - iterate: None, - + get: Some(get), + set: Some(set), call: None, construct: None, - nativeCall: 0 as *const u8, + getPropertyDescriptor: Some(get_property_descriptor), + hasOwn: Some(hasOwn), + getOwnEnumerablePropertyKeys: None, + nativeCall: None, hasInstance: None, - typeOf: None, objectClassIs: None, - obj_toString: None, + className: None, fun_toString: None, - //regexp_toShared: 0 as *u8, + boxedValue_unbox: None, defaultValue: None, - iteratorNext: None, + trace: None, finalize: None, - getElementIfPresent: None, - getPrototypeOf: None, - trace: None + objectMoved: None, + isCallable: None, + isConstructor: None, }; #[allow(unsafe_code)] diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index eae2a08da65..ae2db347264 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -8,7 +8,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CanvasGradientBinding; use dom::bindings::codegen::Bindings::CanvasGradientBinding::CanvasGradientMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::canvasrenderingcontext2d::parse_color; @@ -37,13 +37,13 @@ impl CanvasGradient { } } - pub fn new(global: GlobalRef, style: CanvasGradientStyle) -> Temporary<CanvasGradient> { + pub fn new(global: GlobalRef, style: CanvasGradientStyle) -> Root<CanvasGradient> { reflect_dom_object(box CanvasGradient::new_inherited(style), global, CanvasGradientBinding::Wrap) } } -impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> { +impl<'a> CanvasGradientMethods for &'a CanvasGradient { // https://html.spec.whatwg.org/multipage/#dom-canvasgradient-addcolorstop fn AddColorStop(self, offset: Finite<f64>, color: String) { let default_black = RGBA { @@ -61,11 +61,11 @@ impl<'a> CanvasGradientMethods for JSRef<'a, CanvasGradient> { } pub trait ToFillOrStrokeStyle { - fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle; + fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle; } -impl<'a> ToFillOrStrokeStyle for JSRef<'a, CanvasGradient> { - fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle { +impl<'a> ToFillOrStrokeStyle for &'a CanvasGradient { + fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle { let gradient_stops = self.stops.borrow().clone(); match self.style { CanvasGradientStyle::Linear(ref gradient) => { diff --git a/components/script/dom/canvaspattern.rs b/components/script/dom/canvaspattern.rs index b97ba6bb76e..25293e526f0 100644 --- a/components/script/dom/canvaspattern.rs +++ b/components/script/dom/canvaspattern.rs @@ -5,7 +5,7 @@ use canvas_traits::{FillOrStrokeStyle, SurfaceStyle, RepetitionStyle}; use dom::bindings::codegen::Bindings::CanvasPatternBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::canvasgradient::ToFillOrStrokeStyle; use euclid::size::Size2D; @@ -41,14 +41,14 @@ impl CanvasPattern { surface_data: Vec<u8>, surface_size: Size2D<i32>, repeat: RepetitionStyle) - -> Temporary<CanvasPattern> { + -> Root<CanvasPattern> { reflect_dom_object(box CanvasPattern::new_inherited(surface_data, surface_size, repeat), global, CanvasPatternBinding::Wrap) } } -impl<'a> ToFillOrStrokeStyle for JSRef<'a, CanvasPattern> { - fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle { +impl<'a> ToFillOrStrokeStyle for &'a CanvasPattern { + fn to_fill_or_stroke_style(self) -> FillOrStrokeStyle { FillOrStrokeStyle::Surface( SurfaceStyle::new(self.surface_data.clone(), self.surface_size, self.repeat_x, self.repeat_y)) } diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 06330b48889..c92c9fcdf29 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -12,7 +12,7 @@ use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern; use dom::bindings::error::Error::{IndexSize, NotSupported, Type, InvalidState, Syntax}; use dom::bindings::error::Fallible; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary, Unrooted}; +use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::num::Finite; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle}; @@ -115,20 +115,20 @@ impl CanvasContextState { } impl CanvasRenderingContext2D { - fn new_inherited(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>) + fn new_inherited(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>) -> CanvasRenderingContext2D { CanvasRenderingContext2D { reflector_: Reflector::new(), global: GlobalField::from_rooted(&global), renderer: CanvasPaintTask::start(size), - canvas: JS::from_rooted(canvas), + canvas: JS::from_ref(canvas), state: RefCell::new(CanvasContextState::new()), saved_states: RefCell::new(Vec::new()), } } - pub fn new(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>) - -> Temporary<CanvasRenderingContext2D> { + pub fn new(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>) + -> Root<CanvasRenderingContext2D> { reflect_dom_object(box CanvasRenderingContext2D::new_inherited(global, canvas, size), global, CanvasRenderingContext2DBinding::Wrap) } @@ -211,7 +211,7 @@ impl CanvasRenderingContext2D { // // https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage fn draw_html_canvas_element(&self, - canvas: JSRef<HTMLCanvasElement>, + canvas: &HTMLCanvasElement, sx: f64, sy: f64, sw: f64, sh: f64, dx: f64, dy: f64, dw: f64, dh: f64) -> Fallible<()> { // 1. Check the usability of the image argument @@ -235,7 +235,7 @@ impl CanvasRenderingContext2D { CanvasMsg::Canvas2d(Canvas2dMsg::DrawImageSelf(image_size, dest_rect, source_rect, smoothing_enabled)) } else { // Source and target canvases are different let context = match canvas.get_or_init_2d_context() { - Some(context) => context.root(), + Some(context) => context, None => return Err(InvalidState), }; @@ -275,7 +275,7 @@ impl CanvasRenderingContext2D { } fn fetch_image_data(&self, - image_element: &JSRef<HTMLImageElement>) + image_element: &&HTMLImageElement) -> Option<(Vec<u8>, Size2D<f64>)> { let url = match image_element.get_url() { Some(url) => url, @@ -302,7 +302,7 @@ impl CanvasRenderingContext2D { fn request_image_from_cache(&self, url: Url) -> ImageResponse { let canvas = self.canvas.root(); - let window = window_from_node(canvas.r()).root(); + let window = window_from_node(canvas.r()); let window = window.r(); let image_cache = window.image_cache_task(); let (response_chan, response_port) = channel(); @@ -325,11 +325,11 @@ impl CanvasRenderingContext2D { } pub trait CanvasRenderingContext2DHelpers { - fn get_renderer(&self) -> Sender<CanvasMsg>; + fn get_renderer(self) -> Sender<CanvasMsg>; } -impl CanvasRenderingContext2DHelpers for CanvasRenderingContext2D { - fn get_renderer(&self) -> Sender<CanvasMsg> { +impl<'a> CanvasRenderingContext2DHelpers for &'a CanvasRenderingContext2D { + fn get_renderer(self) -> Sender<CanvasMsg> { self.renderer.clone() } } @@ -355,10 +355,10 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D // Restricted values are guarded in glue code. Therefore we need not add a guard. // // FIXME: this behavior should might be generated by some annotattions to idl. -impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> { +impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D { // https://html.spec.whatwg.org/multipage/#dom-context-2d-canvas - fn Canvas(self) -> Temporary<HTMLCanvasElement> { - Temporary::from_rooted(self.canvas) + fn Canvas(self) -> Root<HTMLCanvasElement> { + self.canvas.root() } // https://html.spec.whatwg.org/multipage/#dom-context-2d-save @@ -552,8 +552,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> let sy: f64 = 0f64; match image { - HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => { - let canvas = image.root(); + HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(canvas) => { let canvas_size = canvas.r().get_size(); let dw: f64 = canvas_size.width as f64; let dh: f64 = canvas_size.height as f64; @@ -564,9 +563,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => { - let image = image.root(); let context = image.r(); - let canvas = context.Canvas().root(); + let canvas = context.Canvas(); let canvas_size = canvas.r().get_size(); let dw: f64 = canvas_size.width as f64; let dh: f64 = canvas_size.height as f64; @@ -577,7 +575,6 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => { - let image = image.root(); let image_element = image.r(); // https://html.spec.whatwg.org/multipage/#img-error // If the image argument is an HTMLImageElement object that is in the broken state, @@ -615,8 +612,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> let sy: f64 = 0f64; match image { - HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => { - let canvas = image.root(); + HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(canvas) => { let canvas_size = canvas.r().get_size(); let sw: f64 = canvas_size.width as f64; let sh: f64 = canvas_size.height as f64; @@ -625,9 +621,8 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => { - let image = image.root(); let context = image.r(); - let canvas = context.Canvas().root(); + let canvas = context.Canvas(); let canvas_size = canvas.r().get_size(); let sw: f64 = canvas_size.width as f64; let sh: f64 = canvas_size.height as f64; @@ -636,7 +631,6 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => { - let image = image.root(); let image_element = image.r(); // https://html.spec.whatwg.org/multipage/#img-error // If the image argument is an HTMLImageElement object that is in the broken state, @@ -666,21 +660,18 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> match image { HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLCanvasElement(image) => { - let canvas = image.root(); - return self.draw_html_canvas_element(canvas.r(), + return self.draw_html_canvas_element(image.r(), sx, sy, sw, sh, dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eCanvasRenderingContext2D(image) => { - let image = image.root(); let context = image.r(); - let canvas = context.Canvas().root(); + let canvas = context.Canvas(); return self.draw_html_canvas_element(canvas.r(), sx, sy, sw, sh, dx, dy, dw, dh) } HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => { - let image = image.root(); let image_element = image.r(); // https://html.spec.whatwg.org/multipage/#img-error // If the image argument is an HTMLImageElement object that is in the broken state, @@ -820,7 +811,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> StringOrCanvasGradientOrCanvasPattern::eString(result) }, CanvasFillOrStrokeStyle::Gradient(gradient) => { - StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(Unrooted::from_js(gradient)) + StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root()) }, } } @@ -840,11 +831,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> } }, StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => { - let gradient_root = gradient.root(); self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Gradient( - JS::from_rooted(gradient_root.r())); + JS::from_ref(gradient.r())); let msg = CanvasMsg::Canvas2d( - Canvas2dMsg::SetStrokeStyle(gradient_root.r().to_fill_or_stroke_style())); + Canvas2dMsg::SetStrokeStyle(gradient.r().to_fill_or_stroke_style())); self.renderer.send(msg).unwrap(); }, _ => {} @@ -860,7 +850,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> StringOrCanvasGradientOrCanvasPattern::eString(result) }, CanvasFillOrStrokeStyle::Gradient(gradient) => { - StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(Unrooted::from_js(gradient)) + StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root()) }, } } @@ -880,22 +870,21 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> } } StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient) => { - let gradient_root = gradient.root(); self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Gradient( - JS::from_rooted(gradient_root.r())); + JS::from_rooted(&gradient)); let msg = CanvasMsg::Canvas2d( - Canvas2dMsg::SetFillStyle(gradient_root.r().to_fill_or_stroke_style())); + Canvas2dMsg::SetFillStyle(gradient.r().to_fill_or_stroke_style())); self.renderer.send(msg).unwrap(); } StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => { self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle( - pattern.root().r().to_fill_or_stroke_style()))).unwrap(); + pattern.r().to_fill_or_stroke_style()))).unwrap(); } } } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata - fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Temporary<ImageData>> { + fn CreateImageData(self, sw: f64, sh: f64) -> Fallible<Root<ImageData>> { if !(sw.is_finite() && sh.is_finite()) { return Err(NotSupported); } @@ -908,7 +897,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> } // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata - fn CreateImageData_(self, imagedata: JSRef<ImageData>) -> Fallible<Temporary<ImageData>> { + fn CreateImageData_(self, imagedata: &ImageData) -> Fallible<Root<ImageData>> { Ok(ImageData::new(self.global.root().r(), imagedata.Width(), imagedata.Height(), None)) } @@ -917,7 +906,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> sx: Finite<f64>, sy: Finite<f64>, sw: Finite<f64>, - sh: Finite<f64>) -> Fallible<Temporary<ImageData>> { + sh: Finite<f64>) -> Fallible<Root<ImageData>> { let sx = *sx; let sy = *sy; let sw = *sw; @@ -938,7 +927,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> } // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata - fn PutImageData(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>) { + fn PutImageData(self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>) { let dx = *dx; let dy = *dy; @@ -960,7 +949,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> } // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata - fn PutImageData_(self, imagedata: JSRef<ImageData>, dx: Finite<f64>, dy: Finite<f64>, + fn PutImageData_(self, imagedata: &ImageData, dx: Finite<f64>, dy: Finite<f64>, dirtyX: Finite<f64>, dirtyY: Finite<f64>, dirtyWidth: Finite<f64>, dirtyHeight: Finite<f64>) { let dx = *dx; let dy = *dy; @@ -989,7 +978,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient fn CreateLinearGradient(self, x0: Finite<f64>, y0: Finite<f64>, - x1: Finite<f64>, y1: Finite<f64>) -> Fallible<Temporary<CanvasGradient>> { + x1: Finite<f64>, y1: Finite<f64>) -> Fallible<Root<CanvasGradient>> { let x0 = *x0; let y0 = *y0; let x1 = *x1; @@ -1006,7 +995,7 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> // https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient fn CreateRadialGradient(self, x0: Finite<f64>, y0: Finite<f64>, r0: Finite<f64>, x1: Finite<f64>, y1: Finite<f64>, r1: Finite<f64>) - -> Fallible<Temporary<CanvasGradient>> { + -> Fallible<Root<CanvasGradient>> { let x0 = *x0; let y0 = *y0; let r0 = *r0; @@ -1025,10 +1014,9 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D> // https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern fn CreatePattern(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D, - repetition: DOMString) -> Fallible<Temporary<CanvasPattern>> { + repetition: DOMString) -> Fallible<Root<CanvasPattern>> { match image { HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => { - let image = image.root(); let image_element = image.r(); let url = match image_element.get_url() { diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 017bc79f5a2..48c13b02ab4 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -11,7 +11,7 @@ use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::error::Error::IndexSize; -use dom::bindings::js::{JSRef, LayoutJS, Temporary}; +use dom::bindings::js::{LayoutJS, Root}; use dom::document::Document; use dom::element::Element; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -39,7 +39,7 @@ impl CharacterDataDerived for EventTarget { } impl CharacterData { - pub fn new_inherited(id: CharacterDataTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData { + pub fn new_inherited(id: CharacterDataTypeId, data: DOMString, document: &Document) -> CharacterData { CharacterData { node: Node::new_inherited(NodeTypeId::CharacterData(id), document), data: DOMRefCell::new(data), @@ -47,7 +47,7 @@ impl CharacterData { } } -impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { +impl<'a> CharacterDataMethods for &'a CharacterData { // https://dom.spec.whatwg.org/#dom-characterdata-data fn Data(self) -> DOMString { // FIXME(https://github.com/rust-lang/rust/issues/23338) @@ -136,20 +136,20 @@ impl<'a> CharacterDataMethods for JSRef<'a, CharacterData> { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(self) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.remove_self(); } // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling - fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> { + fn GetPreviousElementSibling(self) -> Option<Root<Element>> { NodeCast::from_ref(self).preceding_siblings() - .filter_map(ElementCast::to_temporary).next() + .filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling - fn GetNextElementSibling(self) -> Option<Temporary<Element>> { + fn GetNextElementSibling(self) -> Option<Root<Element>> { NodeCast::from_ref(self).following_siblings() - .filter_map(ElementCast::to_temporary).next() + .filter_map(ElementCast::to_root).next() } } @@ -166,10 +166,10 @@ pub trait CharacterDataHelpers<'a> { fn data(self) -> Ref<'a, DOMString>; } -impl<'a> CharacterDataHelpers<'a> for JSRef<'a, CharacterData> { +impl<'a> CharacterDataHelpers<'a> for &'a CharacterData { #[inline] fn data(self) -> Ref<'a, DOMString> { - self.extended_deref().data.borrow() + self.data.borrow() } } diff --git a/components/script/dom/closeevent.rs b/components/script/dom/closeevent.rs index 2d2e7d8e323..cedbd61703e 100644 --- a/components/script/dom/closeevent.rs +++ b/components/script/dom/closeevent.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::CloseEventBinding::CloseEventMethods; use dom::bindings::codegen::InheritTypes::EventCast; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary, Rootable}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable}; use script_task::ScriptChan; @@ -40,21 +40,23 @@ impl CloseEvent { cancelable: EventCancelable, wasClean: bool, code: u16, - reason: DOMString) -> Temporary<CloseEvent> { + reason: DOMString) -> Root<CloseEvent> { let event = box CloseEvent::new_inherited(EventTypeId::CloseEvent, wasClean, code, reason); - let ev = reflect_dom_object(event, global, CloseEventBinding::Wrap).root(); - let event: JSRef<Event> = EventCast::from_ref(ev.r()); - event.InitEvent(type_, - bubbles == EventBubbles::Bubbles, - cancelable == EventCancelable::Cancelable); - Temporary::from_rooted(ev.r()) + let ev = reflect_dom_object(event, global, CloseEventBinding::Wrap); + { + let event = EventCast::from_ref(ev.r()); + event.InitEvent(type_, + bubbles == EventBubbles::Bubbles, + cancelable == EventCancelable::Cancelable); + } + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, init: &CloseEventBinding::CloseEventInit) - -> Fallible<Temporary<CloseEvent>> { + -> Fallible<Root<CloseEvent>> { let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble }; let cancelable = if init.parent.cancelable { EventCancelable::Cancelable @@ -66,7 +68,7 @@ impl CloseEvent { } } -impl<'a> CloseEventMethods for JSRef<'a, CloseEvent> { +impl<'a> CloseEventMethods for &'a CloseEvent { fn WasClean(self) -> bool { self.wasClean } diff --git a/components/script/dom/comment.rs b/components/script/dom/comment.rs index b65384e9ddf..da617903806 100644 --- a/components/script/dom/comment.rs +++ b/components/script/dom/comment.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::CommentDerived; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::characterdata::{CharacterData, CharacterDataTypeId}; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -27,19 +27,19 @@ impl CommentDerived for EventTarget { } impl Comment { - fn new_inherited(text: DOMString, document: JSRef<Document>) -> Comment { + fn new_inherited(text: DOMString, document: &Document) -> Comment { Comment { characterdata: CharacterData::new_inherited(CharacterDataTypeId::Comment, text, document) } } - pub fn new(text: DOMString, document: JSRef<Document>) -> Temporary<Comment> { + pub fn new(text: DOMString, document: &Document) -> Root<Comment> { Node::reflect_node(box Comment::new_inherited(text, document), document, CommentBinding::Wrap) } - pub fn Constructor(global: GlobalRef, data: DOMString) -> Fallible<Temporary<Comment>> { - let document = global.as_window().Document().root(); + pub fn Constructor(global: GlobalRef, data: DOMString) -> Fallible<Root<Comment>> { + let document = global.as_window().Document(); Ok(Comment::new(data, document.r())) } } diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 45cd3e43f76..6f4c021796f 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::ConsoleBinding; use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::WindowHelpers; use devtools_traits::{DevtoolsControlMsg, ConsoleMessage, LogLevel}; @@ -26,12 +26,12 @@ impl Console { } } - pub fn new(global: GlobalRef) -> Temporary<Console> { + pub fn new(global: GlobalRef) -> Root<Console> { reflect_dom_object(box Console::new_inherited(global), global, ConsoleBinding::Wrap) } } -impl<'a> ConsoleMethods for JSRef<'a, Console> { +impl<'a> ConsoleMethods for &'a Console { // https://developer.mozilla.org/en-US/docs/Web/API/Console/log fn Log(self, messages: Vec<DOMString>) { for message in messages { @@ -95,7 +95,7 @@ fn prepare_message(logLevel: LogLevel, message: String) -> ConsoleMessage { } } -fn propagate_console_msg(console: &JSRef<Console>, console_message: ConsoleMessage) { +fn propagate_console_msg(console: &&Console, console_message: ConsoleMessage) { let global = console.global.root(); match global.r() { GlobalRef::Window(window_ref) => { diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 7e1f500627b..c460aa836ae 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::InheritTypes::ElementCast; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::Element; use dom::element::ElementCreator; @@ -81,8 +81,8 @@ use string_cache::{Atom, QualName}; use std::borrow::ToOwned; pub fn create_element(name: QualName, prefix: Option<Atom>, - document: JSRef<Document>, creator: ElementCreator) - -> Temporary<Element> { + document: &Document, creator: ElementCreator) + -> Root<Element> { let prefix = prefix.map(|p| (*p).to_owned()); if name.ns != ns!(HTML) { @@ -92,11 +92,11 @@ pub fn create_element(name: QualName, prefix: Option<Atom>, macro_rules! make( ($ctor:ident) => ({ let obj = $ctor::new((*name.local).to_owned(), prefix, document); - ElementCast::from_temporary(obj) + ElementCast::from_root(obj) }); ($ctor:ident, $($arg:expr),+) => ({ let obj = $ctor::new((*name.local).to_owned(), prefix, document, $($arg),+); - ElementCast::from_temporary(obj) + ElementCast::from_root(obj) }) ); diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 1e0b13b2ee3..5251c889ff0 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -6,12 +6,12 @@ use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::{self, CSSStyl use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::DocumentHelpers; -use dom::element::{Element, ElementHelpers, StylePriority}; +use dom::element::{ElementHelpers, StylePriority}; use dom::htmlelement::HTMLElement; -use dom::node::{window_from_node, document_from_node, NodeDamage, Node}; +use dom::node::{window_from_node, document_from_node, NodeDamage}; use dom::window::{Window, WindowHelpers}; use util::str::DOMString; use string_cache::Atom; @@ -55,17 +55,17 @@ fn serialize_list(list: &Vec<PropertyDeclaration>) -> DOMString { } impl CSSStyleDeclaration { - pub fn new_inherited(owner: JSRef<HTMLElement>, + pub fn new_inherited(owner: &HTMLElement, modification_access: CSSModificationAccess) -> CSSStyleDeclaration { CSSStyleDeclaration { reflector_: Reflector::new(), - owner: JS::from_rooted(owner), + owner: JS::from_ref(owner), readonly: modification_access == CSSModificationAccess::Readonly, } } - pub fn new(global: JSRef<Window>, owner: JSRef<HTMLElement>, - modification_access: CSSModificationAccess) -> Temporary<CSSStyleDeclaration> { + pub fn new(global: &Window, owner: &HTMLElement, + modification_access: CSSModificationAccess) -> Root<CSSStyleDeclaration> { reflect_dom_object(box CSSStyleDeclaration::new_inherited(owner, modification_access), GlobalRef::Window(global), CSSStyleDeclarationBinding::Wrap) @@ -77,25 +77,25 @@ trait PrivateCSSStyleDeclarationHelpers { fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration>; } -impl<'a> PrivateCSSStyleDeclarationHelpers for JSRef<'a, CSSStyleDeclaration> { +impl<'a> PrivateCSSStyleDeclarationHelpers for &'a CSSStyleDeclaration { fn get_declaration(self, property: &Atom) -> Option<PropertyDeclaration> { let owner = self.owner.root(); - let element: JSRef<Element> = ElementCast::from_ref(owner.r()); + let element = ElementCast::from_ref(owner.r()); element.get_inline_style_declaration(property).map(|decl| decl.clone()) } fn get_important_declaration(self, property: &Atom) -> Option<PropertyDeclaration> { let owner = self.owner.root(); - let element: JSRef<Element> = ElementCast::from_ref(owner.r()); + let element = ElementCast::from_ref(owner.r()); element.get_important_inline_style_declaration(property).map(|decl| decl.clone()) } } -impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { +impl<'a> CSSStyleDeclarationMethods for &'a CSSStyleDeclaration { // http://dev.w3.org/csswg/cssom/#dom-cssstyledeclaration-length fn Length(self) -> u32 { let owner = self.owner.root(); - let elem: JSRef<Element> = ElementCast::from_ref(owner.r()); + let elem = ElementCast::from_ref(owner.r()); let len = match *elem.style_attribute().borrow() { Some(ref declarations) => declarations.normal.len() + declarations.important.len(), None => 0 @@ -107,7 +107,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { fn Item(self, index: u32) -> DOMString { let index = index as usize; let owner = self.owner.root(); - let elem: JSRef<Element> = ElementCast::from_ref(owner.r()); + let elem = ElementCast::from_ref(owner.r()); let style_attribute = elem.style_attribute().borrow(); let result = style_attribute.as_ref().and_then(|declarations| { if index > declarations.normal.len() { @@ -216,7 +216,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { synthesized_declaration.push_str(&value); let owner = self.owner.root(); - let window = window_from_node(owner.r()).root(); + let window = window_from_node(owner.r()); let decl_block = parse_style_attribute(&synthesized_declaration, &window.r().get_url()); // Step 7 @@ -225,7 +225,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } let owner = self.owner.root(); - let element: JSRef<Element> = ElementCast::from_ref(owner.r()); + let element = ElementCast::from_ref(owner.r()); // Step 8 for decl in decl_block.normal.iter() { @@ -238,8 +238,8 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { element.update_inline_style(decl.clone(), style_priority); } - let document = document_from_node(element).root(); - let node: JSRef<Node> = NodeCast::from_ref(element); + let document = document_from_node(element); + let node = NodeCast::from_ref(element); document.r().content_changed(node, NodeDamage::NodeStyleDamaged); Ok(()) } @@ -266,9 +266,9 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { } let owner = self.owner.root(); - let window = window_from_node(owner.r()).root(); + let window = window_from_node(owner.r()); let decl_block = parse_style_attribute(&property, &window.r().get_url()); - let element: JSRef<Element> = ElementCast::from_ref(owner.r()); + let element = ElementCast::from_ref(owner.r()); // Step 5 for decl in decl_block.normal.iter() { @@ -281,8 +281,8 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { element.update_inline_style(decl.clone(), style_priority); } - let document = document_from_node(element).root(); - let node: JSRef<Node> = NodeCast::from_ref(element); + let document = document_from_node(element); + let node = NodeCast::from_ref(element); document.r().content_changed(node, NodeDamage::NodeStyleDamaged); Ok(()) } @@ -317,7 +317,7 @@ impl<'a> CSSStyleDeclarationMethods for JSRef<'a, CSSStyleDeclaration> { None => { // Step 5 let owner = self.owner.root(); - let elem: JSRef<Element> = ElementCast::from_ref(owner.r()); + let elem = ElementCast::from_ref(owner.r()); elem.remove_inline_style_property(property) } } diff --git a/components/script/dom/customevent.rs b/components/script/dom/customevent.rs index 5aa761d6846..303eebb8ca5 100644 --- a/components/script/dom/customevent.rs +++ b/components/script/dom/customevent.rs @@ -8,18 +8,18 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, CustomEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, MutHeap, Rootable, Temporary}; +use dom::bindings::js::{Root, MutHeapJSVal}; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId}; -use js::jsapi::JSContext; -use js::jsval::{JSVal, NullValue}; +use js::jsapi::{JSContext, HandleValue}; +use js::jsval::JSVal; use util::str::DOMString; // https://dom.spec.whatwg.org/#interface-customevent #[dom_struct] pub struct CustomEvent { event: Event, - detail: MutHeap<JSVal>, + detail: MutHeapJSVal, } impl CustomEventDerived for Event { @@ -32,11 +32,11 @@ impl CustomEvent { fn new_inherited(type_id: EventTypeId) -> CustomEvent { CustomEvent { event: Event::new_inherited(type_id), - detail: MutHeap::new(NullValue()), + detail: MutHeapJSVal::new(), } } - pub fn new_uninitialized(global: GlobalRef) -> Temporary<CustomEvent> { + pub fn new_uninitialized(global: GlobalRef) -> Root<CustomEvent> { reflect_dom_object(box CustomEvent::new_inherited(EventTypeId::CustomEvent), global, CustomEventBinding::Wrap) @@ -45,19 +45,23 @@ impl CustomEvent { type_: DOMString, bubbles: bool, cancelable: bool, - detail: JSVal) -> Temporary<CustomEvent> { - let ev = CustomEvent::new_uninitialized(global).root(); + detail: HandleValue) -> Root<CustomEvent> { + let ev = CustomEvent::new_uninitialized(global); ev.r().InitCustomEvent(global.get_cx(), type_, bubbles, cancelable, detail); - Temporary::from_rooted(ev.r()) + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &CustomEventBinding::CustomEventInit) -> Fallible<Temporary<CustomEvent>>{ - Ok(CustomEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable, init.detail)) + init: &CustomEventBinding::CustomEventInit) -> Fallible<Root<CustomEvent>>{ + Ok(CustomEvent::new(global, + type_, + init.parent.bubbles, + init.parent.cancelable, + HandleValue { ptr: &init.detail })) } } -impl<'a> CustomEventMethods for JSRef<'a, CustomEvent> { +impl<'a> CustomEventMethods for &'a CustomEvent { // https://dom.spec.whatwg.org/#dom-customevent-detail fn Detail(self, _cx: *mut JSContext) -> JSVal { self.detail.get() @@ -69,13 +73,13 @@ impl<'a> CustomEventMethods for JSRef<'a, CustomEvent> { type_: DOMString, can_bubble: bool, cancelable: bool, - detail: JSVal) { - let event: JSRef<Event> = EventCast::from_ref(self); + detail: HandleValue) { + let event = EventCast::from_ref(self); if event.dispatching() { return; } - self.detail.set(detail); + self.detail.set(detail.get()); event.InitEvent(type_, can_bubble, cancelable); } } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index d4411a811fa..bc71b94144c 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -9,9 +9,9 @@ use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived; use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast}; -use dom::bindings::error::ErrorResult; +use dom::bindings::error::{ErrorResult, report_pending_exception}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, RootCollection, Rootable, Temporary}; +use dom::bindings::js::{RootCollection, Root}; use dom::bindings::refcounted::LiveDOMReferences; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::utils::Reflectable; @@ -33,8 +33,9 @@ use util::task::spawn_named; use util::task_state; use util::task_state::{SCRIPT, IN_WORKER}; -use js::jsapi::JSContext; -use js::jsval::JSVal; +use js::jsapi::{JSContext, RootedValue, HandleValue}; +use js::jsapi::{JSAutoRequest, JSAutoCompartment}; +use js::jsval::UndefinedValue; use js::rust::Runtime; use url::Url; @@ -69,12 +70,12 @@ impl ScriptChan for SendableWorkerScriptChan { /// object only lives as long as necessary (ie. while events are being executed), while /// providing a reference that can be cloned freely. struct AutoWorkerReset<'a> { - workerscope: JSRef<'a, DedicatedWorkerGlobalScope>, + workerscope: &'a DedicatedWorkerGlobalScope, old_worker: Option<TrustedWorkerAddress>, } impl<'a> AutoWorkerReset<'a> { - fn new(workerscope: JSRef<'a, DedicatedWorkerGlobalScope>, worker: TrustedWorkerAddress) -> AutoWorkerReset<'a> { + fn new(workerscope: &'a DedicatedWorkerGlobalScope, worker: TrustedWorkerAddress) -> AutoWorkerReset<'a> { let reset = AutoWorkerReset { workerscope: workerscope, old_worker: workerscope.worker.borrow().clone() @@ -132,7 +133,7 @@ impl DedicatedWorkerGlobalScope { parent_sender: Box<ScriptChan+Send>, own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>, receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>) - -> Temporary<DedicatedWorkerGlobalScope> { + -> Root<DedicatedWorkerGlobalScope> { let scope = box DedicatedWorkerGlobalScope::new_inherited( worker_url, id, devtools_chan, runtime.clone(), resource_task, parent_sender, own_sender, receiver); @@ -170,7 +171,7 @@ impl DedicatedWorkerGlobalScope { let runtime = Rc::new(ScriptTask::new_rt_and_cx()); let global = DedicatedWorkerGlobalScope::new( worker_url, id, devtools_chan, runtime.clone(), resource_task, - parent_sender, own_sender, receiver).root(); + parent_sender, own_sender, receiver); { let _ar = AutoWorkerReset::new(global.r(), worker); @@ -178,7 +179,13 @@ impl DedicatedWorkerGlobalScope { match runtime.evaluate_script( global.r().reflector().get_jsobject(), source, url.serialize(), 1) { Ok(_) => (), - Err(_) => println!("evaluate_script failed") + Err(_) => { + // TODO: An error needs to be dispatched to the parent. + // https://github.com/servo/servo/issues/6422 + println!("evaluate_script failed"); + let _ar = JSAutoRequest::new(runtime.cx()); + report_pending_exception(runtime.cx(), global.r().reflector().get_jsobject().get()); + } } } @@ -202,7 +209,7 @@ pub trait DedicatedWorkerGlobalScopeHelpers { fn process_event(self, msg: ScriptMsg); } -impl<'a> DedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> { +impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope { fn script_chan(self) -> Box<ScriptChan+Send> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let worker = self.worker.borrow(); @@ -232,34 +239,37 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalSc trait PrivateDedicatedWorkerGlobalScopeHelpers { fn handle_event(self, msg: ScriptMsg); - fn dispatch_error_to_worker(self, JSRef<ErrorEvent>); + fn dispatch_error_to_worker(self, &ErrorEvent); } -impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> { +impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope { fn handle_event(self, msg: ScriptMsg) { match msg { ScriptMsg::DOMMessage(data) => { - let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); - let message = data.read(GlobalRef::Worker(scope)); - MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message); + let scope = WorkerGlobalScopeCast::from_ref(self); + let target = EventTargetCast::from_ref(self); + let _ar = JSAutoRequest::new(scope.get_cx()); + let _ac = JSAutoCompartment::new(scope.get_cx(), scope.reflector().get_jsobject().get()); + let mut message = RootedValue::new(scope.get_cx(), UndefinedValue()); + data.read(GlobalRef::Worker(scope), message.handle_mut()); + MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message.handle()); }, ScriptMsg::RunnableMsg(runnable) => { runnable.handler() }, ScriptMsg::RefcountCleanup(addr) => { - let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self); + let scope = WorkerGlobalScopeCast::from_ref(self); LiveDOMReferences::cleanup(scope.get_cx(), addr); } ScriptMsg::FireTimer(TimerSource::FromWorker, timer_id) => { - let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self); + let scope = WorkerGlobalScopeCast::from_ref(self); scope.handle_fire_timer(timer_id); } _ => panic!("Unexpected message"), } } - fn dispatch_error_to_worker(self, errorevent: JSRef<ErrorEvent>) { + fn dispatch_error_to_worker(self, errorevent: &ErrorEvent) { let msg = errorevent.Message(); let file_name = errorevent.Filename(); let line_num = errorevent.Lineno(); @@ -270,9 +280,9 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerG } } -impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> { +impl<'a> DedicatedWorkerGlobalScopeMethods for &'a DedicatedWorkerGlobalScope { // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage - fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult { + fn PostMessage(self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { let data = try!(StructuredCloneData::write(cx, message)); let worker = self.worker.borrow().as_ref().unwrap().clone(); self.parent_sender.send(ScriptMsg::RunnableMsg( diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f009e4d1cdc..57414705a14 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -22,19 +22,17 @@ use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLAppletE use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLEmbedElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, HTMLTitleElementDerived}; +use dom::bindings::codegen::InheritTypes::ElementDerived; use dom::bindings::codegen::UnionTypes::NodeOrString; -use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security}; use dom::bindings::error::Error::HierarchyRequest; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap}; -use dom::bindings::js::{OptionalRootable, Rootable, RootedReference}; -use dom::bindings::js::Temporary; -use dom::bindings::js::TemporaryPushable; +use dom::bindings::js::{JS, Root, LayoutJS, MutNullableHeap}; +use dom::bindings::js::RootedReference; use dom::bindings::refcounted::Trusted; use dom::bindings::trace::RootedVec; -use dom::bindings::utils::reflect_dom_object; +use dom::bindings::utils::{reflect_dom_object, Reflectable}; use dom::bindings::utils::{xml_name_type, validate_and_extract}; use dom::bindings::utils::XMLName::InvalidXMLName; use dom::comment::Comment; @@ -99,6 +97,7 @@ use std::cell::{Cell, Ref, RefMut, RefCell}; use std::default::Default; use std::ptr; use std::sync::mpsc::channel; +use std::rc::Rc; use time; #[derive(PartialEq)] @@ -153,6 +152,12 @@ pub struct Document { reflow_timeout: Cell<Option<u64>>, } +impl PartialEq for Document { + fn eq(&self, other: &Document) -> bool { + self as *const Document == &*other + } +} + impl DocumentDerived for EventTarget { fn is_document(&self) -> bool { *self.type_id() == EventTargetTypeId::Node(NodeTypeId::Document) @@ -162,7 +167,7 @@ impl DocumentDerived for EventTarget { #[jstraceable] struct ImagesFilter; impl CollectionFilter for ImagesFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlimageelement() } } @@ -170,7 +175,7 @@ impl CollectionFilter for ImagesFilter { #[jstraceable] struct EmbedsFilter; impl CollectionFilter for EmbedsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlembedelement() } } @@ -178,7 +183,7 @@ impl CollectionFilter for EmbedsFilter { #[jstraceable] struct LinksFilter; impl CollectionFilter for LinksFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { (elem.is_htmlanchorelement() || elem.is_htmlareaelement()) && elem.has_attribute(&atom!("href")) } @@ -187,7 +192,7 @@ impl CollectionFilter for LinksFilter { #[jstraceable] struct FormsFilter; impl CollectionFilter for FormsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlformelement() } } @@ -195,7 +200,7 @@ impl CollectionFilter for FormsFilter { #[jstraceable] struct ScriptsFilter; impl CollectionFilter for ScriptsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlscriptelement() } } @@ -203,7 +208,7 @@ impl CollectionFilter for ScriptsFilter { #[jstraceable] struct AnchorsFilter; impl CollectionFilter for AnchorsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlanchorelement() && elem.has_attribute(&atom!("href")) } } @@ -211,7 +216,7 @@ impl CollectionFilter for AnchorsFilter { #[jstraceable] struct AppletsFilter; impl CollectionFilter for AppletsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmlappletelement() } } @@ -219,7 +224,7 @@ impl CollectionFilter for AppletsFilter { pub trait DocumentHelpers<'a> { fn loader(&self) -> Ref<DocumentLoader>; fn mut_loader(&self) -> RefMut<DocumentLoader>; - fn window(self) -> Temporary<Window>; + fn window(self) -> Root<Window>; fn encoding_name(self) -> Ref<'a, DOMString>; fn is_html_document(self) -> bool; fn is_fully_active(self) -> bool; @@ -227,22 +232,22 @@ pub trait DocumentHelpers<'a> { fn quirks_mode(self) -> QuirksMode; fn set_quirks_mode(self, mode: QuirksMode); fn set_encoding_name(self, name: DOMString); - fn content_changed(self, node: JSRef<Node>, damage: NodeDamage); - fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage); + fn content_changed(self, node: &Node, damage: NodeDamage); + fn content_and_heritage_changed(self, node: &Node, damage: NodeDamage); fn reflow_if_reflow_timer_expired(self); fn set_reflow_timeout(self, timeout: u64); fn disarm_reflow_timeout(self); - fn unregister_named_element(self, to_unregister: JSRef<Element>, id: Atom); - fn register_named_element(self, element: JSRef<Element>, id: Atom); + fn unregister_named_element(self, to_unregister: &Element, id: Atom); + fn register_named_element(self, element: &Element, id: Atom); fn load_anchor_href(self, href: DOMString); - fn find_fragment_node(self, fragid: DOMString) -> Option<Temporary<Element>>; + fn find_fragment_node(self, fragid: DOMString) -> Option<Root<Element>>; fn hit_test(self, point: &Point2D<f32>) -> Option<UntrustedNodeAddress>; fn get_nodes_under_mouse(self, point: &Point2D<f32>) -> Vec<UntrustedNodeAddress>; fn set_ready_state(self, state: DocumentReadyState); - fn get_focused_element(self) -> Option<Temporary<Element>>; + fn get_focused_element(self) -> Option<Root<Element>>; fn is_scripting_enabled(self) -> bool; fn begin_focus_transaction(self); - fn request_focus(self, elem: JSRef<Element>); + fn request_focus(self, elem: &Element); fn commit_focus_transaction(self, focus_type: FocusType); fn title_changed(self); fn send_title_to_compositor(self); @@ -250,7 +255,7 @@ pub trait DocumentHelpers<'a> { fn dispatch_key_event(self, key: Key, state: KeyState, modifiers: KeyModifiers, compositor: &mut Box<ScriptListener+'static>); fn node_from_nodes_and_strings(self, nodes: Vec<NodeOrString>) - -> Fallible<Temporary<Node>>; + -> Fallible<Root<Node>>; fn get_body_attribute(self, local_name: &Atom) -> DOMString; fn set_body_attribute(self, local_name: &Atom, value: DOMString); @@ -263,7 +268,7 @@ pub trait DocumentHelpers<'a> { point: Point2D<f32>, prev_mouse_over_targets: &mut RootedVec<JS<Node>>); - fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>); + fn set_current_script(self, script: Option<&HTMLScriptElement>); fn trigger_mozbrowser_event(self, event: MozBrowserEvent); /// http://w3c.github.io/animation-timing/#dom-windowanimationtiming-requestanimationframe fn request_animation_frame(self, callback: Box<Fn(f64, )>) -> i32; @@ -275,11 +280,11 @@ pub trait DocumentHelpers<'a> { fn load_async(self, load: LoadType, listener: Box<AsyncResponseTarget + Send>); fn load_sync(self, load: LoadType) -> Result<(Metadata, Vec<u8>), String>; fn finish_load(self, load: LoadType); - fn set_current_parser(self, script: Option<JSRef<ServoHTMLParser>>); - fn get_current_parser(self) -> Option<Temporary<ServoHTMLParser>>; + fn set_current_parser(self, script: Option<&ServoHTMLParser>); + fn get_current_parser(self) -> Option<Root<ServoHTMLParser>>; } -impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { +impl<'a> DocumentHelpers<'a> for &'a Document { #[inline] fn loader(&self) -> Ref<DocumentLoader> { self.loader.borrow() @@ -291,13 +296,13 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } #[inline] - fn window(self) -> Temporary<Window> { - Temporary::from_rooted(self.window) + fn window(self) -> Root<Window> { + self.window.root() } #[inline] fn encoding_name(self) -> Ref<'a, DOMString> { - self.extended_deref().encoding_name.borrow() + self.encoding_name.borrow() } #[inline] @@ -311,7 +316,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let window = window.r(); let browser_context = window.browser_context(); let browser_context = browser_context.as_ref().unwrap(); - let active_document = browser_context.active_document().root(); + let active_document = browser_context.active_document(); if self != active_document.r() { return false; @@ -344,11 +349,11 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { *self.encoding_name.borrow_mut() = name; } - fn content_changed(self, node: JSRef<Node>, damage: NodeDamage) { + fn content_changed(self, node: &Node, damage: NodeDamage) { node.dirty(damage); } - fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage) { + fn content_and_heritage_changed(self, node: &Node, damage: NodeDamage) { node.force_dirty_ancestors(damage); node.dirty(damage); } @@ -387,7 +392,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// Remove any existing association between the provided id and any elements in this document. fn unregister_named_element(self, - to_unregister: JSRef<Element>, + to_unregister: &Element, id: Atom) { let mut idmap = self.idmap.borrow_mut(); let is_empty = match idmap.get_mut(&id) { @@ -408,10 +413,10 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// Associate an element present in this document with the provided id. fn register_named_element(self, - element: JSRef<Element>, + element: &Element, id: Atom) { assert!({ - let node: JSRef<Node> = NodeCast::from_ref(element); + let node = NodeCast::from_ref(element); node.is_in_doc() }); assert!(!id.is_empty()); @@ -419,20 +424,19 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let mut idmap = self.idmap.borrow_mut(); let root = self.GetDocumentElement().expect( - "The element is in the document, so there must be a document element.").root(); + "The element is in the document, so there must be a document element."); match idmap.entry(id) { Vacant(entry) => { - entry.insert(vec![JS::from_rooted(element)]); + entry.insert(vec![JS::from_ref(element)]); } Occupied(entry) => { let elements = entry.into_mut(); - let new_node: JSRef<Node> = NodeCast::from_ref(element); + let new_node = NodeCast::from_ref(element); let mut head: usize = 0; - let root: JSRef<Node> = NodeCast::from_ref(root.r()); + let root = NodeCast::from_ref(root.r()); for node in root.traverse_preorder() { - let node = node.root(); if let Some(elem) = ElementCast::to_ref(node.r()) { if (*elements)[head].root().r() == elem { head += 1; @@ -443,7 +447,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } } - elements.insert_unrooted(head, &element); + elements.insert(head, JS::from_ref(element)); } } } @@ -455,27 +459,27 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// Attempt to find a named element in this page's document. /// https://html.spec.whatwg.org/multipage/#the-indicated-part-of-the-document - fn find_fragment_node(self, fragid: DOMString) -> Option<Temporary<Element>> { + fn find_fragment_node(self, fragid: DOMString) -> Option<Root<Element>> { self.GetElementById(fragid.clone()).or_else(|| { - let check_anchor = |&node: &JSRef<HTMLAnchorElement>| { - let elem: JSRef<Element> = ElementCast::from_ref(node); - elem.get_attribute(&ns!(""), &atom!("name")).root().map_or(false, |attr| { + let check_anchor = |&node: &&HTMLAnchorElement| { + let elem = ElementCast::from_ref(node); + elem.get_attribute(&ns!(""), &atom!("name")).map_or(false, |attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); &**value == &*fragid }) }; - let doc_node: JSRef<Node> = NodeCast::from_ref(self); + let doc_node = NodeCast::from_ref(self); doc_node.traverse_preorder() - .filter_map(HTMLAnchorElementCast::to_temporary) - .find(|node| check_anchor(&node.root().r())) - .map(ElementCast::from_temporary) + .filter_map(HTMLAnchorElementCast::to_root) + .find(|node| check_anchor(&node.r())) + .map(ElementCast::from_root) }) } fn hit_test(self, point: &Point2D<f32>) -> Option<UntrustedNodeAddress> { - let root = self.GetDocumentElement().root(); + let root = self.GetDocumentElement(); let root = match root.r() { Some(root) => root, None => return None, @@ -493,12 +497,12 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } fn get_nodes_under_mouse(self, point: &Point2D<f32>) -> Vec<UntrustedNodeAddress> { - let root = self.GetDocumentElement().root(); + let root = self.GetDocumentElement(); let root = match root.r() { Some(root) => root, None => return vec!(), }; - let root: JSRef<Node> = NodeCast::from_ref(root); + let root = NodeCast::from_ref(root); let win = self.window.root(); match win.r().layout().mouse_over(root.to_trusted_node_address(), *point) { Ok(MouseOverResponse(node_address)) => node_address, @@ -513,8 +517,8 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let window = self.window.root(); let event = Event::new(GlobalRef::Window(window.r()), "readystatechange".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + EventCancelable::NotCancelable); + let target = EventTargetCast::from_ref(self); let _ = event.r().fire(target); } @@ -525,8 +529,8 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// Return the element that currently has focus. // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#events-focusevent-doc-focus - fn get_focused_element(self) -> Option<Temporary<Element>> { - self.focused.get().map(Temporary::from_rooted) + fn get_focused_element(self) -> Option<Root<Element>> { + self.focused.get().map(Root::from_rooted) } /// Initiate a new round of checking for elements requesting focus. The last element to call @@ -536,9 +540,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } /// Request that the given element receive focus once the current transaction is complete. - fn request_focus(self, elem: JSRef<Element>) { + fn request_focus(self, elem: &Element) { if elem.is_focusable_area() { - self.possibly_focused.set(Some(JS::from_rooted(elem))) + self.possibly_focused.set(Some(JS::from_ref(elem))) } } @@ -547,15 +551,15 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { fn commit_focus_transaction(self, focus_type: FocusType) { //TODO: dispatch blur, focus, focusout, and focusin events - if let Some(ref elem) = self.focused.get().root() { - let node: JSRef<Node> = NodeCast::from_ref(elem.r()); + if let Some(ref elem) = self.focused.get().map(|t| t.root()) { + let node = NodeCast::from_ref(elem.r()); node.set_focus_state(false); } self.focused.set(self.possibly_focused.get()); - if let Some(ref elem) = self.focused.get().root() { - let node: JSRef<Node> = NodeCast::from_ref(elem.r()); + if let Some(ref elem) = self.focused.get().map(|t| t.root()) { + let node = NodeCast::from_ref(elem.r()); node.set_focus_state(true); // Update the focus state for all elements in the focus chain. @@ -579,7 +583,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { /// Sends this document's title to the compositor. fn send_title_to_compositor(self) { - let window = self.window().root(); + let window = self.window(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let window = window.r(); let mut compositor = window.compositor(); @@ -587,9 +591,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } fn dirty_all_nodes(self) { - let root: JSRef<Node> = NodeCast::from_ref(self); + let root = NodeCast::from_ref(self); for node in root.traverse_preorder() { - node.root().r().dirty(NodeDamage::OtherNodeDamage) + node.r().dirty(NodeDamage::OtherNodeDamage) } } @@ -608,20 +612,20 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { node::from_untrusted_node_address(js_runtime, node_address) }, None => return, - }.root(); + }; let el = match ElementCast::to_ref(node.r()) { - Some(el) => Temporary::from_rooted(el), + Some(el) => Root::from_ref(el), None => { let parent = node.r().GetParentNode(); - match parent.and_then(ElementCast::to_temporary) { + match parent.and_then(ElementCast::to_root) { Some(parent) => parent, None => return, } }, - }.root(); + }; - let node: JSRef<Node> = NodeCast::from_ref(el.r()); + let node = NodeCast::from_ref(el.r()); debug!("{} on {:?}", mouse_event_type_string, node.debug_str()); // Prevent click event if form control element is disabled. if let MouseEventType::Click = mouse_event_type { @@ -646,16 +650,16 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { x, y, x, y, false, false, false, false, 0i16, - None).root(); - let event: JSRef<Event> = EventCast::from_ref(event.r()); + None); + let event = EventCast::from_ref(event.r()); // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#trusted-events event.set_trusted(true); // https://html.spec.whatwg.org/multipage/#run-authentic-click-activation-steps match mouse_event_type { - MouseEventType::Click => el.r().authentic_click_activation(event), + MouseEventType::Click => el.authentic_click_activation(event), _ => { - let target: JSRef<EventTarget> = EventTargetCast::from_ref(node); + let target = EventTargetCast::from_ref(node); event.fire(target); }, } @@ -675,11 +679,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { let mut mouse_over_targets: RootedVec<JS<Node>> = RootedVec::new(); for node_address in mouse_over_addresses.iter() { let node = node::from_untrusted_node_address(js_runtime, *node_address); - mouse_over_targets.push(node.root().r().inclusive_ancestors() - .map(|node| node.root()) - .find(|node| node.r() - .is_element()) - .map(|node| JS::from_rooted(node.r())).unwrap()); + mouse_over_targets.push(node.r().inclusive_ancestors() + .find(|node| node.r().is_element()) + .map(|node| JS::from_rooted(&node)).unwrap()); }; // Remove hover from any elements in the previous list that are no longer @@ -704,7 +706,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { // Send mousemove event to topmost target if mouse_over_addresses.len() > 0 { let top_most_node = - node::from_untrusted_node_address(js_runtime, mouse_over_addresses[0]).root(); + node::from_untrusted_node_address(js_runtime, mouse_over_addresses[0]); let x = point.x.to_i32().unwrap_or(0); let y = point.y.to_i32().unwrap_or(0); @@ -719,10 +721,10 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { x, y, x, y, false, false, false, false, 0i16, - None).root(); + None); - let event: JSRef<Event> = EventCast::from_ref(mouse_event.r()); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(top_most_node.r()); + let event = EventCast::from_ref(mouse_event.r()); + let target = EventTargetCast::from_ref(top_most_node.r()); event.fire(target); } @@ -742,10 +744,10 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { modifiers: KeyModifiers, compositor: &mut Box<ScriptListener+'static>) { let window = self.window.root(); - let focused = self.get_focused_element().root(); - let body = self.GetBody().root(); + let focused = self.get_focused_element(); + let body = self.GetBody(); - let target: JSRef<EventTarget> = match (&focused, &body) { + let target = match (&focused, &body) { (&Some(ref focused), _) => EventTargetCast::from_ref(focused.r()), (&None, &Some(ref body)) => EventTargetCast::from_ref(body.r()), (&None, &None) => EventTargetCast::from_ref(window.r()), @@ -770,7 +772,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { props.key_string.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, - None, props.key_code).root(); + None, props.key_code); let event = EventCast::from_ref(keyevent.r()); event.fire(target); let mut prevented = event.DefaultPrevented(); @@ -783,7 +785,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { props.key_string.to_owned(), props.code.to_owned(), props.location, is_repeating, is_composing, ctrl, alt, shift, meta, - props.char_code, 0).root(); + props.char_code, 0); let ev = EventCast::from_ref(event.r()); ev.fire(target); prevented = ev.DefaultPrevented(); @@ -801,12 +803,12 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27337 match key { Key::Space if !prevented && state == KeyState::Released => { - let maybe_elem: Option<JSRef<Element>> = ElementCast::to_ref(target); + let maybe_elem: Option<&Element> = ElementCast::to_ref(target); maybe_elem.map( |el| el.as_maybe_activatable().map(|a| a.synthetic_click_activation(ctrl, alt, shift, meta))); } Key::Enter if !prevented && state == KeyState::Released => { - let maybe_elem: Option<JSRef<Element>> = ElementCast::to_ref(target); + let maybe_elem: Option<&Element> = ElementCast::to_ref(target); maybe_elem.map(|el| el.as_maybe_activatable().map(|a| a.implicit_submission(ctrl, alt, shift, meta))); } _ => () @@ -816,35 +818,35 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } fn node_from_nodes_and_strings(self, nodes: Vec<NodeOrString>) - -> Fallible<Temporary<Node>> { + -> Fallible<Root<Node>> { if nodes.len() == 1 { match nodes.into_iter().next().unwrap() { - NodeOrString::eNode(node) => Ok(Temporary::from_unrooted(node)), + NodeOrString::eNode(node) => Ok(node), NodeOrString::eString(string) => { - Ok(NodeCast::from_temporary(self.CreateTextNode(string))) + Ok(NodeCast::from_root(self.CreateTextNode(string))) }, } } else { - let fragment = NodeCast::from_temporary(self.CreateDocumentFragment()).root(); + let fragment = NodeCast::from_root(self.CreateDocumentFragment()); for node in nodes.into_iter() { match node { NodeOrString::eNode(node) => { - try!(fragment.r().AppendChild(node.root().r())); + try!(fragment.r().AppendChild(node.r())); }, NodeOrString::eString(string) => { - let node = NodeCast::from_temporary(self.CreateTextNode(string)).root(); + let node = NodeCast::from_root(self.CreateTextNode(string)); // No try!() here because appending a text node // should not fail. fragment.r().AppendChild(node.r()).unwrap(); } } } - Ok(Temporary::from_rooted(fragment.r())) + Ok(fragment) } } fn get_body_attribute(self, local_name: &Atom) -> DOMString { - match self.GetBody().and_then(HTMLBodyElementCast::to_temporary).root() { + match self.GetBody().and_then(HTMLBodyElementCast::to_root) { Some(ref body) => { ElementCast::from_ref(body.r()).get_string_attribute(local_name) }, @@ -853,13 +855,13 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } fn set_body_attribute(self, local_name: &Atom, value: DOMString) { - if let Some(ref body) = self.GetBody().and_then(HTMLBodyElementCast::to_temporary).root() { + if let Some(ref body) = self.GetBody().and_then(HTMLBodyElementCast::to_root) { ElementCast::from_ref(body.r()).set_string_attribute(local_name, value); } } - fn set_current_script(self, script: Option<JSRef<HTMLScriptElement>>) { - self.current_script.set(script.map(JS::from_rooted)); + fn set_current_script(self, script: Option<&HTMLScriptElement>) { + self.current_script.set(script.map(JS::from_ref)); } fn trigger_mozbrowser_event(self, event: MozBrowserEvent) { @@ -923,7 +925,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { } let window = self.window.root(); let window = window.r(); - let performance = window.Performance().root(); + let performance = window.Performance(); let performance = performance.r(); for (_, callback) in animation_frame_list { @@ -951,12 +953,12 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> { loader.finish_load(load); } - fn set_current_parser(self, script: Option<JSRef<ServoHTMLParser>>) { - self.current_parser.set(script.map(JS::from_rooted)); + fn set_current_parser(self, script: Option<&ServoHTMLParser>) { + self.current_parser.set(script.map(JS::from_ref)); } - fn get_current_parser(self) -> Option<Temporary<ServoHTMLParser>> { - self.current_parser.get().map(Temporary::from_rooted) + fn get_current_parser(self) -> Option<Root<ServoHTMLParser>> { + self.current_parser.get().map(Root::from_rooted) } } @@ -988,7 +990,7 @@ impl LayoutDocumentHelpers for LayoutJS<Document> { } impl Document { - fn new_inherited(window: JSRef<Window>, + fn new_inherited(window: &Window, url: Option<Url>, is_html_document: IsHTMLDocument, content_type: Option<DOMString>, @@ -1005,7 +1007,7 @@ impl Document { Document { node: Node::new_without_doc(NodeTypeId::Document), - window: JS::from_rooted(window), + window: JS::from_ref(window), idmap: DOMRefCell::new(HashMap::new()), implementation: Default::default(), location: Default::default(), @@ -1046,9 +1048,9 @@ impl Document { } // https://dom.spec.whatwg.org/#dom-document - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<Document>> { + pub fn Constructor(global: GlobalRef) -> Fallible<Root<Document>> { let win = global.as_window(); - let doc = win.Document().root(); + let doc = win.Document(); let doc = doc.r(); let docloader = DocumentLoader::new(&*doc.loader()); Ok(Document::new(win, None, @@ -1056,55 +1058,55 @@ impl Document { None, DocumentSource::NotFromParser, docloader)) } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, url: Option<Url>, doctype: IsHTMLDocument, content_type: Option<DOMString>, last_modified: Option<DOMString>, source: DocumentSource, - doc_loader: DocumentLoader) -> Temporary<Document> { + doc_loader: DocumentLoader) -> Root<Document> { let document = reflect_dom_object(box Document::new_inherited(window, url, doctype, content_type, last_modified, source, doc_loader), GlobalRef::Window(window), - DocumentBinding::Wrap).root(); - - let node: JSRef<Node> = NodeCast::from_ref(document.r()); - node.set_owner_doc(document.r()); - Temporary::from_rooted(document.r()) + DocumentBinding::Wrap); + { + let node = NodeCast::from_ref(document.r()); + node.set_owner_doc(document.r()); + } + document } } trait PrivateDocumentHelpers { - fn create_node_list<F: Fn(JSRef<Node>) -> bool>(self, callback: F) -> Temporary<NodeList>; - fn get_html_element(self) -> Option<Temporary<HTMLHtmlElement>>; + fn create_node_list<F: Fn(&Node) -> bool>(self, callback: F) -> Root<NodeList>; + fn get_html_element(self) -> Option<Root<HTMLHtmlElement>>; } -impl<'a> PrivateDocumentHelpers for JSRef<'a, Document> { - fn create_node_list<F: Fn(JSRef<Node>) -> bool>(self, callback: F) -> Temporary<NodeList> { +impl<'a> PrivateDocumentHelpers for &'a Document { + fn create_node_list<F: Fn(&Node) -> bool>(self, callback: F) -> Root<NodeList> { let window = self.window.root(); - let doc = self.GetDocumentElement().root(); + let doc = self.GetDocumentElement(); let maybe_node = doc.r().map(NodeCast::from_ref); let iter = maybe_node.iter().flat_map(|node| node.traverse_preorder()) - .filter(|node| callback(node.root().r())); + .filter(|node| callback(node.r())); NodeList::new_simple_list(window.r(), iter) } - fn get_html_element(self) -> Option<Temporary<HTMLHtmlElement>> { + fn get_html_element(self) -> Option<Root<HTMLHtmlElement>> { self.GetDocumentElement() - .root() .r() .and_then(HTMLHtmlElementCast::to_ref) - .map(Temporary::from_rooted) + .map(Root::from_ref) } } trait PrivateClickEventHelpers { - fn click_event_filter_by_disabled_state(&self) -> bool; + fn click_event_filter_by_disabled_state(self) -> bool; } -impl<'a> PrivateClickEventHelpers for JSRef<'a, Node> { - fn click_event_filter_by_disabled_state(&self) -> bool { +impl<'a> PrivateClickEventHelpers for &'a Node { + fn click_event_filter_by_disabled_state(self) -> bool { match self.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) | @@ -1118,9 +1120,9 @@ impl<'a> PrivateClickEventHelpers for JSRef<'a, Node> { } } -impl<'a> DocumentMethods for JSRef<'a, Document> { +impl<'a> DocumentMethods for &'a Document { // https://dom.spec.whatwg.org/#dom-document-implementation - fn Implementation(self) -> Temporary<DOMImplementation> { + fn Implementation(self) -> Root<DOMImplementation> { self.implementation.or_init(|| DOMImplementation::new(self)) } @@ -1130,13 +1132,13 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/multipage/#dom-document-activeelement - fn GetActiveElement(self) -> Option<Temporary<Element>> { + fn GetActiveElement(self) -> Option<Root<Element>> { // TODO: Step 2. match self.get_focused_element() { Some(element) => Some(element), // Step 3. and 4. None => match self.GetBody() { // Step 5. - Some(body) => Some(ElementCast::from_temporary(body)), + Some(body) => Some(ElementCast::from_root(body)), None => self.GetDocumentElement(), } } @@ -1175,50 +1177,49 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-doctype - fn GetDoctype(self) -> Option<Temporary<DocumentType>> { - let node: JSRef<Node> = NodeCast::from_ref(self); + fn GetDoctype(self) -> Option<Root<DocumentType>> { + let node = NodeCast::from_ref(self); node.children() - .map(|c| c.root()) - .filter_map(|c| DocumentTypeCast::to_ref(c.r()).map(Temporary::from_rooted)) + .filter_map(|c| DocumentTypeCast::to_ref(c.r()).map(Root::from_ref)) .next() } // https://dom.spec.whatwg.org/#dom-document-documentelement - fn GetDocumentElement(self) -> Option<Temporary<Element>> { - let node: JSRef<Node> = NodeCast::from_ref(self); + fn GetDocumentElement(self) -> Option<Root<Element>> { + let node = NodeCast::from_ref(self); node.child_elements().next() } // https://dom.spec.whatwg.org/#dom-document-getelementsbytagname - fn GetElementsByTagName(self, tag_name: DOMString) -> Temporary<HTMLCollection> { + fn GetElementsByTagName(self, tag_name: DOMString) -> Root<HTMLCollection> { let window = self.window.root(); HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), tag_name) } // https://dom.spec.whatwg.org/#dom-document-getelementsbytagnamens fn GetElementsByTagNameNS(self, maybe_ns: Option<DOMString>, tag_name: DOMString) - -> Temporary<HTMLCollection> { + -> Root<HTMLCollection> { let window = self.window.root(); HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), tag_name, maybe_ns) } // https://dom.spec.whatwg.org/#dom-document-getelementsbyclassname - fn GetElementsByClassName(self, classes: DOMString) -> Temporary<HTMLCollection> { + fn GetElementsByClassName(self, classes: DOMString) -> Root<HTMLCollection> { let window = self.window.root(); HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes) } // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid - fn GetElementById(self, id: DOMString) -> Option<Temporary<Element>> { + fn GetElementById(self, id: DOMString) -> Option<Root<Element>> { let id = Atom::from_slice(&id); // FIXME(https://github.com/rust-lang/rust/issues/23338) let idmap = self.idmap.borrow(); - idmap.get(&id).map(|ref elements| Temporary::from_rooted((*elements)[0].clone())) + idmap.get(&id).map(|ref elements| (*elements)[0].root()) } // https://dom.spec.whatwg.org/#dom-document-createelement - fn CreateElement(self, mut local_name: DOMString) -> Fallible<Temporary<Element>> { + fn CreateElement(self, mut local_name: DOMString) -> Fallible<Root<Element>> { if xml_name_type(&local_name) == InvalidXMLName { debug!("Not a valid element name"); return Err(InvalidCharacter); @@ -1233,7 +1234,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { // https://dom.spec.whatwg.org/#dom-document-createelementns fn CreateElementNS(self, namespace: Option<DOMString>, - qualified_name: DOMString) -> Fallible<Temporary<Element>> { + qualified_name: DOMString) -> Fallible<Root<Element>> { let (namespace, prefix, local_name) = try!(validate_and_extract(namespace, &qualified_name)); let name = QualName::new(namespace, local_name); @@ -1241,7 +1242,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-createattribute - fn CreateAttribute(self, local_name: DOMString) -> Fallible<Temporary<Attr>> { + fn CreateAttribute(self, local_name: DOMString) -> Fallible<Root<Attr>> { if xml_name_type(&local_name) == InvalidXMLName { debug!("Not a valid element name"); return Err(InvalidCharacter); @@ -1258,7 +1259,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { // https://dom.spec.whatwg.org/#dom-document-createattributens fn CreateAttributeNS(self, namespace: Option<DOMString>, qualified_name: DOMString) - -> Fallible<Temporary<Attr>> { + -> Fallible<Root<Attr>> { let (namespace, prefix, local_name) = try!(validate_and_extract(namespace, &qualified_name)); let window = self.window.root(); @@ -1269,23 +1270,23 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-createdocumentfragment - fn CreateDocumentFragment(self) -> Temporary<DocumentFragment> { + fn CreateDocumentFragment(self) -> Root<DocumentFragment> { DocumentFragment::new(self) } // https://dom.spec.whatwg.org/#dom-document-createtextnode - fn CreateTextNode(self, data: DOMString) -> Temporary<Text> { + fn CreateTextNode(self, data: DOMString) -> Root<Text> { Text::new(data, self) } // https://dom.spec.whatwg.org/#dom-document-createcomment - fn CreateComment(self, data: DOMString) -> Temporary<Comment> { + fn CreateComment(self, data: DOMString) -> Root<Comment> { Comment::new(data, self) } // https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction fn CreateProcessingInstruction(self, target: DOMString, data: DOMString) -> - Fallible<Temporary<ProcessingInstruction>> { + Fallible<Root<ProcessingInstruction>> { // Step 1. if xml_name_type(&target) == InvalidXMLName { return Err(InvalidCharacter); @@ -1301,7 +1302,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-importnode - fn ImportNode(self, node: JSRef<Node>, deep: bool) -> Fallible<Temporary<Node>> { + fn ImportNode(self, node: &Node, deep: bool) -> Fallible<Root<Node>> { // Step 1. if node.is_document() { return Err(NotSupported); @@ -1317,7 +1318,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-adoptnode - fn AdoptNode(self, node: JSRef<Node>) -> Fallible<Temporary<Node>> { + fn AdoptNode(self, node: &Node) -> Fallible<Root<Node>> { // Step 1. if node.is_document() { return Err(NotSupported); @@ -1327,25 +1328,25 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { Node::adopt(node, self); // Step 3. - Ok(Temporary::from_rooted(node)) + Ok(Root::from_ref(node)) } // https://dom.spec.whatwg.org/#dom-document-createevent - fn CreateEvent(self, interface: DOMString) -> Fallible<Temporary<Event>> { + fn CreateEvent(self, interface: DOMString) -> Fallible<Root<Event>> { let window = self.window.root(); match &*interface.to_ascii_lowercase() { - "uievents" | "uievent" => Ok(EventCast::from_temporary( + "uievents" | "uievent" => Ok(EventCast::from_root( UIEvent::new_uninitialized(window.r()))), - "mouseevents" | "mouseevent" => Ok(EventCast::from_temporary( + "mouseevents" | "mouseevent" => Ok(EventCast::from_root( MouseEvent::new_uninitialized(window.r()))), - "customevent" => Ok(EventCast::from_temporary( + "customevent" => Ok(EventCast::from_root( CustomEvent::new_uninitialized(GlobalRef::Window(window.r())))), "htmlevents" | "events" | "event" => Ok(Event::new_uninitialized( GlobalRef::Window(window.r()))), - "keyboardevent" | "keyevents" => Ok(EventCast::from_temporary( + "keyboardevent" | "keyevents" => Ok(EventCast::from_root( KeyboardEvent::new_uninitialized(window.r()))), - "messageevent" => Ok(EventCast::from_temporary( + "messageevent" => Ok(EventCast::from_root( MessageEvent::new_uninitialized(GlobalRef::Window(window.r())))), _ => Err(NotSupported) } @@ -1360,39 +1361,38 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-document-createrange - fn CreateRange(self) -> Temporary<Range> { + fn CreateRange(self) -> Root<Range> { Range::new_with_doc(self) } // https://dom.spec.whatwg.org/#dom-document-createnodeiteratorroot-whattoshow-filter - fn CreateNodeIterator(self, root: JSRef<Node>, whatToShow: u32, filter: Option<NodeFilter>) - -> Temporary<NodeIterator> { + fn CreateNodeIterator(self, root: &Node, whatToShow: u32, filter: Option<Rc<NodeFilter>>) + -> Root<NodeIterator> { NodeIterator::new(self, root, whatToShow, filter) } // https://dom.spec.whatwg.org/#dom-document-createtreewalker - fn CreateTreeWalker(self, root: JSRef<Node>, whatToShow: u32, filter: Option<NodeFilter>) - -> Temporary<TreeWalker> { + fn CreateTreeWalker(self, root: &Node, whatToShow: u32, filter: Option<Rc<NodeFilter>>) + -> Root<TreeWalker> { TreeWalker::new(self, root, whatToShow, filter) } // https://html.spec.whatwg.org/#document.title fn Title(self) -> DOMString { - let title = self.GetDocumentElement().root().and_then(|root| { + let title = self.GetDocumentElement().and_then(|root| { if root.r().namespace() == &ns!(SVG) && root.r().local_name() == &atom!("svg") { // Step 1. NodeCast::from_ref(root.r()).child_elements().find(|node| { - let node = node.root(); node.r().namespace() == &ns!(SVG) && node.r().local_name() == &atom!("title") - }).map(NodeCast::from_temporary) + }).map(NodeCast::from_root) } else { // Step 2. NodeCast::from_ref(root.r()) .traverse_preorder() - .find(|node| node.root().r().is_htmltitleelement()) + .find(|node| node.r().is_htmltitleelement()) } - }).root(); + }); match title { None => DOMString::new(), @@ -1409,30 +1409,29 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { let root = match self.GetDocumentElement() { Some(root) => root, None => return, - }.root(); + }; let elem = if root.r().namespace() == &ns!(SVG) && root.r().local_name() == &atom!("svg") { let elem = NodeCast::from_ref(root.r()).child_elements().find(|node| { - let node = node.root(); node.r().namespace() == &ns!(SVG) && node.r().local_name() == &atom!("title") }); match elem { - Some(elem) => NodeCast::from_temporary(elem), + Some(elem) => NodeCast::from_root(elem), None => { let name = QualName::new(ns!(SVG), atom!("title")); let elem = Element::create(name, None, self, ElementCreator::ScriptCreated); NodeCast::from_ref(root.r()) - .AppendChild(NodeCast::from_ref(elem.root().r())) + .AppendChild(NodeCast::from_ref(elem.r())) .unwrap() } } } else if root.r().namespace() == &ns!(HTML) { let elem = NodeCast::from_ref(root.r()) .traverse_preorder() - .find(|node| node.root().r().is_htmltitleelement()); + .find(|node| node.r().is_htmltitleelement()); match elem { Some(elem) => elem, None => { @@ -1441,8 +1440,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { let name = QualName::new(ns!(HTML), atom!("title")); let elem = Element::create(name, None, self, ElementCreator::ScriptCreated); - NodeCast::from_ref(head.root().r()) - .AppendChild(NodeCast::from_ref(elem.root().r())) + NodeCast::from_ref(head.r()) + .AppendChild(NodeCast::from_ref(elem.r())) .unwrap() }, None => return, @@ -1453,52 +1452,49 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { return }; - elem.root().r().SetTextContent(Some(title)); + elem.r().SetTextContent(Some(title)); } // https://html.spec.whatwg.org/#dom-document-head - fn GetHead(self) -> Option<Temporary<HTMLHeadElement>> { + fn GetHead(self) -> Option<Root<HTMLHeadElement>> { self.get_html_element().and_then(|root| { - let root = root.root(); - let node: JSRef<Node> = NodeCast::from_ref(root.r()); + let node = NodeCast::from_ref(root.r()); node.children() - .map(|c| c.root()) - .filter_map(|c| HTMLHeadElementCast::to_ref(c.r()).map(Temporary::from_rooted)) + .filter_map(|c| HTMLHeadElementCast::to_ref(c.r()).map(Root::from_ref)) .next() }) } // https://html.spec.whatwg.org/#dom-document-currentscript - fn GetCurrentScript(self) -> Option<Temporary<HTMLScriptElement>> { - self.current_script.get().map(Temporary::from_rooted) + fn GetCurrentScript(self) -> Option<Root<HTMLScriptElement>> { + self.current_script.get().map(Root::from_rooted) } // https://html.spec.whatwg.org/#dom-document-body - fn GetBody(self) -> Option<Temporary<HTMLElement>> { + fn GetBody(self) -> Option<Root<HTMLElement>> { self.get_html_element().and_then(|root| { - let root = root.root(); - let node: JSRef<Node> = NodeCast::from_ref(root.r()); - node.children().map(|c| c.root()).find(|child| { + let node = NodeCast::from_ref(root.r()); + node.children().find(|child| { match child.r().type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBodyElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFrameSetElement)) => true, _ => false } }).map(|node| { - Temporary::from_rooted(HTMLElementCast::to_ref(node.r()).unwrap()) + Root::from_ref(HTMLElementCast::to_ref(node.r()).unwrap()) }) }) } // https://html.spec.whatwg.org/#dom-document-body - fn SetBody(self, new_body: Option<JSRef<HTMLElement>>) -> ErrorResult { + fn SetBody(self, new_body: Option<&HTMLElement>) -> ErrorResult { // Step 1. let new_body = match new_body { Some(new_body) => new_body, None => return Err(HierarchyRequest), }; - let node: JSRef<Node> = NodeCast::from_ref(new_body); + let node = NodeCast::from_ref(new_body); match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBodyElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFrameSetElement)) => {} @@ -1506,17 +1502,17 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // Step 2. - let old_body = self.GetBody().root(); + let old_body = self.GetBody(); if old_body.as_ref().map(|body| body.r()) == Some(new_body) { return Ok(()); } - match (self.get_html_element().root(), &old_body) { + match (self.get_html_element(), &old_body) { // Step 3. (Some(ref root), &Some(ref child)) => { - let root: JSRef<Node> = NodeCast::from_ref(root.r()); - let child: JSRef<Node> = NodeCast::from_ref(child.r()); - let new_body: JSRef<Node> = NodeCast::from_ref(new_body); + let root = NodeCast::from_ref(root.r()); + let child = NodeCast::from_ref(child.r()); + let new_body = NodeCast::from_ref(new_body); assert!(root.ReplaceChild(new_body, child).is_ok()) }, @@ -1525,8 +1521,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { // Step 5. (Some(ref root), &None) => { - let root: JSRef<Node> = NodeCast::from_ref(root.r()); - let new_body: JSRef<Node> = NodeCast::from_ref(new_body); + let root = NodeCast::from_ref(root.r()); + let new_body = NodeCast::from_ref(new_body); assert!(root.AppendChild(new_body).is_ok()); } } @@ -1534,16 +1530,16 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-getelementsbyname - fn GetElementsByName(self, name: DOMString) -> Temporary<NodeList> { + fn GetElementsByName(self, name: DOMString) -> Root<NodeList> { self.create_node_list(|node| { - let element: JSRef<Element> = match ElementCast::to_ref(node) { + let element = match ElementCast::to_ref(node) { Some(element) => element, None => return false, }; if element.namespace() != &ns!(HTML) { return false; } - element.get_attribute(&ns!(""), &atom!("name")).root().map_or(false, |attr| { + element.get_attribute(&ns!(""), &atom!("name")).map_or(false, |attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -1553,7 +1549,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-images - fn Images(self) -> Temporary<HTMLCollection> { + fn Images(self) -> Root<HTMLCollection> { self.images.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1563,7 +1559,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-embeds - fn Embeds(self) -> Temporary<HTMLCollection> { + fn Embeds(self) -> Root<HTMLCollection> { self.embeds.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1573,12 +1569,12 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-plugins - fn Plugins(self) -> Temporary<HTMLCollection> { + fn Plugins(self) -> Root<HTMLCollection> { self.Embeds() } // https://html.spec.whatwg.org/#dom-document-links - fn Links(self) -> Temporary<HTMLCollection> { + fn Links(self) -> Root<HTMLCollection> { self.links.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1588,7 +1584,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-forms - fn Forms(self) -> Temporary<HTMLCollection> { + fn Forms(self) -> Root<HTMLCollection> { self.forms.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1598,7 +1594,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-scripts - fn Scripts(self) -> Temporary<HTMLCollection> { + fn Scripts(self) -> Root<HTMLCollection> { self.scripts.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1608,7 +1604,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-anchors - fn Anchors(self) -> Temporary<HTMLCollection> { + fn Anchors(self) -> Root<HTMLCollection> { self.anchors.or_init(|| { let window = self.window.root(); let root = NodeCast::from_ref(self); @@ -1618,7 +1614,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-applets - fn Applets(self) -> Temporary<HTMLCollection> { + fn Applets(self) -> Root<HTMLCollection> { // FIXME: This should be return OBJECT elements containing applets. self.applets.or_init(|| { let window = self.window.root(); @@ -1629,26 +1625,26 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/#dom-document-location - fn Location(self) -> Temporary<Location> { + fn Location(self) -> Root<Location> { let window = self.window.root(); let window = window.r(); self.location.or_init(|| Location::new(window)) } // https://dom.spec.whatwg.org/#dom-parentnode-children - fn Children(self) -> Temporary<HTMLCollection> { + fn Children(self) -> Root<HTMLCollection> { let window = self.window.root(); HTMLCollection::children(window.r(), NodeCast::from_ref(self)) } // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild - fn GetFirstElementChild(self) -> Option<Temporary<Element>> { + fn GetFirstElementChild(self) -> Option<Root<Element>> { NodeCast::from_ref(self).child_elements().next() } // https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild - fn GetLastElementChild(self) -> Option<Temporary<Element>> { - NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_temporary).next() + fn GetLastElementChild(self) -> Option<Root<Element>> { + NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-parentnode-childelementcount @@ -1667,14 +1663,14 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://dom.spec.whatwg.org/#dom-parentnode-queryselector - fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> { + let root = NodeCast::from_ref(self); root.query_selector(selectors) } // https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall - fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> { + let root = NodeCast::from_ref(self); root.query_selector_all(selectors) } @@ -1684,8 +1680,8 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // https://html.spec.whatwg.org/multipage/#dom-document-defaultview - fn DefaultView(self) -> Temporary<Window> { - Temporary::from_rooted(self.window) + fn DefaultView(self) -> Root<Window> { + self.window.root() } // https://html.spec.whatwg.org/multipage/#dom-document-cookie @@ -1730,12 +1726,12 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { name: Atom, } impl CollectionFilter for NamedElementFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { filter_by_name(&self.name, NodeCast::from_ref(elem)) } } // https://html.spec.whatwg.org/#dom-document-nameditem-filter - fn filter_by_name(name: &Atom, node: JSRef<Node>) -> bool { + fn filter_by_name(name: &Atom, node: &Node) -> bool { let html_elem_type = match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(type_)) => type_, _ => return false, @@ -1746,10 +1742,10 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { }; match html_elem_type { HTMLElementTypeId::HTMLAppletElement => { - match elem.get_attribute(&ns!(""), &atom!("name")).root() { + match elem.get_attribute(&ns!(""), &atom!("name")) { Some(ref attr) if attr.r().value().atom() == Some(name) => true, _ => { - match elem.get_attribute(&ns!(""), &atom!("id")).root() { + match elem.get_attribute(&ns!(""), &atom!("id")) { Some(ref attr) => attr.r().value().atom() == Some(name), None => false, } @@ -1757,18 +1753,18 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } }, HTMLElementTypeId::HTMLFormElement => { - match elem.get_attribute(&ns!(""), &atom!("name")).root() { + match elem.get_attribute(&ns!(""), &atom!("name")) { Some(ref attr) => attr.r().value().atom() == Some(name), None => false, } }, HTMLElementTypeId::HTMLImageElement => { - match elem.get_attribute(&ns!(""), &atom!("name")).root() { + match elem.get_attribute(&ns!(""), &atom!("name")) { Some(ref attr) => { if attr.r().value().atom() == Some(name) { true } else { - match elem.get_attribute(&ns!(""), &atom!("id")).root() { + match elem.get_attribute(&ns!(""), &atom!("id")) { Some(ref attr) => attr.r().value().atom() == Some(name), None => false, } @@ -1786,16 +1782,14 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { { // Step 1. let mut elements = root.traverse_preorder().filter(|node| { - let node = node.root(); filter_by_name(&name, node.r()) }).peekable(); if let Some(first) = elements.next() { - let first = first.root(); if elements.is_empty() { *found = true; // TODO: Step 2. // Step 3. - return first.to_jsval(cx).to_object(); + return first.r().reflector().get_jsobject().get() } } else { *found = false; @@ -1804,10 +1798,10 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { } // Step 4. *found = true; - let window = self.window().root(); + let window = self.window(); let filter = NamedElementFilter { name: name }; - let collection = HTMLCollection::create(window.r(), root, box filter).root(); - collection.to_jsval(cx).to_object() + let collection = HTMLCollection::create(window.r(), root, box filter); + collection.r().reflector().get_jsobject().get() } global_event_handlers!(); @@ -1837,30 +1831,30 @@ impl DocumentProgressHandler { } fn dispatch_dom_content_loaded(&self) { - let document = self.addr.to_temporary().root(); - let window = document.r().window().root(); + let document = self.addr.root(); + let window = document.r().window(); let event = Event::new(GlobalRef::Window(window.r()), "DOMContentLoaded".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); - let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r()); + EventCancelable::NotCancelable); + let doctarget = EventTargetCast::from_ref(document.r()); let _ = doctarget.DispatchEvent(event.r()); window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::DOMContentLoaded); } fn set_ready_state_complete(&self) { - let document = self.addr.to_temporary().root(); + let document = self.addr.root(); document.r().set_ready_state(DocumentReadyState::Complete); } fn dispatch_load(&self) { - let document = self.addr.to_temporary().root(); - let window = document.r().window().root(); + let document = self.addr.root(); + let window = document.r().window(); let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); - let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r()); - let doctarget: JSRef<EventTarget> = EventTargetCast::from_ref(document.r()); + EventCancelable::NotCancelable); + let wintarget = EventTargetCast::from_ref(window.r()); + let doctarget = EventTargetCast::from_ref(document.r()); event.r().set_trusted(true); let _ = wintarget.dispatch_event_with_target(doctarget, event.r()); @@ -1869,12 +1863,11 @@ impl DocumentProgressHandler { let browser_context = browser_context.as_ref().unwrap(); browser_context.frame_element().map(|frame_element| { - let frame_element = frame_element.root(); - let frame_window = window_from_node(frame_element.r()).root(); + let frame_window = window_from_node(frame_element.r()); let event = Event::new(GlobalRef::Window(frame_window.r()), "load".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(frame_element.r()); + EventCancelable::NotCancelable); + let target = EventTargetCast::from_ref(frame_element.r()); event.r().fire(target); }); @@ -1889,8 +1882,8 @@ impl DocumentProgressHandler { impl Runnable for DocumentProgressHandler { fn handler(self: Box<DocumentProgressHandler>) { - let document = self.addr.to_temporary().root(); - let window = document.r().window().root(); + let document = self.addr.root(); + let window = document.r().window(); if window.r().is_alive() { match self.task { DocumentProgressTask::DOMContentLoaded => { diff --git a/components/script/dom/documentfragment.rs b/components/script/dom/documentfragment.rs index 15ced7b57ae..07baab72224 100644 --- a/components/script/dom/documentfragment.rs +++ b/components/script/dom/documentfragment.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::DocumentFragmentDerived; use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast}; use dom::bindings::codegen::UnionTypes::NodeOrString; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::document::Document; @@ -33,40 +33,39 @@ impl DocumentFragmentDerived for EventTarget { impl DocumentFragment { /// Creates a new DocumentFragment. - fn new_inherited(document: JSRef<Document>) -> DocumentFragment { + fn new_inherited(document: &Document) -> DocumentFragment { DocumentFragment { node: Node::new_inherited(NodeTypeId::DocumentFragment, document), } } - pub fn new(document: JSRef<Document>) -> Temporary<DocumentFragment> { + pub fn new(document: &Document) -> Root<DocumentFragment> { Node::reflect_node(box DocumentFragment::new_inherited(document), document, DocumentFragmentBinding::Wrap) } - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<DocumentFragment>> { + pub fn Constructor(global: GlobalRef) -> Fallible<Root<DocumentFragment>> { let document = global.as_window().Document(); - let document = document.root(); Ok(DocumentFragment::new(document.r())) } } -impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> { +impl<'a> DocumentFragmentMethods for &'a DocumentFragment { // https://dom.spec.whatwg.org/#dom-parentnode-children - fn Children(self) -> Temporary<HTMLCollection> { - let window = window_from_node(self).root(); + fn Children(self) -> Root<HTMLCollection> { + let window = window_from_node(self); HTMLCollection::children(window.r(), NodeCast::from_ref(self)) } // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild - fn GetFirstElementChild(self) -> Option<Temporary<Element>> { + fn GetFirstElementChild(self) -> Option<Root<Element>> { NodeCast::from_ref(self).child_elements().next() } // https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild - fn GetLastElementChild(self) -> Option<Temporary<Element>> { - NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_temporary).next() + fn GetLastElementChild(self) -> Option<Root<Element>> { + NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-parentnode-childelementcount @@ -85,14 +84,14 @@ impl<'a> DocumentFragmentMethods for JSRef<'a, DocumentFragment> { } // https://dom.spec.whatwg.org/#dom-parentnode-queryselector - fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> { + let root = NodeCast::from_ref(self); root.query_selector(selectors) } // https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall - fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> { + let root = NodeCast::from_ref(self); root.query_selector_all(selectors) } } diff --git a/components/script/dom/documenttype.rs b/components/script/dom/documenttype.rs index b5fd4300b70..3de5397c206 100644 --- a/components/script/dom/documenttype.rs +++ b/components/script/dom/documenttype.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DocumentTypeBinding::DocumentTypeMethods; use dom::bindings::codegen::InheritTypes::{DocumentTypeDerived, NodeCast}; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::ErrorResult; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::node::{Node, NodeHelpers, NodeTypeId}; @@ -35,7 +35,7 @@ impl DocumentType { fn new_inherited(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: JSRef<Document>) + document: &Document) -> DocumentType { DocumentType { node: Node::new_inherited(NodeTypeId::DocumentType, document), @@ -48,8 +48,8 @@ impl DocumentType { pub fn new(name: DOMString, public_id: Option<DOMString>, system_id: Option<DOMString>, - document: JSRef<Document>) - -> Temporary<DocumentType> { + document: &Document) + -> Root<DocumentType> { let documenttype = DocumentType::new_inherited(name, public_id, system_id, @@ -73,7 +73,7 @@ impl DocumentType { } } -impl<'a> DocumentTypeMethods for JSRef<'a, DocumentType> { +impl<'a> DocumentTypeMethods for &'a DocumentType { // https://dom.spec.whatwg.org/#dom-documenttype-name fn Name(self) -> DOMString { self.name.clone() @@ -106,7 +106,7 @@ impl<'a> DocumentTypeMethods for JSRef<'a, DocumentType> { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(self) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.remove_self(); } } diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 434a6acc957..19bebacf9ad 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding; use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants; use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use util::str::DOMString; @@ -54,12 +54,12 @@ impl DOMException { } } - pub fn new(global: GlobalRef, code: DOMErrorName) -> Temporary<DOMException> { + pub fn new(global: GlobalRef, code: DOMErrorName) -> Root<DOMException> { reflect_dom_object(box DOMException::new_inherited(code), global, DOMExceptionBinding::Wrap) } } -impl<'a> DOMExceptionMethods for JSRef<'a, DOMException> { +impl<'a> DOMExceptionMethods for &'a DOMException { // https://heycam.github.io/webidl/#dfn-DOMException fn Code(self) -> u16 { match self.code { diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 8171db316ac..28b5dccfd40 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -10,8 +10,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Root, Rootable}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::utils::validate_qualified_name; use dom::document::{Document, DocumentHelpers, IsHTMLDocument}; @@ -21,7 +20,6 @@ use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmlhtmlelement::HTMLHtmlElement; use dom::htmltitleelement::HTMLTitleElement; -use dom::node::Node; use dom::text::Text; use util::str::DOMString; @@ -35,15 +33,15 @@ pub struct DOMImplementation { } impl DOMImplementation { - fn new_inherited(document: JSRef<Document>) -> DOMImplementation { + fn new_inherited(document: &Document) -> DOMImplementation { DOMImplementation { reflector_: Reflector::new(), - document: JS::from_rooted(document), + document: JS::from_ref(document), } } - pub fn new(document: JSRef<Document>) -> Temporary<DOMImplementation> { - let window = document.window().root(); + pub fn new(document: &Document) -> Root<DOMImplementation> { + let window = document.window(); reflect_dom_object(box DOMImplementation::new_inherited(document), GlobalRef::Window(window.r()), DOMImplementationBinding::Wrap) @@ -51,10 +49,10 @@ impl DOMImplementation { } // https://dom.spec.whatwg.org/#domimplementation -impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { +impl<'a> DOMImplementationMethods for &'a DOMImplementation { // https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype fn CreateDocumentType(self, qualified_name: DOMString, pubid: DOMString, sysid: DOMString) - -> Fallible<Temporary<DocumentType>> { + -> Fallible<Root<DocumentType>> { try!(validate_qualified_name(&qualified_name)); let document = self.document.root(); Ok(DocumentType::new(qualified_name, Some(pubid), Some(sysid), document.r())) @@ -62,15 +60,15 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // https://dom.spec.whatwg.org/#dom-domimplementation-createdocument fn CreateDocument(self, namespace: Option<DOMString>, qname: DOMString, - maybe_doctype: Option<JSRef<DocumentType>>) -> Fallible<Temporary<Document>> { + maybe_doctype: Option<&DocumentType>) -> Fallible<Root<Document>> { let doc = self.document.root(); let doc = doc.r(); - let win = doc.window().root(); + let win = doc.window(); let loader = DocumentLoader::new(&*doc.loader()); // Step 1. let doc = Document::new(win.r(), None, IsHTMLDocument::NonHTMLDocument, - None, None, DocumentSource::NotFromParser, loader).root(); + None, None, DocumentSource::NotFromParser, loader); // Step 2-3. let maybe_elem = if qname.is_empty() { None @@ -82,19 +80,19 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { }; { - let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let doc_node = NodeCast::from_ref(doc.r()); // Step 4. match maybe_doctype { None => (), Some(ref doctype) => { - let doc_type: JSRef<Node> = NodeCast::from_ref(*doctype); + let doc_type = NodeCast::from_ref(*doctype); assert!(doc_node.AppendChild(doc_type).is_ok()) } } // Step 5. - match maybe_elem.root() { + match maybe_elem { None => (), Some(ref elem) => { assert!(doc_node.AppendChild(NodeCast::from_ref(elem.r())).is_ok()) @@ -106,37 +104,38 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // FIXME: https://github.com/mozilla/servo/issues/1522 // Step 7. - Ok(Temporary::from_rooted(doc.r())) + Ok(doc) } // https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument - fn CreateHTMLDocument(self, title: Option<DOMString>) -> Temporary<Document> { + fn CreateHTMLDocument(self, title: Option<DOMString>) -> Root<Document> { let document = self.document.root(); let document = document.r(); - let win = document.window().root(); + let win = document.window(); let loader = DocumentLoader::new(&*document.loader()); // Step 1-2. let doc = Document::new(win.r(), None, IsHTMLDocument::HTMLDocument, None, None, - DocumentSource::NotFromParser, loader).root(); - let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); + DocumentSource::NotFromParser, loader); { // Step 3. - let doc_type = DocumentType::new("html".to_owned(), None, None, doc.r()).root(); + let doc_node = NodeCast::from_ref(doc.r()); + let doc_type = DocumentType::new("html".to_owned(), None, None, doc.r()); assert!(doc_node.AppendChild(NodeCast::from_ref(doc_type.r())).is_ok()); } { // Step 4. - let doc_html: Root<Node> = NodeCast::from_temporary( - HTMLHtmlElement::new("html".to_owned(), None, doc.r())).root(); + let doc_node = NodeCast::from_ref(doc.r()); + let doc_html = NodeCast::from_root( + HTMLHtmlElement::new("html".to_owned(), None, doc.r())); assert!(doc_node.AppendChild(doc_html.r()).is_ok()); { // Step 5. - let doc_head: Root<Node> = NodeCast::from_temporary( - HTMLHeadElement::new("head".to_owned(), None, doc.r())).root(); + let doc_head = NodeCast::from_root( + HTMLHeadElement::new("head".to_owned(), None, doc.r())); assert!(doc_html.r().AppendChild(doc_head.r()).is_ok()); // Step 6. @@ -144,19 +143,19 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { None => (), Some(title_str) => { // Step 6.1. - let doc_title: Root<Node> = NodeCast::from_temporary( - HTMLTitleElement::new("title".to_owned(), None, doc.r())).root(); + let doc_title = NodeCast::from_root( + HTMLTitleElement::new("title".to_owned(), None, doc.r())); assert!(doc_head.r().AppendChild(doc_title.r()).is_ok()); // Step 6.2. - let title_text: Root<Text> = Text::new(title_str, doc.r()).root(); + let title_text = Text::new(title_str, doc.r()); assert!(doc_title.r().AppendChild(NodeCast::from_ref(title_text.r())).is_ok()); } } } // Step 7. - let doc_body: Root<HTMLBodyElement> = HTMLBodyElement::new("body".to_owned(), None, doc.r()).root(); + let doc_body = HTMLBodyElement::new("body".to_owned(), None, doc.r()); assert!(doc_html.r().AppendChild(NodeCast::from_ref(doc_body.r())).is_ok()); } @@ -164,7 +163,7 @@ impl<'a> DOMImplementationMethods for JSRef<'a, DOMImplementation> { // FIXME: https://github.com/mozilla/servo/issues/1522 // Step 9. - Temporary::from_rooted(doc.r()) + doc } // https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 40c9d8f436c..a225817b985 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::{Text_htm use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers, IsHTMLDocument}; use dom::document::DocumentSource; @@ -27,33 +27,33 @@ pub struct DOMParser { } impl DOMParser { - fn new_inherited(window: JSRef<Window>) -> DOMParser { + fn new_inherited(window: &Window) -> DOMParser { DOMParser { reflector_: Reflector::new(), - window: JS::from_rooted(window), + window: JS::from_ref(window), } } - pub fn new(window: JSRef<Window>) -> Temporary<DOMParser> { + pub fn new(window: &Window) -> Root<DOMParser> { reflect_dom_object(box DOMParser::new_inherited(window), GlobalRef::Window(window), DOMParserBinding::Wrap) } - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<DOMParser>> { + pub fn Constructor(global: GlobalRef) -> Fallible<Root<DOMParser>> { Ok(DOMParser::new(global.as_window())) } } -impl<'a> DOMParserMethods for JSRef<'a, DOMParser> { +impl<'a> DOMParserMethods for &'a DOMParser { // https://domparsing.spec.whatwg.org/#the-domparser-interface fn ParseFromString(self, s: DOMString, ty: DOMParserBinding::SupportedType) - -> Fallible<Temporary<Document>> { + -> Fallible<Root<Document>> { let window = self.window.root(); let url = window.r().get_url(); let content_type = DOMParserBinding::SupportedTypeValues::strings[ty as usize].to_owned(); - let doc = window.r().Document().root(); + let doc = window.r().Document(); let doc = doc.r(); let loader = DocumentLoader::new(&*doc.loader()); match ty { @@ -63,10 +63,10 @@ impl<'a> DOMParserMethods for JSRef<'a, DOMParser> { Some(content_type), None, DocumentSource::FromParser, - loader).root(); + loader); parse_html(document.r(), s, &url, ParseContext::Owner(None)); document.r().set_ready_state(DocumentReadyState::Complete); - Ok(Temporary::from_rooted(document.r())) + Ok(document) } Text_xml => { //FIXME: this should probably be FromParser when we actually parse the string (#3756). diff --git a/components/script/dom/domrect.rs b/components/script/dom/domrect.rs index 45c325b3a2d..c1870c18cc9 100644 --- a/components/script/dom/domrect.rs +++ b/components/script/dom/domrect.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::DOMRectBinding; use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::Window; @@ -32,15 +32,15 @@ impl DOMRect { } } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, top: Au, bottom: Au, - left: Au, right: Au) -> Temporary<DOMRect> { + left: Au, right: Au) -> Root<DOMRect> { reflect_dom_object(box DOMRect::new_inherited(top, bottom, left, right), GlobalRef::Window(window), DOMRectBinding::Wrap) } } -impl<'a> DOMRectMethods for JSRef<'a, DOMRect> { +impl<'a> DOMRectMethods for &'a DOMRect { fn Top(self) -> Finite<f32> { Finite::wrap(self.top) } diff --git a/components/script/dom/domrectlist.rs b/components/script/dom/domrectlist.rs index fe3a45ecf02..ebf227bb35d 100644 --- a/components/script/dom/domrectlist.rs +++ b/components/script/dom/domrectlist.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::DOMRectListBinding; use dom::bindings::codegen::Bindings::DOMRectListBinding::DOMRectListMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::domrect::DOMRect; use dom::window::Window; @@ -18,37 +18,37 @@ pub struct DOMRectList { } impl DOMRectList { - fn new_inherited<T>(window: JSRef<Window>, rects: T) -> DOMRectList - where T: Iterator<Item=Temporary<DOMRect>> { + fn new_inherited<T>(window: &Window, rects: T) -> DOMRectList + where T: Iterator<Item=Root<DOMRect>> { DOMRectList { reflector_: Reflector::new(), - rects: rects.map(JS::from_rooted).collect(), - window: JS::from_rooted(window), + rects: rects.map(|r| JS::from_rooted(&r)).collect(), + window: JS::from_ref(window), } } - pub fn new<T>(window: JSRef<Window>, rects: T) -> Temporary<DOMRectList> - where T: Iterator<Item=Temporary<DOMRect>> { + pub fn new<T>(window: &Window, rects: T) -> Root<DOMRectList> + where T: Iterator<Item=Root<DOMRect>> { reflect_dom_object(box DOMRectList::new_inherited(window, rects), GlobalRef::Window(window), DOMRectListBinding::Wrap) } } -impl<'a> DOMRectListMethods for JSRef<'a, DOMRectList> { +impl<'a> DOMRectListMethods for &'a DOMRectList { fn Length(self) -> u32 { self.rects.len() as u32 } - fn Item(self, index: u32) -> Option<Temporary<DOMRect>> { + fn Item(self, index: u32) -> Option<Root<DOMRect>> { let rects = &self.rects; if index < rects.len() as u32 { - Some(Temporary::from_rooted(rects[index as usize].clone())) + Some(rects[index as usize].root()) } else { None } } - fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<DOMRect>> { + fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<DOMRect>> { *found = index < self.rects.len() as u32; self.Item(index) } diff --git a/components/script/dom/domstringmap.rs b/components/script/dom/domstringmap.rs index f48b4218aed..625d261b686 100644 --- a/components/script/dom/domstringmap.rs +++ b/components/script/dom/domstringmap.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::DOMStringMapBinding; use dom::bindings::codegen::Bindings::DOMStringMapBinding::DOMStringMapMethods; use dom::bindings::error::ErrorResult; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::node::window_from_node; use dom::htmlelement::{HTMLElement, HTMLElementCustomAttributeHelpers}; @@ -19,22 +19,22 @@ pub struct DOMStringMap { } impl DOMStringMap { - fn new_inherited(element: JSRef<HTMLElement>) -> DOMStringMap { + fn new_inherited(element: &HTMLElement) -> DOMStringMap { DOMStringMap { reflector_: Reflector::new(), - element: JS::from_rooted(element), + element: JS::from_ref(element), } } - pub fn new(element: JSRef<HTMLElement>) -> Temporary<DOMStringMap> { - let window = window_from_node(element).root(); + pub fn new(element: &HTMLElement) -> Root<DOMStringMap> { + let window = window_from_node(element); reflect_dom_object(box DOMStringMap::new_inherited(element), GlobalRef::Window(window.r()), DOMStringMapBinding::Wrap) } } // https://html.spec.whatwg.org/#domstringmap -impl<'a> DOMStringMapMethods for JSRef<'a, DOMStringMap> { +impl<'a> DOMStringMapMethods for &'a DOMStringMap { fn NamedCreator(self, name: DOMString, value: DOMString) -> ErrorResult { self.NamedSetter(name, value) } diff --git a/components/script/dom/domtokenlist.rs b/components/script/dom/domtokenlist.rs index 0a42db03d5d..fc56673733c 100644 --- a/components/script/dom/domtokenlist.rs +++ b/components/script/dom/domtokenlist.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::DOMTokenListBinding::DOMTokenListMethods; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{InvalidCharacter, Syntax}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers}; use dom::node::window_from_node; @@ -26,16 +26,16 @@ pub struct DOMTokenList { } impl DOMTokenList { - pub fn new_inherited(element: JSRef<Element>, local_name: Atom) -> DOMTokenList { + pub fn new_inherited(element: &Element, local_name: Atom) -> DOMTokenList { DOMTokenList { reflector_: Reflector::new(), - element: JS::from_rooted(element), + element: JS::from_ref(element), local_name: local_name, } } - pub fn new(element: JSRef<Element>, local_name: &Atom) -> Temporary<DOMTokenList> { - let window = window_from_node(element).root(); + pub fn new(element: &Element, local_name: &Atom) -> Root<DOMTokenList> { + let window = window_from_node(element); reflect_dom_object(box DOMTokenList::new_inherited(element, local_name.clone()), GlobalRef::Window(window.r()), DOMTokenListBinding::Wrap) @@ -43,12 +43,12 @@ impl DOMTokenList { } trait PrivateDOMTokenListHelpers { - fn attribute(self) -> Option<Temporary<Attr>>; + fn attribute(self) -> Option<Root<Attr>>; fn check_token_exceptions(self, token: &str) -> Fallible<Atom>; } -impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> { - fn attribute(self) -> Option<Temporary<Attr>> { +impl<'a> PrivateDOMTokenListHelpers for &'a DOMTokenList { + fn attribute(self) -> Option<Root<Attr>> { let element = self.element.root(); element.r().get_attribute(&ns!(""), &self.local_name) } @@ -63,10 +63,10 @@ impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> { } // https://dom.spec.whatwg.org/#domtokenlist -impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { +impl<'a> DOMTokenListMethods for &'a DOMTokenList { // https://dom.spec.whatwg.org/#dom-domtokenlist-length fn Length(self) -> u32 { - self.attribute().root().map(|attr| { + self.attribute().map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -76,7 +76,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // https://dom.spec.whatwg.org/#dom-domtokenlist-item fn Item(self, index: u32) -> Option<DOMString> { - self.attribute().root().and_then(|attr| { + self.attribute().and_then(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -95,7 +95,7 @@ impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> { // https://dom.spec.whatwg.org/#dom-domtokenlist-contains fn Contains(self, token: DOMString) -> Fallible<bool> { self.check_token_exceptions(&token).map(|token| { - self.attribute().root().map(|attr| { + self.attribute().map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index a8cb3198135..a84773dd195 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -29,9 +29,8 @@ use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{InvalidCharacter, Syntax}; use dom::bindings::error::Error::NoModificationAllowed; -use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap}; -use dom::bindings::js::{OptionalRootable, Rootable, RootedReference}; -use dom::bindings::js::{Temporary, TemporaryPushable}; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; +use dom::bindings::js::{Root, RootedReference}; use dom::bindings::trace::RootedVec; use dom::bindings::utils::{xml_name_type, validate_and_extract}; use dom::bindings::utils::XMLName::InvalidXMLName; @@ -42,7 +41,6 @@ use dom::document::{Document, DocumentHelpers, LayoutDocumentHelpers}; use dom::domtokenlist::DOMTokenList; use dom::event::{Event, EventHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; -use dom::htmlanchorelement::HTMLAnchorElement; use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElementTypeId; @@ -113,6 +111,12 @@ impl ElementDerived for EventTarget { } } +impl PartialEq for Element { + fn eq(&self, other: &Element) -> bool { + self as *const Element == &*other + } +} + #[derive(Copy, Clone, PartialEq, Debug)] #[jstraceable] pub enum ElementTypeId { @@ -131,14 +135,14 @@ pub enum ElementCreator { // impl Element { pub fn create(name: QualName, prefix: Option<Atom>, - document: JSRef<Document>, creator: ElementCreator) - -> Temporary<Element> { + document: &Document, creator: ElementCreator) + -> Root<Element> { create_element(name, prefix, document, creator) } pub fn new_inherited(type_id: ElementTypeId, local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, - document: JSRef<Document>) -> Element { + document: &Document) -> Element { Element { node: Node::new_inherited(NodeTypeId::Element(type_id), document), local_name: Atom::from_slice(&local_name), @@ -154,7 +158,7 @@ impl Element { pub fn new(local_name: DOMString, namespace: Namespace, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<Element> { + document: &Document) -> Root<Element> { Node::reflect_node( box Element::new_inherited(ElementTypeId::Element, local_name, namespace, prefix, document), document, @@ -181,8 +185,6 @@ pub trait RawLayoutElementHelpers { -> Option<u32>; fn local_name<'a>(&'a self) -> &'a Atom; - fn namespace<'a>(&'a self) -> &'a Namespace; - fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>; } #[inline] @@ -504,14 +506,6 @@ impl RawLayoutElementHelpers for Element { fn local_name<'a>(&'a self) -> &'a Atom { &self.local_name } - - fn namespace<'a>(&'a self) -> &'a Namespace { - &self.namespace - } - - fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> { - &self.style_attribute - } } pub trait LayoutElementHelpers { @@ -560,18 +554,18 @@ pub trait ElementHelpers<'a> { fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>; fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>; fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString>; - fn get_root_element(self) -> Temporary<Element>; + fn get_root_element(self) -> Root<Element>; fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString>; } -impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { +impl<'a> ElementHelpers<'a> for &'a Element { fn html_element_in_html_document(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); self.namespace == ns!(HTML) && node.is_in_html_doc() } fn local_name(self) -> &'a Atom { - &self.extended_deref().local_name + &self.local_name } fn parsed_name(self, name: DOMString) -> DOMString { @@ -583,30 +577,30 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { } fn namespace(self) -> &'a Namespace { - &self.extended_deref().namespace + &self.namespace } fn prefix(self) -> &'a Option<DOMString> { - &self.extended_deref().prefix + &self.prefix } fn attrs(&self) -> Ref<Vec<JS<Attr>>> { - self.extended_deref().attrs.borrow() + self.attrs.borrow() } fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>> { - self.extended_deref().attrs.borrow_mut() + self.attrs.borrow_mut() } fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> { - &self.extended_deref().style_attribute + &self.style_attribute } fn summarize(self) -> Vec<AttrInfo> { - let attrs = self.Attributes().root(); + let attrs = self.Attributes(); let mut summarized = vec!(); for i in 0..attrs.r().Length() { - let attr = attrs.r().Item(i).unwrap().root(); + let attr = attrs.r().Item(i).unwrap(); summarized.push(attr.r().summarize()); } summarized @@ -702,7 +696,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { } fn serialize(self, traversal_scope: TraversalScope) -> Fallible<DOMString> { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let mut writer = vec![]; match serialize(&mut writer, &node, SerializeOpts { @@ -715,10 +709,10 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { } // https://html.spec.whatwg.org/multipage/#root-element - fn get_root_element(self) -> Temporary<Element> { - let node: JSRef<Node> = NodeCast::from_ref(self); + fn get_root_element(self) -> Root<Element> { + let node = NodeCast::from_ref(self); node.inclusive_ancestors() - .filter_map(ElementCast::to_temporary) + .filter_map(ElementCast::to_root) .last() .expect("We know inclusive_ancestors will return `self` which is an element") } @@ -726,7 +720,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { // https://dom.spec.whatwg.org/#locate-a-namespace-prefix fn lookup_prefix(self, namespace: Namespace) -> Option<DOMString> { for node in NodeCast::from_ref(self).inclusive_ancestors() { - match ElementCast::to_ref(node.root().r()) { + match ElementCast::to_ref(node.r()) { Some(element) => { // Step 1. if *element.namespace() == namespace { @@ -736,9 +730,9 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> { } // Step 2. - let attrs = element.Attributes().root(); + let attrs = element.Attributes(); for i in 0..attrs.r().Length() { - let attr = attrs.r().Item(i).unwrap().root(); + let attr = attrs.r().Item(i).unwrap(); if *attr.r().prefix() == Some(atom!("xmlns")) && **attr.r().value() == *namespace.0 { return Some(attr.r().LocalName()); @@ -760,13 +754,13 @@ pub trait FocusElementHelpers { fn is_actually_disabled(self) -> bool; } -impl<'a> FocusElementHelpers for JSRef<'a, Element> { +impl<'a> FocusElementHelpers for &'a Element { fn is_focusable_area(self) -> bool { if self.is_actually_disabled() { return false; } // TODO: Check whether the element is being rendered (i.e. not hidden). - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if node.get_flag(SEQUENTIALLY_FOCUSABLE) { return true; } @@ -783,7 +777,7 @@ impl<'a> FocusElementHelpers for JSRef<'a, Element> { } fn is_actually_disabled(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) | @@ -805,10 +799,10 @@ pub trait AttributeHandlers { /// Returns the attribute with given namespace and case-sensitive local /// name, if any. fn get_attribute(self, namespace: &Namespace, local_name: &Atom) - -> Option<Temporary<Attr>>; + -> Option<Root<Attr>>; /// Returns the first attribute with any namespace and given case-sensitive /// name, if any. - fn get_attribute_by_name(self, name: DOMString) -> Option<Temporary<Attr>>; + fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>>; fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>); fn set_attribute_from_parser(self, name: QualName, @@ -819,19 +813,19 @@ pub trait AttributeHandlers { fn do_set_attribute<F>(self, local_name: Atom, value: AttrValue, name: Atom, namespace: Namespace, prefix: Option<Atom>, cb: F) - where F: Fn(JSRef<Attr>) -> bool; + where F: Fn(&Attr) -> bool; fn parse_attribute(self, namespace: &Namespace, local_name: &Atom, value: DOMString) -> AttrValue; /// Removes the first attribute with any given namespace and case-sensitive local /// name, if any. fn remove_attribute(self, namespace: &Namespace, local_name: &Atom) - -> Option<Temporary<Attr>>; + -> Option<Root<Attr>>; /// Removes the first attribute with any namespace and given case-sensitive name. - fn remove_attribute_by_name(self, name: &Atom) -> Option<Temporary<Attr>>; + fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>>; /// Removes the first attribute that satisfies `find`. - fn do_remove_attribute<F>(self, find: F) -> Option<Temporary<Attr>> - where F: Fn(JSRef<Attr>) -> bool; + fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>> + where F: Fn(&Attr) -> bool; fn has_class(self, name: &Atom) -> bool; @@ -851,36 +845,34 @@ pub trait AttributeHandlers { fn set_uint_attribute(self, local_name: &Atom, value: u32); } -impl<'a> AttributeHandlers for JSRef<'a, Element> { - fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Temporary<Attr>> { +impl<'a> AttributeHandlers for &'a Element { + fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> { let mut attributes = RootedVec::new(); self.get_attributes(local_name, &mut attributes); attributes.iter() .map(|attr| attr.root()) .find(|attr| attr.r().namespace() == namespace) - .map(|x| Temporary::from_rooted(x.r())) } // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name - fn get_attribute_by_name(self, name: DOMString) -> Option<Temporary<Attr>> { + fn get_attribute_by_name(self, name: DOMString) -> Option<Root<Attr>> { let name = &Atom::from_slice(&self.parsed_name(name)); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attrs = self.attrs.borrow(); attrs.iter().map(|attr| attr.root()) .find(|a| a.r().name() == name) - .map(|x| Temporary::from_rooted(x.r())) } // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name fn get_attributes(self, local_name: &Atom, attributes: &mut RootedVec<JS<Attr>>) { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attrs = self.attrs.borrow(); - for ref attr in attrs.iter().map(|attr| attr.root()) { + for ref attr in attrs.iter() { // FIXME(https://github.com/rust-lang/rust/issues/23338) - let attr = attr.r(); - let attr_local_name = attr.local_name(); + let attr = attr.root(); + let attr_local_name = attr.r().local_name(); if attr_local_name == local_name { - attributes.push(JS::from_rooted(attr)); + attributes.push(JS::from_rooted(&attr)); } } } @@ -938,7 +930,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { namespace: Namespace, prefix: Option<Atom>, cb: F) - where F: Fn(JSRef<Attr>) -> bool + where F: Fn(&Attr) -> bool { let idx = self.attrs.borrow().iter() .map(|attr| attr.root()) @@ -946,10 +938,10 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { let (idx, set_type) = match idx { Some(idx) => (idx, AttrSettingType::ReplacedAttr), None => { - let window = window_from_node(self).root(); + let window = window_from_node(self); let attr = Attr::new(window.r(), local_name, value.clone(), name, namespace.clone(), prefix, Some(self)); - self.attrs.borrow_mut().push_unrooted(&attr); + self.attrs.borrow_mut().push(JS::from_rooted(&attr)); (self.attrs.borrow().len() - 1, AttrSettingType::FirstSetAttr) } }; @@ -968,18 +960,18 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn remove_attribute(self, namespace: &Namespace, local_name: &Atom) - -> Option<Temporary<Attr>> { + -> Option<Root<Attr>> { self.do_remove_attribute(|attr| { attr.namespace() == namespace && attr.local_name() == local_name }) } - fn remove_attribute_by_name(self, name: &Atom) -> Option<Temporary<Attr>> { + fn remove_attribute_by_name(self, name: &Atom) -> Option<Root<Attr>> { self.do_remove_attribute(|attr| attr.name() == name) } - fn do_remove_attribute<F>(self, find: F) -> Option<Temporary<Attr>> - where F: Fn(JSRef<Attr>) -> bool + fn do_remove_attribute<F>(self, find: F) -> Option<Root<Attr>> + where F: Fn(&Attr) -> bool { let idx = self.attrs.borrow().iter() .map(|attr| attr.root()) @@ -997,9 +989,9 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { vtable_for(&NodeCast::from_ref(self)).after_remove_attr(attr.r().name()); } - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if node.is_in_doc() { - let document = document_from_node(self).root(); + let document = document_from_node(self); let damage = if attr.r().local_name() == &atom!("style") { NodeDamage::NodeStyleDamaged } else { @@ -1007,21 +999,21 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { }; document.r().content_changed(node, damage); } - Temporary::from_rooted(attr.r()) + attr }) } fn has_class(self, name: &Atom) -> bool { let quirks_mode = { - let node: JSRef<Node> = NodeCast::from_ref(self); - let owner_doc = node.owner_doc().root(); + let node = NodeCast::from_ref(self); + let owner_doc = node.owner_doc(); owner_doc.r().quirks_mode() }; let is_equal = |lhs: &Atom, rhs: &Atom| match quirks_mode { NoQuirks | LimitedQuirks => lhs == rhs, Quirks => lhs.eq_ignore_ascii_case(&rhs) }; - self.get_attribute(&ns!(""), &atom!("class")).root().map(|attr| { + self.get_attribute(&ns!(""), &atom!("class")).map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -1063,7 +1055,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { return "".to_owned(); } let url = self.get_string_attribute(local_name); - let doc = document_from_node(self).root(); + let doc = document_from_node(self); let base = doc.r().url(); // https://html.spec.whatwg.org/multipage/#reflect // XXXManishearth this doesn't handle `javascript:` urls properly @@ -1078,7 +1070,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { fn get_string_attribute(self, local_name: &Atom) -> DOMString { match self.get_attribute(&ns!(""), local_name) { - Some(x) => x.root().r().Value(), + Some(x) => x.r().Value(), None => "".to_owned() } } @@ -1088,7 +1080,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } fn get_tokenlist_attribute(self, local_name: &Atom) -> Vec<Atom> { - self.get_attribute(&ns!(""), local_name).root().map(|attr| { + self.get_attribute(&ns!(""), local_name).map(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -1112,7 +1104,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { assert!(local_name.chars().all(|ch| { !ch.is_ascii() || ch.to_ascii_lowercase() == ch })); - let attribute = self.get_attribute(&ns!(""), local_name).root(); + let attribute = self.get_attribute(&ns!(""), local_name); match attribute { Some(ref attribute) => { match *attribute.r().value() { @@ -1130,7 +1122,7 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> { } } -impl<'a> ElementMethods for JSRef<'a, Element> { +impl<'a> ElementMethods for &'a Element { // https://dom.spec.whatwg.org/#dom-element-namespaceuri fn GetNamespaceURI(self) -> Option<DOMString> { match self.namespace { @@ -1185,25 +1177,25 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // https://dom.spec.whatwg.org/#dom-element-classlist - fn ClassList(self) -> Temporary<DOMTokenList> { + fn ClassList(self) -> Root<DOMTokenList> { self.class_list.or_init(|| DOMTokenList::new(self, &atom!("class"))) } // https://dom.spec.whatwg.org/#dom-element-attributes - fn Attributes(self) -> Temporary<NamedNodeMap> { + fn Attributes(self) -> Root<NamedNodeMap> { self.attr_list.or_init(|| { let doc = { - let node: JSRef<Node> = NodeCast::from_ref(self); - node.owner_doc().root() + let node = NodeCast::from_ref(self); + node.owner_doc() }; - let window = doc.r().window().root(); + let window = doc.r().window(); NamedNodeMap::new(window.r(), self) }) } // https://dom.spec.whatwg.org/#dom-element-getattribute fn GetAttribute(self, name: DOMString) -> Option<DOMString> { - self.get_attribute_by_name(name).root() + self.get_attribute_by_name(name) .map(|s| s.r().Value()) } @@ -1212,7 +1204,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString> { let namespace = &namespace::from_domstring(namespace); - self.get_attribute(namespace, &Atom::from_slice(&local_name)).root() + self.get_attribute(namespace, &Atom::from_slice(&local_name)) .map(|attr| attr.r().Value()) } @@ -1282,28 +1274,28 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // https://dom.spec.whatwg.org/#dom-element-getelementsbytagname - fn GetElementsByTagName(self, localname: DOMString) -> Temporary<HTMLCollection> { - let window = window_from_node(self).root(); + fn GetElementsByTagName(self, localname: DOMString) -> Root<HTMLCollection> { + let window = window_from_node(self); HTMLCollection::by_tag_name(window.r(), NodeCast::from_ref(self), localname) } // https://dom.spec.whatwg.org/#dom-element-getelementsbytagnamens fn GetElementsByTagNameNS(self, maybe_ns: Option<DOMString>, - localname: DOMString) -> Temporary<HTMLCollection> { - let window = window_from_node(self).root(); + localname: DOMString) -> Root<HTMLCollection> { + let window = window_from_node(self); HTMLCollection::by_tag_name_ns(window.r(), NodeCast::from_ref(self), localname, maybe_ns) } // https://dom.spec.whatwg.org/#dom-element-getelementsbyclassname - fn GetElementsByClassName(self, classes: DOMString) -> Temporary<HTMLCollection> { - let window = window_from_node(self).root(); + fn GetElementsByClassName(self, classes: DOMString) -> Root<HTMLCollection> { + let window = window_from_node(self); HTMLCollection::by_class_name(window.r(), NodeCast::from_ref(self), classes) } // http://dev.w3.org/csswg/cssom-view/#dom-element-getclientrects - fn GetClientRects(self) -> Temporary<DOMRectList> { - let win = window_from_node(self).root(); - let node: JSRef<Node> = NodeCast::from_ref(self); + fn GetClientRects(self) -> Root<DOMRectList> { + let win = window_from_node(self); + let node = NodeCast::from_ref(self); let raw_rects = node.get_content_boxes(); let rects = raw_rects.iter().map(|rect| { DOMRect::new(win.r(), @@ -1314,9 +1306,9 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // http://dev.w3.org/csswg/cssom-view/#dom-element-getboundingclientrect - fn GetBoundingClientRect(self) -> Temporary<DOMRect> { - let win = window_from_node(self).root(); - let node: JSRef<Node> = NodeCast::from_ref(self); + fn GetBoundingClientRect(self) -> Root<DOMRect> { + let win = window_from_node(self); + let node = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); DOMRect::new( win.r(), @@ -1334,11 +1326,11 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-innerHTML fn SetInnerHTML(self, value: DOMString) -> Fallible<()> { - let context_node: JSRef<Node> = NodeCast::from_ref(self); + let context_node = NodeCast::from_ref(self); // Step 1. let frag = try!(context_node.parse_fragment(value)); // Step 2. - Node::replace_all(Some(NodeCast::from_ref(frag.root().r())), context_node); + Node::replace_all(Some(NodeCast::from_ref(frag.r())), context_node); Ok(()) } @@ -1349,8 +1341,8 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML fn SetOuterHTML(self, value: DOMString) -> Fallible<()> { - let context_document = document_from_node(self).root(); - let context_node: JSRef<Node> = NodeCast::from_ref(self); + let context_document = document_from_node(self); + let context_node = NodeCast::from_ref(self); // Step 1. let context_parent = match context_node.GetParentNode() { None => { @@ -1358,7 +1350,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { return Ok(()); }, Some(parent) => parent, - }.root(); + }; let parent = match context_parent.r().type_id() { // Step 3. @@ -1369,45 +1361,45 @@ impl<'a> ElementMethods for JSRef<'a, Element> { let body_elem = Element::create(QualName::new(ns!(HTML), atom!(body)), None, context_document.r(), ElementCreator::ScriptCreated); - NodeCast::from_temporary(body_elem) + NodeCast::from_root(body_elem) }, _ => context_node.GetParentNode().unwrap() - }.root(); + }; // Step 5. let frag = try!(parent.r().parse_fragment(value)); // Step 6. - try!(context_parent.r().ReplaceChild(NodeCast::from_ref(frag.root().r()), + try!(context_parent.r().ReplaceChild(NodeCast::from_ref(frag.r()), context_node)); Ok(()) } // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling - fn GetPreviousElementSibling(self) -> Option<Temporary<Element>> { + fn GetPreviousElementSibling(self) -> Option<Root<Element>> { NodeCast::from_ref(self).preceding_siblings() - .filter_map(ElementCast::to_temporary).next() + .filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling - fn GetNextElementSibling(self) -> Option<Temporary<Element>> { + fn GetNextElementSibling(self) -> Option<Root<Element>> { NodeCast::from_ref(self).following_siblings() - .filter_map(ElementCast::to_temporary).next() + .filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-parentnode-children - fn Children(self) -> Temporary<HTMLCollection> { - let window = window_from_node(self).root(); + fn Children(self) -> Root<HTMLCollection> { + let window = window_from_node(self); HTMLCollection::children(window.r(), NodeCast::from_ref(self)) } // https://dom.spec.whatwg.org/#dom-parentnode-firstelementchild - fn GetFirstElementChild(self) -> Option<Temporary<Element>> { + fn GetFirstElementChild(self) -> Option<Root<Element>> { NodeCast::from_ref(self).child_elements().next() } // https://dom.spec.whatwg.org/#dom-parentnode-lastelementchild - fn GetLastElementChild(self) -> Option<Temporary<Element>> { - NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_temporary).next() + fn GetLastElementChild(self) -> Option<Root<Element>> { + NodeCast::from_ref(self).rev_children().filter_map(ElementCast::to_root).next() } // https://dom.spec.whatwg.org/#dom-parentnode-childelementcount @@ -1426,14 +1418,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } // https://dom.spec.whatwg.org/#dom-parentnode-queryselector - fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> { + let root = NodeCast::from_ref(self); root.query_selector(selectors) } // https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall - fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> { - let root: JSRef<Node> = NodeCast::from_ref(self); + fn QuerySelectorAll(self, selectors: DOMString) -> Fallible<Root<NodeList>> { + let root = NodeCast::from_ref(self); root.query_selector_all(selectors) } @@ -1454,7 +1446,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // https://dom.spec.whatwg.org/#dom-childnode-remove fn Remove(self) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.remove_self(); } @@ -1463,23 +1455,22 @@ impl<'a> ElementMethods for JSRef<'a, Element> { match parse_author_origin_selector_list_from_str(&selectors) { Err(()) => Err(Syntax), Ok(ref selectors) => { - let root: JSRef<Node> = NodeCast::from_ref(self); + let root = NodeCast::from_ref(self); Ok(matches(selectors, &root, &mut None)) } } } // https://dom.spec.whatwg.org/#dom-element-closest - fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { + fn Closest(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> { match parse_author_origin_selector_list_from_str(&selectors) { Err(()) => Err(Syntax), Ok(ref selectors) => { - let root: JSRef<Node> = NodeCast::from_ref(self); + let root = NodeCast::from_ref(self); for element in root.inclusive_ancestors() { - let element = element.root(); if let Some(element) = ElementCast::to_ref(element.r()) { if matches(selectors, &NodeCast::from_ref(element), &mut None) { - return Ok(Some(Temporary::from_rooted(element))); + return Ok(Some(Root::from_ref(element))); } } } @@ -1489,22 +1480,22 @@ impl<'a> ElementMethods for JSRef<'a, Element> { } } -impl<'a> VirtualMethods for JSRef<'a, Element> { +impl<'a> VirtualMethods for &'a Element { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let node: &JSRef<Node> = NodeCast::from_borrowed_ref(self); + let node: &&Node = NodeCast::from_borrowed_ref(self); Some(node as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); match attr.local_name() { &atom!("style") => { // Modifying the `style` attribute might change style. - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); let base_url = doc.r().url(); let value = attr.value(); let style = Some(parse_style_attribute(&value, &base_url)); @@ -1517,7 +1508,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { &atom!("class") => { // Modifying a class can change style. if node.is_in_doc() { - let document = document_from_node(*self).root(); + let document = document_from_node(*self); document.r().content_changed(node, NodeDamage::NodeStyleDamaged); } } @@ -1525,7 +1516,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { // Modifying an ID might change style. let value = attr.value(); if node.is_in_doc() { - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); if !value.is_empty() { let value = value.atom().unwrap().clone(); doc.r().register_named_element(*self, value); @@ -1536,26 +1527,26 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { _ => { // Modifying any other attribute might change arbitrary things. if node.is_in_doc() { - let document = document_from_node(*self).root(); + let document = document_from_node(*self); document.r().content_changed(node, NodeDamage::OtherNodeDamage); } } } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); match attr.local_name() { &atom!("style") => { // Modifying the `style` attribute might change style. *self.style_attribute.borrow_mut() = None; if node.is_in_doc() { - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); doc.r().content_changed(node, NodeDamage::NodeStyleDamaged); } } @@ -1563,7 +1554,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { // Modifying an ID can change style. let value = attr.value(); if node.is_in_doc() { - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); if !value.is_empty() { let value = value.atom().unwrap().clone(); doc.r().unregister_named_element(*self, value); @@ -1574,14 +1565,14 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { &atom!("class") => { // Modifying a class can change style. if node.is_in_doc() { - let document = document_from_node(*self).root(); + let document = document_from_node(*self); document.r().content_changed(node, NodeDamage::NodeStyleDamaged); } } _ => { // Modifying any other attribute might change arbitrary things. if node.is_in_doc() { - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); doc.r().content_changed(node, NodeDamage::OtherNodeDamage); } } @@ -1603,8 +1594,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { if !tree_in_doc { return; } - if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")).root() { - let doc = document_from_node(*self).root(); + if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) { + let doc = document_from_node(*self); let value = attr.r().Value(); if !value.is_empty() { let value = Atom::from_slice(&value); @@ -1620,8 +1611,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { if !tree_in_doc { return; } - if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")).root() { - let doc = document_from_node(*self).root(); + if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("id")) { + let doc = document_from_node(*self); let value = attr.r().Value(); if !value.is_empty() { let value = Atom::from_slice(&value); @@ -1631,10 +1622,10 @@ impl<'a> VirtualMethods for JSRef<'a, Element> { } } -impl<'a> style::node::TElement<'a> for JSRef<'a, Element> { +impl<'a> style::node::TElement<'a> for &'a Element { fn is_link(self) -> bool { // FIXME: This is HTML only. - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); match node.type_id() { // https://html.spec.whatwg.org/multipage/#selector-link NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | @@ -1675,19 +1666,18 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> { get_namespace(self) } fn get_hover_state(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.get_hover_state() } fn get_focus_state(self) -> bool { // TODO: Also check whether the top-level browsing context has the system focus, // and whether this element is a browsing context container. // https://html.spec.whatwg.org/multipage/#selector-focus - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.get_focus_state() } fn get_id(self) -> Option<Atom> { self.get_attribute(&ns!(""), &atom!("id")).map(|attr| { - let attr = attr.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -1698,22 +1688,22 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> { }) } fn get_disabled_state(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.get_disabled_state() } fn get_enabled_state(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.get_enabled_state() } fn get_checked_state(self) -> bool { - let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); + let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self); match input_element { Some(input) => input.Checked(), None => false, } } fn get_indeterminate_state(self) -> bool { - let input_element: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); + let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self); match input_element { Some(input) => input.get_indeterminate_state(), None => false, @@ -1731,7 +1721,7 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> { fn each_class<F>(self, mut callback: F) where F: FnMut(&Atom) { - if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("class")).root() { + if let Some(ref attr) = self.get_attribute(&ns!(""), &atom!("class")) { if let Some(tokens) = attr.r().value().tokens() { for token in tokens { callback(token) @@ -1740,7 +1730,7 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> { } } fn has_nonzero_border(self) -> bool { - let table_element: Option<JSRef<HTMLTableElement>> = HTMLTableElementCast::to_ref(self); + let table_element: Option<&HTMLTableElement> = HTMLTableElementCast::to_ref(self); match table_element { None => false, Some(this) => { @@ -1757,20 +1747,20 @@ pub trait ActivationElementHelpers<'a> { fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)>; fn click_in_progress(self) -> bool; fn set_click_in_progress(self, click: bool); - fn nearest_activable_element(self) -> Option<Temporary<Element>>; - fn authentic_click_activation<'b>(self, event: JSRef<'b, Event>); + fn nearest_activable_element(self) -> Option<Root<Element>>; + fn authentic_click_activation<'b>(self, event: &'b Event); } -impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> { +impl<'a> ActivationElementHelpers<'a> for &'a Element { fn as_maybe_activatable(&'a self) -> Option<&'a (Activatable + 'a)> { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); let element = match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { - let element: &'a JSRef<'a, HTMLInputElement> = HTMLInputElementCast::to_borrowed_ref(self).unwrap(); + let element = HTMLInputElementCast::to_borrowed_ref(self).unwrap(); Some(element as &'a (Activatable + 'a)) }, NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => { - let element: &'a JSRef<'a, HTMLAnchorElement> = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap(); + let element = HTMLAnchorElementCast::to_borrowed_ref(self).unwrap(); Some(element as &'a (Activatable + 'a)) }, _ => { @@ -1787,26 +1777,25 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> { } fn click_in_progress(self) -> bool { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.get_flag(CLICK_IN_PROGRESS) } fn set_click_in_progress(self, click: bool) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.set_flag(CLICK_IN_PROGRESS, click) } // https://html.spec.whatwg.org/multipage/#nearest-activatable-element - fn nearest_activable_element(self) -> Option<Temporary<Element>> { + fn nearest_activable_element(self) -> Option<Root<Element>> { match self.as_maybe_activatable() { - Some(el) => Some(Temporary::from_rooted(el.as_element().root().r())), + Some(el) => Some(Root::from_ref(el.as_element())), None => { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); for node in node.ancestors() { - let node = node.root(); if let Some(node) = ElementCast::to_ref(node.r()) { if node.as_maybe_activatable().is_some() { - return Some(Temporary::from_rooted(node)) + return Some(Root::from_ref(node)) } } } @@ -1821,19 +1810,19 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> { /// /// Use an element's synthetic click activation (or handle_event) for any script-triggered clicks. /// If the spec says otherwise, check with Manishearth first - fn authentic_click_activation<'b>(self, event: JSRef<'b, Event>) { + fn authentic_click_activation<'b>(self, event: &'b Event) { // Not explicitly part of the spec, however this helps enforce the invariants // required to save state between pre-activation and post-activation // since we cannot nest authentic clicks (unlike synthetic click activation, where // the script can generate more click events from the handler) assert!(!self.click_in_progress()); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let target = EventTargetCast::from_ref(self); // Step 2 (requires canvas support) // Step 3 self.set_click_in_progress(true); // Step 4 - let e = self.nearest_activable_element().root(); + let e = self.nearest_activable_element(); match e { Some(ref el) => match el.r().as_maybe_activatable() { Some(elem) => { diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs index a43dd368505..7d86e0e7921 100644 --- a/components/script/dom/errorevent.rs +++ b/components/script/dom/errorevent.rs @@ -8,8 +8,8 @@ use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, ErrorEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, MutHeap, Rootable, Temporary}; -use js::jsapi::JSContext; +use dom::bindings::js::{Root, MutHeapJSVal}; +use js::jsapi::{JSContext, HandleValue}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::reflect_dom_object; @@ -18,8 +18,8 @@ use util::str::DOMString; use dom::bindings::cell::DOMRefCell; use std::borrow::ToOwned; -use std::cell::{Cell}; -use js::jsval::{JSVal, NullValue}; +use std::cell::Cell; +use js::jsval::JSVal; #[dom_struct] pub struct ErrorEvent { @@ -28,7 +28,7 @@ pub struct ErrorEvent { filename: DOMRefCell<DOMString>, lineno: Cell<u32>, colno: Cell<u32>, - error: MutHeap<JSVal>, + error: MutHeapJSVal, } impl ErrorEventDerived for Event { @@ -45,11 +45,11 @@ impl ErrorEvent { filename: DOMRefCell::new("".to_owned()), lineno: Cell::new(0), colno: Cell::new(0), - error: MutHeap::new(NullValue()) + error: MutHeapJSVal::new() } } - pub fn new_uninitialized(global: GlobalRef) -> Temporary<ErrorEvent> { + pub fn new_uninitialized(global: GlobalRef) -> Root<ErrorEvent> { reflect_dom_object(box ErrorEvent::new_inherited(EventTypeId::ErrorEvent), global, ErrorEventBinding::Wrap) @@ -63,24 +63,26 @@ impl ErrorEvent { filename: DOMString, lineno: u32, colno: u32, - error: JSVal) -> Temporary<ErrorEvent> { - let ev = ErrorEvent::new_uninitialized(global).root(); - let event: JSRef<Event> = EventCast::from_ref(ev.r()); - event.InitEvent(type_, bubbles == EventBubbles::Bubbles, - cancelable == EventCancelable::Cancelable); + error: HandleValue) -> Root<ErrorEvent> { + let ev = ErrorEvent::new_uninitialized(global); // FIXME(https://github.com/rust-lang/rust/issues/23338) - let ev = ev.r(); - *ev.message.borrow_mut() = message; - *ev.filename.borrow_mut() = filename; - ev.lineno.set(lineno); - ev.colno.set(colno); - ev.error.set(error); - Temporary::from_rooted(ev) + { + let ev = ev.r(); + let event = EventCast::from_ref(ev); + event.InitEvent(type_, bubbles == EventBubbles::Bubbles, + cancelable == EventCancelable::Cancelable); + *ev.message.borrow_mut() = message; + *ev.filename.borrow_mut() = filename; + ev.lineno.set(lineno); + ev.colno.set(colno); + } + ev.error.set(error.get()); + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Temporary<ErrorEvent>>{ + init: &ErrorEventBinding::ErrorEventInit) -> Fallible<Root<ErrorEvent>>{ let msg = match init.message.as_ref() { Some(message) => message.clone(), None => "".to_owned(), @@ -106,13 +108,14 @@ impl ErrorEvent { let event = ErrorEvent::new(global, type_, bubbles, cancelable, msg, file_name, - line_num, col_num, init.error); + line_num, col_num, + HandleValue { ptr: &init.error }); Ok(event) } } -impl<'a> ErrorEventMethods for JSRef<'a, ErrorEvent> { +impl<'a> ErrorEventMethods for &'a ErrorEvent { fn Lineno(self) -> u32 { self.lineno.get() } diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 012742a0d7b..ebaaec09033 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::EventBinding; use dom::bindings::codegen::Bindings::EventBinding::{EventConstants, EventMethods}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary}; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::eventtarget::{EventTarget, EventTargetHelpers}; use util::str::DOMString; @@ -95,7 +95,7 @@ impl Event { } } - pub fn new_uninitialized(global: GlobalRef) -> Temporary<Event> { + pub fn new_uninitialized(global: GlobalRef) -> Root<Event> { reflect_dom_object(box Event::new_inherited(EventTypeId::HTMLEvent), global, EventBinding::Wrap) @@ -104,15 +104,15 @@ impl Event { pub fn new(global: GlobalRef, type_: DOMString, bubbles: EventBubbles, - cancelable: EventCancelable) -> Temporary<Event> { - let event = Event::new_uninitialized(global).root(); + cancelable: EventCancelable) -> Root<Event> { + let event = Event::new_uninitialized(global); event.r().InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable); - Temporary::from_rooted(event.r()) + event } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &EventBinding::EventInit) -> Fallible<Temporary<Event>> { + init: &EventBinding::EventInit) -> Fallible<Root<Event>> { let bubbles = if init.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble }; let cancelable = if init.cancelable { EventCancelable::Cancelable } else { EventCancelable::NotCancelable }; Ok(Event::new(global, type_, bubbles, cancelable)) @@ -129,13 +129,13 @@ impl Event { } #[inline] - pub fn set_current_target(&self, val: JSRef<EventTarget>) { - self.current_target.set(Some(JS::from_rooted(val))); + pub fn set_current_target(&self, val: &EventTarget) { + self.current_target.set(Some(JS::from_ref(val))); } #[inline] - pub fn set_target(&self, val: JSRef<EventTarget>) { - self.target.set(Some(JS::from_rooted(val))); + pub fn set_target(&self, val: &EventTarget) { + self.target.set(Some(JS::from_ref(val))); } #[inline] @@ -174,7 +174,7 @@ impl Event { } } -impl<'a> EventMethods for JSRef<'a, Event> { +impl<'a> EventMethods for &'a Event { // https://dom.spec.whatwg.org/#dom-event-eventphase fn EventPhase(self) -> u16 { self.phase.get() as u16 @@ -188,13 +188,13 @@ impl<'a> EventMethods for JSRef<'a, Event> { } // https://dom.spec.whatwg.org/#dom-event-target - fn GetTarget(self) -> Option<Temporary<EventTarget>> { - self.target.get().map(Temporary::from_rooted) + fn GetTarget(self) -> Option<Root<EventTarget>> { + self.target.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-event-currenttarget - fn GetCurrentTarget(self) -> Option<Temporary<EventTarget>> { - self.current_target.get().map(Temporary::from_rooted) + fn GetCurrentTarget(self) -> Option<Root<EventTarget>> { + self.current_target.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-event-defaultprevented @@ -263,16 +263,16 @@ impl<'a> EventMethods for JSRef<'a, Event> { pub trait EventHelpers { fn set_trusted(self, trusted: bool); - fn fire(self, target: JSRef<EventTarget>) -> bool; + fn fire(self, target: &EventTarget) -> bool; } -impl<'a> EventHelpers for JSRef<'a, Event> { +impl<'a> EventHelpers for &'a Event { fn set_trusted(self, trusted: bool) { self.trusted.set(trusted); } // https://html.spec.whatwg.org/multipage/#fire-a-simple-event - fn fire(self, target: JSRef<EventTarget>) -> bool { + fn fire(self, target: &EventTarget) -> bool { self.set_trusted(true); target.dispatch_event(self) } diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index ca534ba0389..8633f63df7c 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -5,7 +5,7 @@ use dom::bindings::callback::ExceptionHandling::Report; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast}; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Rootable}; +use dom::bindings::js::JS; use dom::bindings::trace::RootedVec; use dom::eventtarget::{EventTarget, ListenerPhase}; use dom::event::{Event, EventPhase}; @@ -13,9 +13,9 @@ use dom::node::{Node, NodeHelpers}; use dom::virtualmethods::vtable_for; // See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm -pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, - pseudo_target: Option<JSRef<'b, EventTarget>>, - event: JSRef<Event>) -> bool { +pub fn dispatch_event<'a, 'b>(target: &'a EventTarget, + pseudo_target: Option<&'b EventTarget>, + event: &Event) -> bool { assert!(!event.dispatching()); assert!(event.initialized()); @@ -31,9 +31,8 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new(); if let Some(target_node) = NodeCast::to_ref(target) { for ancestor in target_node.ancestors() { - let ancestor = ancestor.root(); let ancestor_target = EventTargetCast::from_ref(ancestor.r()); - chain.push(JS::from_rooted(ancestor_target)) + chain.push(JS::from_ref(ancestor_target)) } } @@ -113,10 +112,10 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, } /* default action */ - let target = event.GetTarget().root(); + let target = event.GetTarget(); match target { Some(ref target) => { - let node: Option<JSRef<Node>> = NodeCast::to_ref(target.r()); + let node: Option<&Node> = NodeCast::to_ref(target.r()); match node { Some(node) => { let vtable = vtable_for(&node); diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 57ee6e31e50..bbb26623052 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -9,7 +9,6 @@ use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener; use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; use dom::bindings::error::{Fallible, report_pending_exception}; use dom::bindings::error::Error::InvalidState; -use dom::bindings::js::JSRef; use dom::bindings::utils::{Reflectable, Reflector}; use dom::event::{Event, EventHelpers}; use dom::eventdispatcher::dispatch_event; @@ -17,8 +16,10 @@ use dom::node::NodeTypeId; use dom::workerglobalscope::WorkerGlobalScopeTypeId; use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTargetTypeId; use dom::virtualmethods::VirtualMethods; -use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObject}; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{CompileFunction, JS_GetFunctionObject}; +use js::jsapi::{JSContext, RootedFunction, HandleObject}; +use js::jsapi::{JSAutoCompartment, JSAutoRequest}; +use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper}; use util::str::DOMString; use fnv::FnvHasher; @@ -30,6 +31,7 @@ use std::default::Default; use std::ffi::CString; use std::intrinsics; use std::ptr; +use std::rc::Rc; use url::Url; use std::collections::HashMap; @@ -88,23 +90,23 @@ impl EventTargetTypeId { } } -#[derive(Copy, Clone, PartialEq)] +#[derive(Clone, PartialEq)] #[jstraceable] pub enum EventListenerType { - Additive(EventListener), - Inline(EventListener), + Additive(Rc<EventListener>), + Inline(Rc<EventListener>), } impl EventListenerType { - fn get_listener(&self) -> EventListener { + fn get_listener(&self) -> Rc<EventListener> { match *self { - EventListenerType::Additive(listener) | - EventListenerType::Inline(listener) => listener + EventListenerType::Additive(ref listener) | + EventListenerType::Inline(ref listener) => listener.clone(), } } } -#[derive(Copy, Clone, PartialEq)] +#[derive(Clone, PartialEq)] #[jstraceable] #[privatize] pub struct EventListenerEntry { @@ -128,14 +130,14 @@ impl EventTarget { } } - pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListener>> { + pub fn get_listeners(&self, type_: &str) -> Option<Vec<Rc<EventListener>>> { self.handlers.borrow().get(type_).map(|listeners| { listeners.iter().map(|entry| entry.listener.get_listener()).collect() }) } pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase) - -> Option<Vec<EventListener>> { + -> Option<Vec<Rc<EventListener>>> { self.handlers.borrow().get(type_).map(|listeners| { let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase); filtered.map(|entry| entry.listener.get_listener()).collect() @@ -150,47 +152,47 @@ impl EventTarget { pub trait EventTargetHelpers { fn dispatch_event_with_target(self, - target: JSRef<EventTarget>, - event: JSRef<Event>) -> bool; - fn dispatch_event(self, event: JSRef<Event>) -> bool; + target: &EventTarget, + event: &Event) -> bool; + fn dispatch_event(self, event: &Event) -> bool; fn set_inline_event_listener(self, ty: DOMString, - listener: Option<EventListener>); - fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener>; + listener: Option<Rc<EventListener>>); + fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>>; fn set_event_handler_uncompiled(self, cx: *mut JSContext, url: Url, - scope: *mut JSObject, + scope: HandleObject, ty: &str, source: DOMString); fn set_event_handler_common<T: CallbackContainer>(self, ty: &str, - listener: Option<T>); - fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T>; + listener: Option<Rc<T>>); + fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>>; fn has_handlers(self) -> bool; } -impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { +impl<'a> EventTargetHelpers for &'a EventTarget { fn dispatch_event_with_target(self, - target: JSRef<EventTarget>, - event: JSRef<Event>) -> bool { + target: &EventTarget, + event: &Event) -> bool { dispatch_event(self, Some(target), event) } - fn dispatch_event(self, event: JSRef<Event>) -> bool { + fn dispatch_event(self, event: &Event) -> bool { dispatch_event(self, None, event) } fn set_inline_event_listener(self, ty: DOMString, - listener: Option<EventListener>) { + listener: Option<Rc<EventListener>>) { let mut handlers = self.handlers.borrow_mut(); let entries = match handlers.entry(ty) { Occupied(entry) => entry.into_mut(), Vacant(entry) => entry.insert(vec!()), }; - let idx = entries.iter().position(|&entry| { + let idx = entries.iter().position(|ref entry| { match entry.listener { EventListenerType::Inline(_) => true, _ => false, @@ -217,7 +219,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { } } - fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener> { + fn get_inline_event_listener(self, ty: DOMString) -> Option<Rc<EventListener>> { let handlers = self.handlers.borrow(); let entries = handlers.get(&ty); entries.and_then(|entries| entries.iter().find(|entry| { @@ -232,7 +234,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { fn set_event_handler_uncompiled(self, cx: *mut JSContext, url: Url, - scope: *mut JSObject, + scope: HandleObject, ty: &str, source: DOMString) { let url = CString::new(url.serialize()).unwrap(); @@ -243,38 +245,42 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { static mut ARG_NAMES: [*const c_char; 1] = [b"event\0" as *const u8 as *const c_char]; let source: Vec<u16> = source.utf16_units().collect(); - let handler = unsafe { - JS_CompileUCFunction(cx, - ptr::null_mut(), - name.as_ptr(), - nargs, - ARG_NAMES.as_mut_ptr(), - source.as_ptr(), - source.len() as size_t, - url.as_ptr(), - lineno) + let options = CompileOptionsWrapper::new(cx, url.as_ptr(), lineno); + let scopechain = AutoObjectVectorWrapper::new(cx); + + let _ar = JSAutoRequest::new(cx); + let _ac = JSAutoCompartment::new(cx, scope.get()); + let mut handler = RootedFunction::new(cx, ptr::null_mut()); + let rv = unsafe { + CompileFunction(cx, + scopechain.ptr, + options.ptr, + name.as_ptr(), + nargs, + ARG_NAMES.as_mut_ptr(), + source.as_ptr() as *const i16, + source.len() as size_t, + handler.handle_mut()) }; - if handler.is_null() { - report_pending_exception(cx, self.reflector().get_jsobject()); + if rv == 0 || handler.ptr.is_null() { + report_pending_exception(cx, self.reflector().get_jsobject().get()); return; } - let funobj = unsafe { - JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope) - }; + let funobj = unsafe { JS_GetFunctionObject(handler.ptr) }; assert!(!funobj.is_null()); self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj))); } fn set_event_handler_common<T: CallbackContainer>( - self, ty: &str, listener: Option<T>) + self, ty: &str, listener: Option<Rc<T>>) { let event_listener = listener.map(|listener| EventListener::new(listener.callback())); self.set_inline_event_listener(ty.to_owned(), event_listener); } - fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T> { + fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<Rc<T>> { let listener = self.get_inline_event_listener(ty.to_owned()); listener.map(|listener| CallbackContainer::new(listener.parent.callback())) } @@ -286,10 +292,10 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> { } } -impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { +impl<'a> EventTargetMethods for &'a EventTarget { fn AddEventListener(self, ty: DOMString, - listener: Option<EventListener>, + listener: Option<Rc<EventListener>>, capture: bool) { match listener { Some(listener) => { @@ -314,17 +320,17 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { fn RemoveEventListener(self, ty: DOMString, - listener: Option<EventListener>, + listener: Option<Rc<EventListener>>, capture: bool) { match listener { - Some(listener) => { + Some(ref listener) => { let mut handlers = self.handlers.borrow_mut(); let mut entry = handlers.get_mut(&ty); for entry in entry.iter_mut() { let phase = if capture { ListenerPhase::Capturing } else { ListenerPhase::Bubbling }; let old_entry = EventListenerEntry { phase: phase, - listener: EventListenerType::Additive(listener) + listener: EventListenerType::Additive(listener.clone()) }; let position = entry.position_elem(&old_entry); for &position in position.iter() { @@ -336,7 +342,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { } } - fn DispatchEvent(self, event: JSRef<Event>) -> Fallible<bool> { + fn DispatchEvent(self, event: &Event) -> Fallible<bool> { if event.dispatching() || !event.initialized() { return Err(InvalidState); } @@ -345,7 +351,7 @@ impl<'a> EventTargetMethods for JSRef<'a, EventTarget> { } } -impl<'a> VirtualMethods for JSRef<'a, EventTarget> { +impl<'a> VirtualMethods for &'a EventTarget { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { None } diff --git a/components/script/dom/file.rs b/components/script/dom/file.rs index a592d336fb0..b95072b841c 100644 --- a/components/script/dom/file.rs +++ b/components/script/dom/file.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::FileBinding; use dom::bindings::codegen::Bindings::FileBinding::FileMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::blob::{Blob, BlobTypeId}; use util::str::DOMString; @@ -18,7 +18,7 @@ pub struct File { impl File { fn new_inherited(global: GlobalRef, type_: BlobTypeId, - _file_bits: JSRef<Blob>, name: DOMString) -> File { + _file_bits: &Blob, name: DOMString) -> File { File { //TODO: get type from the underlying filesystem instead of "".to_string() blob: Blob::new_inherited(global, type_, None, ""), @@ -28,7 +28,7 @@ impl File { // the relevant subfields of file_bits should be copied over } - pub fn new(global: GlobalRef, file_bits: JSRef<Blob>, name: DOMString) -> Temporary<File> { + pub fn new(global: GlobalRef, file_bits: &Blob, name: DOMString) -> Root<File> { reflect_dom_object(box File::new_inherited(global, BlobTypeId::File, file_bits, name), global, FileBinding::Wrap) @@ -39,7 +39,7 @@ impl File { } } -impl<'a> FileMethods for JSRef<'a, File> { +impl<'a> FileMethods for &'a File { fn Name(self) -> DOMString { self.name.clone() } diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs index 068c0b591a5..2c719e2c116 100644 --- a/components/script/dom/formdata.rs +++ b/components/script/dom/formdata.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::UnionTypes::FileOrString; use dom::bindings::codegen::UnionTypes::FileOrString::{eFile, eString}; use dom::bindings::error::{Fallible}; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JS, JSRef, Temporary, Unrooted}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::blob::Blob; use dom::file::File; @@ -38,29 +38,29 @@ pub struct FormData { } impl FormData { - fn new_inherited(form: Option<JSRef<HTMLFormElement>>, global: GlobalRef) -> FormData { + fn new_inherited(form: Option<&HTMLFormElement>, global: GlobalRef) -> FormData { FormData { reflector_: Reflector::new(), data: DOMRefCell::new(HashMap::new()), global: GlobalField::from_rooted(&global), - form: form.map(|f| JS::from_rooted(f)), + form: form.map(|f| JS::from_ref(f)), } } - pub fn new(form: Option<JSRef<HTMLFormElement>>, global: GlobalRef) -> Temporary<FormData> { + pub fn new(form: Option<&HTMLFormElement>, global: GlobalRef) -> Root<FormData> { reflect_dom_object(box FormData::new_inherited(form, global), global, FormDataBinding::Wrap) } - pub fn Constructor(global: GlobalRef, form: Option<JSRef<HTMLFormElement>>) -> Fallible<Temporary<FormData>> { + pub fn Constructor(global: GlobalRef, form: Option<&HTMLFormElement>) -> Fallible<Root<FormData>> { Ok(FormData::new(form, global)) } } -impl<'a> FormDataMethods for JSRef<'a, FormData> { +impl<'a> FormDataMethods for &'a FormData { #[allow(unrooted_must_root)] - fn Append(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) { - let file = FormDatum::FileData(JS::from_rooted(self.get_file_from_blob(value, filename))); + fn Append(self, name: DOMString, value: &Blob, filename: Option<DOMString>) { + let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename))); let mut data = self.data.borrow_mut(); match data.entry(name) { Occupied(entry) => entry.into_mut().push(file), @@ -90,7 +90,7 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> { match data[&name][0].clone() { FormDatum::StringData(ref s) => Some(eString(s.clone())), FormDatum::FileData(ref f) => { - Some(eFile(Unrooted::from_js(*f))) + Some(eFile(f.root())) } } } else { @@ -104,8 +104,8 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> { data.contains_key(&name) } #[allow(unrooted_must_root)] - fn Set(self, name: DOMString, value: JSRef<Blob>, filename: Option<DOMString>) { - let file = FormDatum::FileData(JS::from_rooted(self.get_file_from_blob(value, filename))); + fn Set(self, name: DOMString, value: &Blob, filename: Option<DOMString>) { + let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename))); self.data.borrow_mut().insert(name, vec!(file)); } @@ -115,13 +115,13 @@ impl<'a> FormDataMethods for JSRef<'a, FormData> { } trait PrivateFormDataHelpers{ - fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File>; + fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File>; } -impl PrivateFormDataHelpers for FormData { - fn get_file_from_blob(&self, value: JSRef<Blob>, filename: Option<DOMString>) -> Temporary<File> { +impl<'a> PrivateFormDataHelpers for &'a FormData { + fn get_file_from_blob(self, value: &Blob, filename: Option<DOMString>) -> Root<File> { let global = self.global.root(); - let f: Option<JSRef<File>> = FileCast::to_ref(value); + let f: Option<&File> = FileCast::to_ref(value); let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or("blob".to_owned())); File::new(global.r(), value, name) } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 21aff2de855..4e749ff6306 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -13,8 +13,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementDerived, HTMLImageElementDerived}; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; use dom::bindings::codegen::InheritTypes::{MouseEventCast, NodeCast}; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary}; -use dom::bindings::js::OptionalRootable; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::document::{Document, DocumentHelpers}; use dom::domtokenlist::DOMTokenList; use dom::element::{Element, AttributeHandlers, ElementTypeId}; @@ -47,7 +46,7 @@ impl HTMLAnchorElementDerived for EventTarget { impl HTMLAnchorElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLAnchorElement { + document: &Document) -> HTMLAnchorElement { HTMLAnchorElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLAnchorElement, localName, prefix, document), @@ -58,19 +57,19 @@ impl HTMLAnchorElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLAnchorElement> { + document: &Document) -> Root<HTMLAnchorElement> { let element = HTMLAnchorElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLAnchorElementBinding::Wrap) } } -impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> { +impl<'a> VirtualMethods for &'a HTMLAnchorElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn handle_event(&self, event: JSRef<Event>) { + fn handle_event(&self, event: &Event) { match self.super_type() { Some(s) => { s.handle_event(event); @@ -87,27 +86,27 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLAnchorElement> { } } -impl<'a> HTMLAnchorElementMethods for JSRef<'a, HTMLAnchorElement> { +impl<'a> HTMLAnchorElementMethods for &'a HTMLAnchorElement { fn Text(self) -> DOMString { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.GetTextContent().unwrap() } fn SetText(self, value: DOMString) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.SetTextContent(Some(value)) } - fn RelList(self) -> Temporary<DOMTokenList> { + fn RelList(self) -> Root<DOMTokenList> { self.rel_list.or_init(|| { DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel")) }) } } -impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> { - fn as_element(&self) -> Temporary<Element> { - Temporary::from_rooted(ElementCast::from_ref(*self)) +impl<'a> Activatable for &'a HTMLAnchorElement { + fn as_element<'b>(&'b self) -> &'b Element { + ElementCast::from_ref(*self) } fn is_instance_activatable(&self) -> bool { @@ -125,22 +124,22 @@ impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> { } //https://html.spec.whatwg.org/multipage/#the-a-element:activation-behaviour - fn activation_behavior(&self, event: JSRef<Event>, target: JSRef<EventTarget>) { + fn activation_behavior(&self, event: &Event, target: &EventTarget) { //Step 1. If the node document is not fully active, abort. - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); if !doc.r().is_fully_active() { return; } //TODO: Step 2. Check if browsing context is specified and act accordingly. //Step 3. Handle <img ismap/>. - let element: JSRef<Element> = ElementCast::from_ref(*self); + let element = ElementCast::from_ref(*self); let mouse_event = MouseEventCast::to_ref(event).unwrap(); let mut ismap_suffix = None; if let Some(element) = ElementCast::to_ref(target) { if target.is_htmlimageelement() && element.has_attribute(&atom!("ismap")) { let target_node = NodeCast::to_ref(target).unwrap(); - let rect = window_from_node(target_node).root().r().content_box_query( + let rect = window_from_node(target_node).r().content_box_query( target_node.to_trusted_node_address()); ismap_suffix = Some( format!("?{},{}", mouse_event.ClientX().to_f32().unwrap() - rect.origin.x.to_f32_px(), @@ -151,7 +150,7 @@ impl<'a> Activatable for JSRef<'a, HTMLAnchorElement> { //TODO: Step 4. Download the link is `download` attribute is set. - let attr = element.get_attribute(&ns!(""), &atom!("href")).root(); + let attr = element.get_attribute(&ns!(""), &atom!("href")); match attr { Some(ref href) => { let value = href.r().Value() + ismap_suffix.as_ref().map(|s| &**s).unwrap_or(""); diff --git a/components/script/dom/htmlappletelement.rs b/components/script/dom/htmlappletelement.rs index 66509384e60..108ee71e1bf 100644 --- a/components/script/dom/htmlappletelement.rs +++ b/components/script/dom/htmlappletelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLAppletElementBinding::HTMLAppletElemen use dom::attr::AttrValue; use dom::bindings::codegen::InheritTypes::HTMLAppletElementDerived; use dom::bindings::codegen::InheritTypes::HTMLElementCast; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::{AttributeHandlers, ElementTypeId}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -35,7 +35,7 @@ impl HTMLAppletElementDerived for EventTarget { impl HTMLAppletElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLAppletElement { + document: &Document) -> HTMLAppletElement { HTMLAppletElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLAppletElement, localName, prefix, document) @@ -45,19 +45,19 @@ impl HTMLAppletElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLAppletElement> { + document: &Document) -> Root<HTMLAppletElement> { let element = HTMLAppletElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLAppletElementBinding::Wrap) } } -impl<'a> HTMLAppletElementMethods for JSRef<'a, HTMLAppletElement> { +impl<'a> HTMLAppletElementMethods for &'a HTMLAppletElement { // https://html.spec.whatwg.org/#the-applet-element:dom-applet-name make_getter!(Name); make_atomic_setter!(SetName, "name"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLAppletElement> { +impl<'a> VirtualMethods for &'a HTMLAppletElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods) } diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index 1baa1379978..6229abaf686 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLAreaElementBinding; use dom::bindings::codegen::Bindings::HTMLAreaElementBinding::HTMLAreaElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLElementCast}; use dom::bindings::codegen::InheritTypes::ElementCast; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Temporary}; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::utils::Reflectable; use dom::document::Document; use dom::domtokenlist::DOMTokenList; @@ -36,7 +36,7 @@ impl HTMLAreaElementDerived for EventTarget { } impl HTMLAreaElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLAreaElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLAreaElement { HTMLAreaElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLAreaElement, localName, prefix, document), rel_list: Default::default(), @@ -46,15 +46,15 @@ impl HTMLAreaElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLAreaElement> { + document: &Document) -> Root<HTMLAreaElement> { let element = HTMLAreaElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLAreaElementBinding::Wrap) } } -impl<'a> VirtualMethods for JSRef<'a, HTMLAreaElement> { +impl<'a> VirtualMethods for &'a HTMLAreaElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } @@ -66,8 +66,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLAreaElement> { } } -impl<'a> HTMLAreaElementMethods for JSRef<'a, HTMLAreaElement> { - fn RelList(self) -> Temporary<DOMTokenList> { +impl<'a> HTMLAreaElementMethods for &'a HTMLAreaElement { + fn RelList(self) -> Root<DOMTokenList> { self.rel_list.or_init(|| { DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel")) }) diff --git a/components/script/dom/htmlaudioelement.rs b/components/script/dom/htmlaudioelement.rs index de0b38c22f8..8b7c86a3fe4 100644 --- a/components/script/dom/htmlaudioelement.rs +++ b/components/script/dom/htmlaudioelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLAudioElementBinding; use dom::bindings::codegen::InheritTypes::HTMLAudioElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -30,7 +30,7 @@ impl HTMLAudioElementDerived for EventTarget { impl HTMLAudioElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLAudioElement { + document: &Document) -> HTMLAudioElement { HTMLAudioElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLMediaElementTypeId::HTMLAudioElement, localName, prefix, document) @@ -40,7 +40,7 @@ impl HTMLAudioElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLAudioElement> { + document: &Document) -> Root<HTMLAudioElement> { let element = HTMLAudioElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLAudioElementBinding::Wrap) } diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs index e66969b7090..f1224d37097 100644 --- a/components/script/dom/htmlbaseelement.rs +++ b/components/script/dom/htmlbaseelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLBaseElementBinding; use dom::bindings::codegen::InheritTypes::HTMLBaseElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLBaseElementDerived for EventTarget { } impl HTMLBaseElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLBaseElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLBaseElement { HTMLBaseElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBaseElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLBaseElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLBaseElement> { + document: &Document) -> Root<HTMLBaseElement> { let element = HTMLBaseElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLBaseElementBinding::Wrap) } diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index fc2b0cf1d57..a7a71b49233 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLBodyElementBinding::{self, HTMLBodyEle use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast}; use dom::bindings::codegen::InheritTypes::{HTMLBodyElementDerived, HTMLElementCast}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::Reflectable; use dom::document::{Document, DocumentHelpers}; use dom::element::ElementTypeId; @@ -25,6 +25,7 @@ use util::str::{self, DOMString}; use std::borrow::ToOwned; use std::cell::Cell; +use std::rc::Rc; use time; /// How long we should wait before performing the initial reflow after `<body>` is parsed, in @@ -45,7 +46,7 @@ impl HTMLBodyElementDerived for EventTarget { } impl HTMLBodyElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLBodyElement { HTMLBodyElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBodyElement, @@ -57,43 +58,43 @@ impl HTMLBodyElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) - -> Temporary<HTMLBodyElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) + -> Root<HTMLBodyElement> { let element = HTMLBodyElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLBodyElementBinding::Wrap) } } -impl<'a> HTMLBodyElementMethods for JSRef<'a, HTMLBodyElement> { +impl<'a> HTMLBodyElementMethods for &'a HTMLBodyElement { // https://html.spec.whatwg.org/#dom-body-bgcolor make_getter!(BgColor, "bgcolor"); make_setter!(SetBgColor, "bgcolor"); - fn GetOnunload(self) -> Option<EventHandlerNonNull> { - let win = window_from_node(self).root(); + fn GetOnunload(self) -> Option<Rc<EventHandlerNonNull>> { + let win = window_from_node(self); win.r().GetOnunload() } - fn SetOnunload(self, listener: Option<EventHandlerNonNull>) { - let win = window_from_node(self).root(); + fn SetOnunload(self, listener: Option<Rc<EventHandlerNonNull>>) { + let win = window_from_node(self); win.r().SetOnunload(listener) } } pub trait HTMLBodyElementHelpers { - fn get_background_color(&self) -> Option<RGBA>; + fn get_background_color(self) -> Option<RGBA>; } -impl HTMLBodyElementHelpers for HTMLBodyElement { - fn get_background_color(&self) -> Option<RGBA> { +impl<'a> HTMLBodyElementHelpers for &'a HTMLBodyElement { + fn get_background_color(self) -> Option<RGBA> { self.background_color.get() } } -impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { +impl<'a> VirtualMethods for &'a HTMLBodyElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } @@ -106,15 +107,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { return } - let window = window_from_node(*self).root(); - let document = window.r().Document().root(); + let window = window_from_node(*self); + let document = window.r().Document(); document.r().set_reflow_timeout(time::precise_time_ns() + INITIAL_REFLOW_DELAY); let ConstellationChan(ref chan) = window.r().constellation_chan(); let event = ConstellationMsg::HeadParsed; chan.send(event).unwrap(); } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -126,11 +127,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { "onbeforeunload", "onhashchange", "onlanguagechange", "onmessage", "onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate", "onstorage", "onresize", "onunload", "onerror"]; - let window = window_from_node(*self).root(); + let window = window_from_node(*self); let (cx, url, reflector) = (window.r().get_cx(), window.r().get_url(), window.r().reflector().get_jsobject()); - let evtarget: JSRef<EventTarget> = + let evtarget = if FORWARDED_EVENTS.iter().any(|&event| &**name == event) { EventTargetCast::from_ref(window.r()) } else { @@ -149,7 +150,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { match self.super_type() { Some(ref s) => s.before_remove_attr(attr), _ => {} diff --git a/components/script/dom/htmlbrelement.rs b/components/script/dom/htmlbrelement.rs index b0e881e040b..8050a3fdef8 100644 --- a/components/script/dom/htmlbrelement.rs +++ b/components/script/dom/htmlbrelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLBRElementBinding; use dom::bindings::codegen::InheritTypes::HTMLBRElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLBRElementDerived for EventTarget { } impl HTMLBRElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLBRElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLBRElement { HTMLBRElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLBRElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLBRElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLBRElement> { + document: &Document) -> Root<HTMLBRElement> { let element = HTMLBRElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLBRElementBinding::Wrap) } diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 3bb7012cab4..426bf0f1cfe 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::HTMLButtonElementBinding; use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLButtonElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::{AttributeHandlers, Element, ElementTypeId}; use dom::element::ActivationElementHelpers; @@ -54,7 +54,7 @@ impl HTMLButtonElementDerived for EventTarget { impl HTMLButtonElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLButtonElement { + document: &Document) -> HTMLButtonElement { HTMLButtonElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLButtonElement, localName, prefix, document), @@ -66,15 +66,15 @@ impl HTMLButtonElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLButtonElement> { + document: &Document) -> Root<HTMLButtonElement> { let element = HTMLButtonElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLButtonElementBinding::Wrap) } } -impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { - fn Validity(self) -> Temporary<ValidityState> { - let window = window_from_node(self).root(); +impl<'a> HTMLButtonElementMethods for &'a HTMLButtonElement { + fn Validity(self) -> Root<ValidityState> { + let window = window_from_node(self); ValidityState::new(window.r()) } @@ -86,7 +86,7 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { // https://html.spec.whatwg.org/multipage/#dom-button-type fn Type(self) -> DOMString { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); let ty = elem.get_string_attribute(&atom!("type")).into_ascii_lowercase(); // https://html.spec.whatwg.org/multipage/#attr-button-type match &*ty { @@ -129,20 +129,20 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> { make_setter!(SetValue, "value"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { +impl<'a> VirtualMethods for &'a HTMLButtonElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); }, @@ -150,14 +150,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); node.check_ancestors_disabled_state_for_form_control(); @@ -171,7 +171,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { s.bind_to_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.check_ancestors_disabled_state_for_form_control(); } @@ -180,8 +180,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { s.unbind_from_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); - if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) { + let node = NodeCast::from_ref(*self); + if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { node.check_ancestors_disabled_state_for_form_control(); } else { node.check_disabled_attribute(); @@ -189,20 +189,20 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> { } } -impl<'a> FormControl<'a> for JSRef<'a, HTMLButtonElement> { - fn to_element(self) -> JSRef<'a, Element> { +impl<'a> FormControl<'a> for &'a HTMLButtonElement { + fn to_element(self) -> &'a Element { ElementCast::from_ref(self) } } -impl<'a> Activatable for JSRef<'a, HTMLButtonElement> { - fn as_element(&self) -> Temporary<Element> { - Temporary::from_rooted(ElementCast::from_ref(*self)) +impl<'a> Activatable for &'a HTMLButtonElement { + fn as_element<'b>(&'b self) -> &'b Element { + ElementCast::from_ref(*self) } fn is_instance_activatable(&self) -> bool { //https://html.spec.whatwg.org/multipage/#the-button-element - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); !(node.get_disabled_state()) } @@ -216,14 +216,14 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> { } // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps - fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) { + fn activation_behavior(&self, _event: &Event, _target: &EventTarget) { let ty = self.button_type.get(); match ty { //https://html.spec.whatwg.org/multipage/#attr-button-type-submit-state ButtonType::ButtonSubmit => { self.form_owner().map(|o| { - o.root().r().submit(SubmittedFrom::NotFromFormSubmitMethod, - FormSubmitter::ButtonElement(self.clone())) + o.r().submit(SubmittedFrom::NotFromFormSubmitMethod, + FormSubmitter::ButtonElement(self.clone())) }); }, _ => () @@ -233,10 +233,10 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> { // https://html.spec.whatwg.org/multipage/#implicit-submission #[allow(unsafe_code)] fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) { - let doc = document_from_node(*self).root(); - let node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let doc = document_from_node(*self); + let node = NodeCast::from_ref(doc.r()); let owner = self.form_owner(); - let elem: JSRef<Element> = ElementCast::from_ref(*self); + let elem = ElementCast::from_ref(*self); if owner.is_none() || elem.click_in_progress() { return; } @@ -244,8 +244,7 @@ impl<'a> Activatable for JSRef<'a, HTMLButtonElement> { // and only then performing actions which may modify the DOM tree unsafe { node.query_selector_iter("button[type=submit]".to_owned()).unwrap() - .filter_map(HTMLButtonElementCast::to_temporary) - .map(|t| t.root()) + .filter_map(HTMLButtonElementCast::to_root) .find(|r| r.r().form_owner() == owner) .map(|s| s.r().synthetic_click_activation(ctrlKey, shiftKey, altKey, metaKey)); } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 1b3c8261bd3..e27a9b7be26 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -12,13 +12,11 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap, HeapGCValue, Rootable}; -use dom::bindings::js::Temporary; -use dom::bindings::js::Unrooted; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, HeapGCValue, Root}; use dom::bindings::utils::{Reflectable}; use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers}; use dom::document::Document; -use dom::element::{Element, AttributeHandlers}; +use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; @@ -27,7 +25,7 @@ use dom::virtualmethods::VirtualMethods; use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderingContextHelpers}; use util::str::{DOMString, parse_unsigned_integer}; -use js::jsapi::{JSContext}; +use js::jsapi::{JSContext, HandleValue}; use js::jsval::JSVal; use offscreen_gl_context::GLContextAttributes; @@ -58,6 +56,12 @@ pub struct HTMLCanvasElement { height: Cell<u32>, } +impl PartialEq for HTMLCanvasElement { + fn eq(&self, other: &HTMLCanvasElement) -> bool { + self as *const HTMLCanvasElement == &*other + } +} + impl HTMLCanvasElementDerived for EventTarget { fn is_htmlcanvaselement(&self) -> bool { *self.type_id() == @@ -69,7 +73,7 @@ impl HTMLCanvasElementDerived for EventTarget { impl HTMLCanvasElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLCanvasElement { + document: &Document) -> HTMLCanvasElement { HTMLCanvasElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLCanvasElement, localName, prefix, document), @@ -82,7 +86,7 @@ impl HTMLCanvasElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLCanvasElement> { + document: &Document) -> Root<HTMLCanvasElement> { let element = HTMLCanvasElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap) } @@ -139,37 +143,37 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> { } pub trait HTMLCanvasElementHelpers { - fn get_or_init_2d_context(self) -> Option<Temporary<CanvasRenderingContext2D>>; + fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>>; fn get_or_init_webgl_context(self, cx: *mut JSContext, - attrs: Option<&JSVal>) -> Option<Temporary<WebGLRenderingContext>>; + attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>>; fn is_valid(self) -> bool; } -impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> { - fn get_or_init_2d_context(self) -> Option<Temporary<CanvasRenderingContext2D>> { +impl<'a> HTMLCanvasElementHelpers for &'a HTMLCanvasElement { + fn get_or_init_2d_context(self) -> Option<Root<CanvasRenderingContext2D>> { if self.context.get().is_none() { - let window = window_from_node(self).root(); + let window = window_from_node(self); let size = self.get_size(); let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size); - self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(context)))); + self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(&context)))); } match self.context.get().unwrap() { - CanvasContext::Context2d(context) => Some(Temporary::from_rooted(context)), + CanvasContext::Context2d(context) => Some(context.root()), _ => None, } } fn get_or_init_webgl_context(self, cx: *mut JSContext, - attrs: Option<&JSVal>) -> Option<Temporary<WebGLRenderingContext>> { + attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> { if self.context.get().is_none() { - let window = window_from_node(self).root(); + let window = window_from_node(self); let size = self.get_size(); let attrs = if let Some(webgl_attributes) = attrs { - if let Ok(ref attrs) = WebGLContextAttributes::new(cx, *webgl_attributes) { + if let Ok(ref attrs) = WebGLContextAttributes::new(cx, webgl_attributes) { From::from(attrs) } else { debug!("Unexpected error on conversion of WebGLContextAttributes"); @@ -181,12 +185,12 @@ impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> { let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs); - self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(ctx)))); + self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)))); } if let Some(context) = self.context.get() { match context { - CanvasContext::WebGL(context) => Some(Temporary::from_rooted(context)), + CanvasContext::WebGL(context) => Some(context.root()), _ => None, } } else { @@ -199,13 +203,13 @@ impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> { } } -impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { +impl<'a> HTMLCanvasElementMethods for &'a HTMLCanvasElement { fn Width(self) -> u32 { self.width.get() } fn SetWidth(self, width: u32) { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.set_uint_attribute(&atom!("width"), width) } @@ -214,38 +218,38 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { } fn SetHeight(self, height: u32) { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.set_uint_attribute(&atom!("height"), height) } fn GetContext(self, cx: *mut JSContext, id: DOMString, - attributes: Vec<JSVal>) + attributes: Vec<HandleValue>) -> Option<CanvasRenderingContext2DOrWebGLRenderingContext> { match &*id { "2d" => { self.get_or_init_2d_context() .map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D( - Unrooted::from_temporary(ctx))) + ctx)) } "webgl" | "experimental-webgl" => { - self.get_or_init_webgl_context(cx, attributes.get(0)) + self.get_or_init_webgl_context(cx, attributes.get(0).map(|p| *p)) .map(|ctx| CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext( - Unrooted::from_temporary(ctx))) + ctx)) } _ => None } } } -impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { +impl<'a> VirtualMethods for &'a HTMLCanvasElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let element: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let element: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } @@ -267,7 +271,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { } } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 68d8c9cf3e8..af33302f036 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLCollectionBinding; use dom::bindings::codegen::Bindings::HTMLCollectionBinding::HTMLCollectionMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::element::{Element, AttributeHandlers, ElementHelpers}; @@ -20,7 +20,7 @@ use std::iter::{FilterMap, Skip}; use string_cache::{Atom, Namespace}; pub trait CollectionFilter : JSTraceable { - fn filter<'a>(&self, elem: JSRef<'a, Element>, root: JSRef<'a, Node>) -> bool; + fn filter<'a>(&self, elem: &'a Element, root: &'a Node) -> bool; } #[jstraceable] @@ -44,26 +44,26 @@ impl HTMLCollection { } } - pub fn new(window: JSRef<Window>, collection: CollectionTypeId) -> Temporary<HTMLCollection> { + pub fn new(window: &Window, collection: CollectionTypeId) -> Root<HTMLCollection> { reflect_dom_object(box HTMLCollection::new_inherited(collection), GlobalRef::Window(window), HTMLCollectionBinding::Wrap) } } impl HTMLCollection { - pub fn create(window: JSRef<Window>, root: JSRef<Node>, - filter: Box<CollectionFilter+'static>) -> Temporary<HTMLCollection> { - HTMLCollection::new(window, CollectionTypeId::Live(JS::from_rooted(root), filter)) + pub fn create(window: &Window, root: &Node, + filter: Box<CollectionFilter+'static>) -> Root<HTMLCollection> { + HTMLCollection::new(window, CollectionTypeId::Live(JS::from_ref(root), filter)) } - fn all_elements(window: JSRef<Window>, root: JSRef<Node>, - namespace_filter: Option<Namespace>) -> Temporary<HTMLCollection> { + fn all_elements(window: &Window, root: &Node, + namespace_filter: Option<Namespace>) -> Root<HTMLCollection> { #[jstraceable] struct AllElementFilter { namespace_filter: Option<Namespace> } impl CollectionFilter for AllElementFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { match self.namespace_filter { None => true, Some(ref namespace) => *elem.namespace() == *namespace @@ -74,8 +74,8 @@ impl HTMLCollection { HTMLCollection::create(window, root, box filter) } - pub fn by_tag_name(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString) - -> Temporary<HTMLCollection> { + pub fn by_tag_name(window: &Window, root: &Node, tag: DOMString) + -> Root<HTMLCollection> { if tag == "*" { return HTMLCollection::all_elements(window, root, None); } @@ -86,7 +86,7 @@ impl HTMLCollection { ascii_lower_tag: Atom, } impl CollectionFilter for TagNameFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { if elem.html_element_in_html_document() { *elem.local_name() == self.ascii_lower_tag } else { @@ -101,8 +101,8 @@ impl HTMLCollection { HTMLCollection::create(window, root, box filter) } - pub fn by_tag_name_ns(window: JSRef<Window>, root: JSRef<Node>, tag: DOMString, - maybe_ns: Option<DOMString>) -> Temporary<HTMLCollection> { + pub fn by_tag_name_ns(window: &Window, root: &Node, tag: DOMString, + maybe_ns: Option<DOMString>) -> Root<HTMLCollection> { let namespace_filter = match maybe_ns { Some(ref namespace) if namespace == &"*" => None, ns => Some(namespace::from_domstring(ns)), @@ -117,7 +117,7 @@ impl HTMLCollection { namespace_filter: Option<Namespace> } impl CollectionFilter for TagNameNSFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { let ns_match = match self.namespace_filter { Some(ref namespace) => { *elem.namespace() == *namespace @@ -134,14 +134,14 @@ impl HTMLCollection { HTMLCollection::create(window, root, box filter) } - pub fn by_class_name(window: JSRef<Window>, root: JSRef<Node>, classes: DOMString) - -> Temporary<HTMLCollection> { + pub fn by_class_name(window: &Window, root: &Node, classes: DOMString) + -> Root<HTMLCollection> { #[jstraceable] struct ClassNameFilter { classes: Vec<Atom> } impl CollectionFilter for ClassNameFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { self.classes.iter().all(|class| elem.has_class(class)) } } @@ -153,30 +153,30 @@ impl HTMLCollection { HTMLCollection::create(window, root, box filter) } - pub fn children(window: JSRef<Window>, root: JSRef<Node>) -> Temporary<HTMLCollection> { + pub fn children(window: &Window, root: &Node) -> Root<HTMLCollection> { #[jstraceable] struct ElementChildFilter; impl CollectionFilter for ElementChildFilter { - fn filter(&self, elem: JSRef<Element>, root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, root: &Node) -> bool { root.is_parent_of(NodeCast::from_ref(elem)) } } HTMLCollection::create(window, root, box ElementChildFilter) } - fn traverse(root: JSRef<Node>) + fn traverse(root: &Node) -> FilterMap<Skip<TreeIterator>, - fn(Temporary<Node>) -> Option<Temporary<Element>>> { - fn to_temporary(node: Temporary<Node>) -> Option<Temporary<Element>> { - ElementCast::to_temporary(node) + fn(Root<Node>) -> Option<Root<Element>>> { + fn to_temporary(node: Root<Node>) -> Option<Root<Element>> { + ElementCast::to_root(node) } root.traverse_preorder() .skip(1) - .filter_map(to_temporary as fn(Temporary<Node>) -> Option<Temporary<Element>>) + .filter_map(to_temporary) } } -impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { +impl<'a> HTMLCollectionMethods for &'a HTMLCollection { // https://dom.spec.whatwg.org/#dom-htmlcollection-length fn Length(self) -> u32 { match self.collection { @@ -184,30 +184,29 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { CollectionTypeId::Live(ref root, ref filter) => { let root = root.root(); HTMLCollection::traverse(root.r()) - .filter(|element| filter.filter(element.root().r(), root.r())) + .filter(|element| filter.filter(element.r(), root.r())) .count() as u32 } } } // https://dom.spec.whatwg.org/#dom-htmlcollection-item - fn Item(self, index: u32) -> Option<Temporary<Element>> { + fn Item(self, index: u32) -> Option<Root<Element>> { let index = index as usize; match self.collection { CollectionTypeId::Static(ref elems) => elems - .get(index) - .map(|elem| Temporary::from_rooted(elem.clone())), + .get(index).map(|t| t.root()), CollectionTypeId::Live(ref root, ref filter) => { let root = root.root(); HTMLCollection::traverse(root.r()) - .filter(|element| filter.filter(element.root().r(), root.r())) + .filter(|element| filter.filter(element.r(), root.r())) .nth(index) } } } // https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem - fn NamedItem(self, key: DOMString) -> Option<Temporary<Element>> { + fn NamedItem(self, key: DOMString) -> Option<Root<Element>> { // Step 1. if key.is_empty() { return None; @@ -219,28 +218,25 @@ impl<'a> HTMLCollectionMethods for JSRef<'a, HTMLCollection> { .map(|elem| elem.root()) .find(|elem| { elem.r().get_string_attribute(&atom!("name")) == key || - elem.r().get_string_attribute(&atom!("id")) == key }) - .map(|maybe_elem| Temporary::from_rooted(maybe_elem.r())), + elem.r().get_string_attribute(&atom!("id")) == key }), CollectionTypeId::Live(ref root, ref filter) => { let root = root.root(); HTMLCollection::traverse(root.r()) - .map(|element| element.root()) .filter(|element| filter.filter(element.r(), root.r())) .find(|elem| { elem.r().get_string_attribute(&atom!("name")) == key || elem.r().get_string_attribute(&atom!("id")) == key }) - .map(|elem| Temporary::from_rooted(elem.r())) } } } - fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Element>> { + fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Element>> { let maybe_elem = self.Item(index); *found = maybe_elem.is_some(); maybe_elem } - fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Temporary<Element>> { + fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Element>> { let maybe_elem = self.NamedItem(name); *found = maybe_elem.is_some(); maybe_elem diff --git a/components/script/dom/htmldataelement.rs b/components/script/dom/htmldataelement.rs index 02148e319fb..e63d41f30a8 100644 --- a/components/script/dom/htmldataelement.rs +++ b/components/script/dom/htmldataelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLDataElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDataElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLDataElementDerived for EventTarget { impl HTMLDataElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLDataElement { + document: &Document) -> HTMLDataElement { HTMLDataElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataElement, localName, prefix, document) } @@ -37,7 +37,7 @@ impl HTMLDataElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDataElement> { + document: &Document) -> Root<HTMLDataElement> { let element = HTMLDataElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDataElementBinding::Wrap) } diff --git a/components/script/dom/htmldatalistelement.rs b/components/script/dom/htmldatalistelement.rs index d9bd35279ef..eeedeb1fa8d 100644 --- a/components/script/dom/htmldatalistelement.rs +++ b/components/script/dom/htmldatalistelement.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLDataListElementBinding; use dom::bindings::codegen::Bindings::HTMLDataListElementBinding::HTMLDataListElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLDataListElementDerived, HTMLOptionElementDerived}; use dom::bindings::codegen::InheritTypes::NodeCast; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::Element; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -32,7 +32,7 @@ impl HTMLDataListElementDerived for EventTarget { impl HTMLDataListElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLDataListElement { + document: &Document) -> HTMLDataListElement { HTMLDataListElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDataListElement, localName, prefix, document) @@ -42,24 +42,24 @@ impl HTMLDataListElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDataListElement> { + document: &Document) -> Root<HTMLDataListElement> { let element = HTMLDataListElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDataListElementBinding::Wrap) } } -impl<'a> HTMLDataListElementMethods for JSRef<'a, HTMLDataListElement> { - fn Options(self) -> Temporary<HTMLCollection> { +impl<'a> HTMLDataListElementMethods for &'a HTMLDataListElement { + fn Options(self) -> Root<HTMLCollection> { #[jstraceable] struct HTMLDataListOptionsFilter; impl CollectionFilter for HTMLDataListOptionsFilter { - fn filter(&self, elem: JSRef<Element>, _root: JSRef<Node>) -> bool { + fn filter(&self, elem: &Element, _root: &Node) -> bool { elem.is_htmloptionelement() } } - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let filter = box HTMLDataListOptionsFilter; - let window = window_from_node(node).root(); + let window = window_from_node(node); HTMLCollection::create(window.r(), node, filter) } } diff --git a/components/script/dom/htmldialogelement.rs b/components/script/dom/htmldialogelement.rs index c614f55a691..98d5e6bbac7 100644 --- a/components/script/dom/htmldialogelement.rs +++ b/components/script/dom/htmldialogelement.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::HTMLDialogElementBinding; use dom::bindings::codegen::Bindings::HTMLDialogElementBinding::HTMLDialogElementMethods; use dom::bindings::codegen::InheritTypes::HTMLDialogElementDerived; use dom::bindings::cell::DOMRefCell; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -34,7 +34,7 @@ impl HTMLDialogElementDerived for EventTarget { impl HTMLDialogElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLDialogElement { + document: &Document) -> HTMLDialogElement { HTMLDialogElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDialogElement, localName, prefix, document), @@ -45,13 +45,13 @@ impl HTMLDialogElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDialogElement> { + document: &Document) -> Root<HTMLDialogElement> { let element = HTMLDialogElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDialogElementBinding::Wrap) } } -impl<'a> HTMLDialogElementMethods for JSRef<'a, HTMLDialogElement> { +impl<'a> HTMLDialogElementMethods for &'a HTMLDialogElement { // https://html.spec.whatwg.org/multipage/#dom-dialog-open make_bool_getter!(Open); diff --git a/components/script/dom/htmldirectoryelement.rs b/components/script/dom/htmldirectoryelement.rs index 7c0eeb0d616..3f1fcfd4759 100644 --- a/components/script/dom/htmldirectoryelement.rs +++ b/components/script/dom/htmldirectoryelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLDirectoryElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDirectoryElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -28,7 +28,7 @@ impl HTMLDirectoryElementDerived for EventTarget { impl HTMLDirectoryElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLDirectoryElement { + document: &Document) -> HTMLDirectoryElement { HTMLDirectoryElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDirectoryElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLDirectoryElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDirectoryElement> { + document: &Document) -> Root<HTMLDirectoryElement> { let element = HTMLDirectoryElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDirectoryElementBinding::Wrap) } diff --git a/components/script/dom/htmldivelement.rs b/components/script/dom/htmldivelement.rs index 6a7bb96cc5d..21b1e6cacd1 100644 --- a/components/script/dom/htmldivelement.rs +++ b/components/script/dom/htmldivelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLDivElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDivElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -28,7 +28,7 @@ impl HTMLDivElementDerived for EventTarget { impl HTMLDivElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLDivElement { + document: &Document) -> HTMLDivElement { HTMLDivElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDivElement, localName, prefix, document) } @@ -37,7 +37,7 @@ impl HTMLDivElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDivElement> { + document: &Document) -> Root<HTMLDivElement> { let element = HTMLDivElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDivElementBinding::Wrap) } diff --git a/components/script/dom/htmldlistelement.rs b/components/script/dom/htmldlistelement.rs index 94e579836cf..6446ac408d2 100644 --- a/components/script/dom/htmldlistelement.rs +++ b/components/script/dom/htmldlistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLDListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLDListElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -26,7 +26,7 @@ impl HTMLDListElementDerived for EventTarget { } impl HTMLDListElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLDListElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLDListElement { HTMLDListElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLDListElement, localName, prefix, document) @@ -36,7 +36,7 @@ impl HTMLDListElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLDListElement> { + document: &Document) -> Root<HTMLDListElement> { let element = HTMLDListElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLDListElementBinding::Wrap) } diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 9a0a0dbf808..47d1042ec5f 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFrameSetElementDerived}; use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLInputElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLElementDerived, HTMLBodyElementDerived}; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary}; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::error::ErrorResult; use dom::bindings::error::Error::Syntax; use dom::bindings::utils::Reflectable; @@ -37,6 +37,7 @@ use string_cache::Atom; use std::borrow::ToOwned; use std::default::Default; use std::intrinsics; +use std::rc::Rc; #[dom_struct] pub struct HTMLElement { @@ -45,6 +46,12 @@ pub struct HTMLElement { dataset: MutNullableHeap<JS<DOMStringMap>>, } +impl PartialEq for HTMLElement { + fn eq(&self, other: &HTMLElement) -> bool { + self as *const HTMLElement == &*other + } +} + impl HTMLElementDerived for EventTarget { fn is_htmlelement(&self) -> bool { match *self.type_id() { @@ -58,7 +65,7 @@ impl HTMLElement { pub fn new_inherited(type_id: HTMLElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLElement { + document: &Document) -> HTMLElement { HTMLElement { element: Element::new_inherited(ElementTypeId::HTMLElement(type_id), tag_name, ns!(HTML), prefix, document), @@ -68,7 +75,7 @@ impl HTMLElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> Temporary<HTMLElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> Root<HTMLElement> { let element = HTMLElement::new_inherited(HTMLElementTypeId::HTMLElement, localName, prefix, document); Node::reflect_node(box element, document, HTMLElementBinding::Wrap) } @@ -79,9 +86,9 @@ trait PrivateHTMLElementHelpers { fn update_sequentially_focusable_status(self); } -impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> { +impl<'a> PrivateHTMLElementHelpers for &'a HTMLElement { fn is_body_or_frameset(self) -> bool { - let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let eventtarget = EventTargetCast::from_ref(self); eventtarget.is_htmlbodyelement() || eventtarget.is_htmlframesetelement() } @@ -105,7 +112,6 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> { }, _ => { if let Some(attr) = element.get_attribute(&ns!(""), &atom!("draggable")) { - let attr = attr.root(); let attr = attr.r(); let value = attr.value(); let is_true = match *value { @@ -124,10 +130,10 @@ impl<'a> PrivateHTMLElementHelpers for JSRef<'a, HTMLElement> { } } -impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { - fn Style(self) -> Temporary<CSSStyleDeclaration> { +impl<'a> HTMLElementMethods for &'a HTMLElement { + fn Style(self) -> Root<CSSStyleDeclaration> { self.style_decl.or_init(|| { - let global = window_from_node(self).root(); + let global = window_from_node(self); CSSStyleDeclaration::new(global.r(), self, CSSModificationAccess::ReadWrite) }) } @@ -145,39 +151,39 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { global_event_handlers!(NoOnload); // https://html.spec.whatwg.org/multipage/#dom-dataset - fn Dataset(self) -> Temporary<DOMStringMap> { + fn Dataset(self) -> Root<DOMStringMap> { self.dataset.or_init(|| DOMStringMap::new(self)) } - fn GetOnload(self) -> Option<EventHandlerNonNull> { + fn GetOnload(self) -> Option<Rc<EventHandlerNonNull>> { if self.is_body_or_frameset() { - let win = window_from_node(self).root(); + let win = window_from_node(self); win.r().GetOnload() } else { - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let target = EventTargetCast::from_ref(self); target.get_event_handler_common("load") } } - fn SetOnload(self, listener: Option<EventHandlerNonNull>) { + fn SetOnload(self, listener: Option<Rc<EventHandlerNonNull>>) { if self.is_body_or_frameset() { - let win = window_from_node(self).root(); + let win = window_from_node(self); win.r().SetOnload(listener) } else { - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let target = EventTargetCast::from_ref(self); target.set_event_handler_common("load", listener) } } // https://html.spec.whatwg.org/multipage/#dom-click fn Click(self) { - let maybe_input: Option<JSRef<HTMLInputElement>> = HTMLInputElementCast::to_ref(self); + let maybe_input: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(self); if let Some(i) = maybe_input { if i.Disabled() { return; } } - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27430 ? element.as_maybe_activatable().map(|a| a.synthetic_click_activation(false, false, false, false)); } @@ -186,8 +192,8 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { fn Focus(self) { // TODO: Mark the element as locked for focus and run the focusing steps. // https://html.spec.whatwg.org/multipage/#focusing-steps - let element: JSRef<Element> = ElementCast::from_ref(self); - let document = document_from_node(self).root(); + let element = ElementCast::from_ref(self); + let document = document_from_node(self); let document = document.r(); document.begin_focus_transaction(); document.request_focus(element); @@ -197,12 +203,12 @@ impl<'a> HTMLElementMethods for JSRef<'a, HTMLElement> { // https://html.spec.whatwg.org/multipage/#dom-blur fn Blur(self) { // TODO: Run the unfocusing steps. - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if !node.get_focus_state() { return; } // https://html.spec.whatwg.org/multipage/#unfocusing-steps - let document = document_from_node(self).root(); + let document = document_from_node(self); document.r().begin_focus_transaction(); // If `request_focus` is not called, focus will be set to None. document.r().commit_focus_transaction(FocusType::Element); @@ -229,22 +235,21 @@ fn to_snake_case(name: DOMString) -> DOMString { attr_name } -impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { +impl<'a> HTMLElementCustomAttributeHelpers for &'a HTMLElement { fn set_custom_attr(self, name: DOMString, value: DOMString) -> ErrorResult { if name.chars() .skip_while(|&ch| ch != '\u{2d}') .nth(1).map_or(false, |ch| ch >= 'a' && ch <= 'z') { return Err(Syntax); } - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.set_custom_attribute(to_snake_case(name), value) } fn get_custom_attr(self, local_name: DOMString) -> Option<DOMString> { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let local_name = Atom::from_slice(&to_snake_case(local_name)); element.get_attribute(&ns!(""), &local_name).map(|attr| { - let attr = attr.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); let value = attr.value(); @@ -253,19 +258,19 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> { } fn delete_custom_attr(self, local_name: DOMString) { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let local_name = Atom::from_slice(&to_snake_case(local_name)); element.remove_attribute(&ns!(""), &local_name); } } -impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { +impl<'a> VirtualMethods for &'a HTMLElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let element: &JSRef<Element> = ElementCast::from_borrowed_ref(self); + let element: &&Element = ElementCast::from_borrowed_ref(self); Some(element as &VirtualMethods) } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } @@ -278,18 +283,18 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> { self.update_sequentially_focusable_status(); } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } let name = attr.local_name(); if name.starts_with("on") { - let window = window_from_node(*self).root(); + let window = window_from_node(*self); let (cx, url, reflector) = (window.r().get_cx(), window.r().get_url(), window.r().reflector().get_jsobject()); - let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self); + let evtarget = EventTargetCast::from_ref(*self); evtarget.set_event_handler_uncompiled(cx, url, reflector, &name[2..], (**attr.value()).to_owned()); diff --git a/components/script/dom/htmlembedelement.rs b/components/script/dom/htmlembedelement.rs index 2e961d6642f..6cabca7e80e 100644 --- a/components/script/dom/htmlembedelement.rs +++ b/components/script/dom/htmlembedelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLEmbedElementBinding; use dom::bindings::codegen::InheritTypes::HTMLEmbedElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -26,7 +26,7 @@ impl HTMLEmbedElementDerived for EventTarget { } impl HTMLEmbedElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLEmbedElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLEmbedElement { HTMLEmbedElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLEmbedElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLEmbedElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLEmbedElement> { + document: &Document) -> Root<HTMLEmbedElement> { let element = HTMLEmbedElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLEmbedElementBinding::Wrap) } diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index ba786f095c7..e65757bfa60 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding; use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLLegendElementDerived}; -use dom::bindings::js::{JSRef, Rootable, RootedReference, Temporary}; +use dom::bindings::js::{Root, RootedReference}; use dom::document::Document; use dom::element::{AttributeHandlers, Element, ElementHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -37,7 +37,7 @@ impl HTMLFieldSetElementDerived for EventTarget { impl HTMLFieldSetElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLFieldSetElement { + document: &Document) -> HTMLFieldSetElement { HTMLFieldSetElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFieldSetElement, localName, prefix, document) @@ -47,32 +47,32 @@ impl HTMLFieldSetElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLFieldSetElement> { + document: &Document) -> Root<HTMLFieldSetElement> { let element = HTMLFieldSetElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLFieldSetElementBinding::Wrap) } } -impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> { +impl<'a> HTMLFieldSetElementMethods for &'a HTMLFieldSetElement { // https://www.whatwg.org/html/#dom-fieldset-elements - fn Elements(self) -> Temporary<HTMLCollection> { + fn Elements(self) -> Root<HTMLCollection> { #[jstraceable] struct ElementsFilter; impl CollectionFilter for ElementsFilter { - fn filter<'a>(&self, elem: JSRef<'a, Element>, _root: JSRef<'a, Node>) -> bool { + fn filter<'a>(&self, elem: &'a Element, _root: &'a Node) -> bool { static TAG_NAMES: StaticStringVec = &["button", "fieldset", "input", "keygen", "object", "output", "select", "textarea"]; TAG_NAMES.iter().any(|&tag_name| tag_name == &**elem.local_name()) } } - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let filter = box ElementsFilter; - let window = window_from_node(node).root(); + let window = window_from_node(node); HTMLCollection::create(window.r(), node, filter) } - fn Validity(self) -> Temporary<ValidityState> { - let window = window_from_node(self).root(); + fn Validity(self) -> Root<ValidityState> { + let window = window_from_node(self); ValidityState::new(window.r()) } @@ -83,34 +83,31 @@ impl<'a> HTMLFieldSetElementMethods for JSRef<'a, HTMLFieldSetElement> { make_bool_setter!(SetDisabled, "disabled"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLFieldSetElement> { +impl<'a> VirtualMethods for &'a HTMLFieldSetElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); let maybe_legend = node.children() - .map(|node| node.root()) .find(|node| node.r().is_htmllegendelement()); for child in node.children() { - let child = child.root(); if Some(child.r()) == maybe_legend.r() { continue; } for descendant in child.r().traverse_preorder() { - let descendant = descendant.root(); match descendant.r().type_id() { NodeTypeId::Element( ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | @@ -132,28 +129,25 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLFieldSetElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); let maybe_legend = node.children() - .map(|node| node.root()) .find(|node| node.r().is_htmllegendelement()); for child in node.children() { - let child = child.root(); if Some(child.r()) == maybe_legend.r() { continue; } for descendant in child.r().traverse_preorder() { - let descendant = descendant.root(); match descendant.r().type_id() { NodeTypeId::Element( ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs index 6a69751aac5..6a10967e441 100644 --- a/components/script/dom/htmlfontelement.rs +++ b/components/script/dom/htmlfontelement.rs @@ -6,7 +6,7 @@ use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLFontElementBinding; use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -33,7 +33,7 @@ impl HTMLFontElementDerived for EventTarget { } impl HTMLFontElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLFontElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLFontElement { HTMLFontElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document), color: Cell::new(None), @@ -43,24 +43,24 @@ impl HTMLFontElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLFontElement> { + document: &Document) -> Root<HTMLFontElement> { let element = HTMLFontElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLFontElementBinding::Wrap) } } -impl<'a> HTMLFontElementMethods for JSRef<'a, HTMLFontElement> { +impl<'a> HTMLFontElementMethods for &'a HTMLFontElement { make_getter!(Color, "color"); make_setter!(SetColor, "color"); } -impl<'a> VirtualMethods for JSRef<'a,HTMLFontElement> { +impl<'a> VirtualMethods for &'a HTMLFontElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -73,7 +73,7 @@ impl<'a> VirtualMethods for JSRef<'a,HTMLFontElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 254465dc416..bfa5792327a 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -17,7 +17,7 @@ use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived; use dom::bindings::codegen::InheritTypes::HTMLInputElementCast; use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::{Root}; use dom::document::{Document, DocumentHelpers}; use dom::element::{Element, AttributeHandlers}; use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable}; @@ -49,6 +49,12 @@ pub struct HTMLFormElement { marked_for_reset: Cell<bool>, } +impl PartialEq for HTMLFormElement { + fn eq(&self, other: &HTMLFormElement) -> bool { + self as *const HTMLFormElement == &*other + } +} + impl HTMLFormElementDerived for EventTarget { fn is_htmlformelement(&self) -> bool { *self.type_id() == @@ -60,7 +66,7 @@ impl HTMLFormElementDerived for EventTarget { impl HTMLFormElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLFormElement { + document: &Document) -> HTMLFormElement { HTMLFormElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFormElement, localName, prefix, document), marked_for_reset: Cell::new(false), @@ -70,13 +76,13 @@ impl HTMLFormElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLFormElement> { + document: &Document) -> Root<HTMLFormElement> { let element = HTMLFormElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap) } } -impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> { +impl<'a> HTMLFormElementMethods for &'a HTMLFormElement { // https://html.spec.whatwg.org/multipage/#dom-form-acceptcharset make_getter!(AcceptCharset, "accept-charset"); @@ -165,19 +171,19 @@ pub trait HTMLFormElementHelpers { fn reset(self, submit_method_flag: ResetFrom); } -impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { +impl<'a> HTMLFormElementHelpers for &'a HTMLFormElement { fn submit(self, _submit_method_flag: SubmittedFrom, submitter: FormSubmitter) { // Step 1 - let doc = document_from_node(self).root(); - let win = window_from_node(self).root(); + let doc = document_from_node(self); + let win = window_from_node(self); let base = doc.r().url(); // TODO: Handle browsing contexts // TODO: Handle validation let event = Event::new(GlobalRef::Window(win.r()), "submit".to_owned(), EventBubbles::Bubbles, - EventCancelable::Cancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + EventCancelable::Cancelable); + let target = EventTargetCast::from_ref(self); event.r().fire(target); if event.r().DefaultPrevented() { return; @@ -262,16 +268,15 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { buf } - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); // TODO: This is an incorrect way of getting controls owned // by the form, but good enough until html5ever lands let data_set = node.traverse_preorder().filter_map(|child| { - let child = child.root(); if child.r().get_disabled_state() { return None; } if child.r().ancestors() - .any(|a| HTMLDataListElementCast::to_temporary(a).is_some()) { + .any(|a| HTMLDataListElementCast::to_root(a).is_some()) { return None; } // XXXManishearth don't include it if it is a button but not the submitter @@ -365,23 +370,22 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> { self.marked_for_reset.set(true); } - let win = window_from_node(self).root(); + let win = window_from_node(self); let event = Event::new(GlobalRef::Window(win.r()), "reset".to_owned(), EventBubbles::Bubbles, - EventCancelable::Cancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + EventCancelable::Cancelable); + let target = EventTargetCast::from_ref(self); event.r().fire(target); if event.r().DefaultPrevented() { return; } - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); // TODO: This is an incorrect way of getting controls owned // by the form, but good enough until html5ever lands for child in node.traverse_preorder() { - let child = child.root(); match child.r().type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { let input = HTMLInputElementCast::to_ref(child.r()).unwrap(); @@ -434,9 +438,9 @@ pub enum FormMethod { #[derive(Copy, Clone)] pub enum FormSubmitter<'a> { - FormElement(JSRef<'a, HTMLFormElement>), - InputElement(JSRef<'a, HTMLInputElement>), - ButtonElement(JSRef<'a, HTMLButtonElement>) + FormElement(&'a HTMLFormElement), + InputElement(&'a HTMLInputElement), + ButtonElement(&'a HTMLButtonElement) // TODO: image submit, etc etc } @@ -525,28 +529,27 @@ impl<'a> FormSubmitter<'a> { pub trait FormControl<'a> : Copy + Sized { // FIXME: This is wrong (https://github.com/servo/servo/issues/3553) // but we need html5ever to do it correctly - fn form_owner(self) -> Option<Temporary<HTMLFormElement>> { + fn form_owner(self) -> Option<Root<HTMLFormElement>> { // https://html.spec.whatwg.org/multipage/#reset-the-form-owner let elem = self.to_element(); let owner = elem.get_string_attribute(&atom!("form")); if !owner.is_empty() { - let doc = document_from_node(elem).root(); - let owner = doc.r().GetElementById(owner).root(); + let doc = document_from_node(elem); + let owner = doc.r().GetElementById(owner); match owner { Some(ref o) => { - let maybe_form: Option<JSRef<HTMLFormElement>> = HTMLFormElementCast::to_ref(o.r()); + let maybe_form = HTMLFormElementCast::to_ref(o.r()); if maybe_form.is_some() { - return maybe_form.map(Temporary::from_rooted); + return maybe_form.map(Root::from_ref); } }, _ => () } } - let node: JSRef<Node> = NodeCast::from_ref(elem); + let node = NodeCast::from_ref(elem); for ancestor in node.ancestors() { - let ancestor = ancestor.root(); if let Some(ancestor) = HTMLFormElementCast::to_ref(ancestor.r()) { - return Some(Temporary::from_rooted(ancestor)) + return Some(Root::from_ref(ancestor)) } } None @@ -558,19 +561,19 @@ pub trait FormControl<'a> : Copy + Sized { owner: OwnerFn) -> DOMString where InputFn: Fn(Self) -> DOMString, - OwnerFn: Fn(JSRef<HTMLFormElement>) -> DOMString + OwnerFn: Fn(&HTMLFormElement) -> DOMString { if self.to_element().has_attribute(attr) { input(self) } else { - self.form_owner().map_or("".to_owned(), |t| owner(t.root().r())) + self.form_owner().map_or("".to_owned(), |t| owner(t.r())) } } - fn to_element(self) -> JSRef<'a, Element>; + fn to_element(self) -> &'a Element; } -impl<'a> VirtualMethods for JSRef<'a, HTMLFormElement> { +impl<'a> VirtualMethods for &'a HTMLFormElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { Some(HTMLElementCast::from_borrowed_ref(self) as &VirtualMethods) } diff --git a/components/script/dom/htmlframeelement.rs b/components/script/dom/htmlframeelement.rs index c9107fa7c33..d9899ba614d 100644 --- a/components/script/dom/htmlframeelement.rs +++ b/components/script/dom/htmlframeelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLFrameElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFrameElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLFrameElementDerived for EventTarget { } impl HTMLFrameElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLFrameElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLFrameElement { HTMLFrameElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLFrameElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLFrameElement> { + document: &Document) -> Root<HTMLFrameElement> { let element = HTMLFrameElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLFrameElementBinding::Wrap) } diff --git a/components/script/dom/htmlframesetelement.rs b/components/script/dom/htmlframesetelement.rs index 529efa599bd..d6f53fb4650 100644 --- a/components/script/dom/htmlframesetelement.rs +++ b/components/script/dom/htmlframesetelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLFrameSetElementBinding; use dom::bindings::codegen::InheritTypes::HTMLFrameSetElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLFrameSetElementDerived for EventTarget { impl HTMLFrameSetElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLFrameSetElement { + document: &Document) -> HTMLFrameSetElement { HTMLFrameSetElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFrameSetElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLFrameSetElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLFrameSetElement> { + document: &Document) -> Root<HTMLFrameSetElement> { let element = HTMLFrameSetElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLFrameSetElementBinding::Wrap) } diff --git a/components/script/dom/htmlheadelement.rs b/components/script/dom/htmlheadelement.rs index 57b365185d3..1165501f3ee 100644 --- a/components/script/dom/htmlheadelement.rs +++ b/components/script/dom/htmlheadelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLHeadElementBinding; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLHeadElementDerived}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -30,7 +30,7 @@ impl HTMLHeadElementDerived for EventTarget { impl HTMLHeadElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLHeadElement { + document: &Document) -> HTMLHeadElement { HTMLHeadElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHeadElement, localName, prefix, document) } @@ -39,15 +39,15 @@ impl HTMLHeadElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLHeadElement> { + document: &Document) -> Root<HTMLHeadElement> { let element = HTMLHeadElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLHeadElementBinding::Wrap) } } -impl<'a> VirtualMethods for JSRef<'a, HTMLHeadElement> { +impl<'a> VirtualMethods for &'a HTMLHeadElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } fn bind_to_tree(&self, _tree_in_doc: bool) { diff --git a/components/script/dom/htmlheadingelement.rs b/components/script/dom/htmlheadingelement.rs index bb701236a8a..f8d0a5a3bed 100644 --- a/components/script/dom/htmlheadingelement.rs +++ b/components/script/dom/htmlheadingelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLHeadingElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHeadingElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -39,7 +39,7 @@ impl HTMLHeadingElementDerived for EventTarget { impl HTMLHeadingElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>, + document: &Document, level: HeadingLevel) -> HTMLHeadingElement { HTMLHeadingElement { htmlelement: @@ -51,8 +51,8 @@ impl HTMLHeadingElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>, - level: HeadingLevel) -> Temporary<HTMLHeadingElement> { + document: &Document, + level: HeadingLevel) -> Root<HTMLHeadingElement> { let element = HTMLHeadingElement::new_inherited(localName, prefix, document, level); Node::reflect_node(box element, document, HTMLHeadingElementBinding::Wrap) } diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs index 71e8a4a6a41..b04c137e934 100644 --- a/components/script/dom/htmlhrelement.rs +++ b/components/script/dom/htmlhrelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLHRElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHRElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLHRElementDerived for EventTarget { } impl HTMLHRElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLHRElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLHRElement { HTMLHRElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHRElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLHRElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLHRElement> { + document: &Document) -> Root<HTMLHRElement> { let element = HTMLHRElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLHRElementBinding::Wrap) } diff --git a/components/script/dom/htmlhtmlelement.rs b/components/script/dom/htmlhtmlelement.rs index f22f822cbdd..96190c0599c 100644 --- a/components/script/dom/htmlhtmlelement.rs +++ b/components/script/dom/htmlhtmlelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLHtmlElementBinding; use dom::bindings::codegen::InheritTypes::HTMLHtmlElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLHtmlElementDerived for EventTarget { } impl HTMLHtmlElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLHtmlElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLHtmlElement { HTMLHtmlElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLHtmlElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLHtmlElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLHtmlElement> { + document: &Document) -> Root<HTMLHtmlElement> { let element = HTMLHtmlElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLHtmlElementBinding::Wrap) } diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 13ec9d9c5a1..cf1c07b69f5 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -13,11 +13,11 @@ use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::NotSupported; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::{Root}; use dom::customevent::CustomEvent; use dom::document::Document; -use dom::element::{self, AttributeHandlers, Element}; -use dom::event::{Event, EventHelpers}; +use dom::element::{self, AttributeHandlers}; +use dom::event::EventHelpers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; @@ -39,6 +39,8 @@ use std::borrow::ToOwned; use std::cell::Cell; use url::{Url, UrlParser}; use util::str::{self, LengthOrPercentageOrAuto}; +use js::jsapi::RootedValue; +use js::jsval::UndefinedValue; enum SandboxAllowance { AllowNothing = 0x00, @@ -82,19 +84,19 @@ pub trait RawHTMLIFrameElementHelpers { fn get_height(&self) -> LengthOrPercentageOrAuto; } -impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { +impl<'a> HTMLIFrameElementHelpers for &'a HTMLIFrameElement { fn is_sandboxed(self) -> bool { self.sandbox.get().is_some() } fn get_url(self) -> Option<Url> { - let element: JSRef<Element> = ElementCast::from_ref(self); - element.get_attribute(&ns!(""), &atom!("src")).root().and_then(|src| { + let element = ElementCast::from_ref(self); + element.get_attribute(&ns!(""), &atom!("src")).and_then(|src| { let url = src.r().value(); if url.is_empty() { None } else { - let window = window_from_node(self).root(); + let window = window_from_node(self); UrlParser::new().base_url(&window.r().get_url()) .parse(&url).ok() } @@ -103,7 +105,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { fn generate_new_subpage_id(self) -> (SubpageId, Option<SubpageId>) { let old_subpage_id = self.subpage_id.get(); - let win = window_from_node(self).root(); + let win = window_from_node(self); let subpage_id = win.r().get_next_subpage_id(); self.subpage_id.set(Some(subpage_id)); (subpage_id, old_subpage_id) @@ -116,7 +118,7 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { IFrameUnsandboxed }; - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let (new_subpage_id, old_subpage_id) = self.generate_new_subpage_id(); @@ -151,15 +153,17 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> { assert!(opts::experimental_enabled()); if self.Mozbrowser() { - let window = window_from_node(self).root(); + let window = window_from_node(self); let cx = window.r().get_cx(); + let mut detail = RootedValue::new(cx, UndefinedValue()); + event.detail().to_jsval(cx, detail.handle_mut()); let custom_event = CustomEvent::new(GlobalRef::Window(window.r()), event.name().to_owned(), true, true, - event.detail().to_jsval(cx)).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); - let event: JSRef<Event> = EventCast::from_ref(custom_event.r()); + detail.handle()); + let target = EventTargetCast::from_ref(self); + let event = EventCast::from_ref(custom_event.r()); event.fire(target); } } @@ -176,7 +180,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement { element::get_attr_for_layout(ElementCast::from_actual(&*self), &ns!(""), &atom!("width")).map(|attribute| { - str::parse_length(&**(*attribute.unsafe_get()).value()) + str::parse_length(&**(*attribute.unsafe_get()).value_for_layout()) }).unwrap_or(LengthOrPercentageOrAuto::Auto) } } @@ -187,7 +191,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement { element::get_attr_for_layout(ElementCast::from_actual(&*self), &ns!(""), &atom!("height")).map(|attribute| { - str::parse_length(&**(*attribute.unsafe_get()).value()) + str::parse_length(&**(*attribute.unsafe_get()).value_for_layout()) }).unwrap_or(LengthOrPercentageOrAuto::Auto) } } @@ -196,7 +200,7 @@ impl RawHTMLIFrameElementHelpers for HTMLIFrameElement { impl HTMLIFrameElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLIFrameElement { + document: &Document) -> HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLIFrameElement, localName, prefix, document), @@ -209,7 +213,7 @@ impl HTMLIFrameElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLIFrameElement> { + document: &Document) -> Root<HTMLIFrameElement> { let element = HTMLIFrameElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLIFrameElementBinding::Wrap) } @@ -225,46 +229,46 @@ impl HTMLIFrameElement { } } -impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { +impl<'a> HTMLIFrameElementMethods for &'a HTMLIFrameElement { fn Src(self) -> DOMString { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.get_string_attribute(&atom!("src")) } fn SetSrc(self, src: DOMString) { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.set_url_attribute(&atom!("src"), src) } fn Sandbox(self) -> DOMString { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.get_string_attribute(&atom!("sandbox")) } fn SetSandbox(self, sandbox: DOMString) { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.set_tokenlist_attribute(&atom!("sandbox"), sandbox); } - fn GetContentWindow(self) -> Option<Temporary<Window>> { + fn GetContentWindow(self) -> Option<Root<Window>> { self.subpage_id.get().and_then(|subpage_id| { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let children = window.page().children.borrow(); children.iter().find(|page| { - let window = page.window().root(); + let window = page.window(); window.r().subpage() == Some(subpage_id) }).map(|page| page.window()) }) } - fn GetContentDocument(self) -> Option<Temporary<Document>> { - self.GetContentWindow().root().and_then(|window| { + fn GetContentDocument(self) -> Option<Root<Document>> { + self.GetContentWindow().and_then(|window| { let self_url = match self.get_url() { Some(self_url) => self_url, None => return None, }; - let win_url = window_from_node(self).root().r().get_url(); + let win_url = window_from_node(self).r().get_url(); if UrlHelper::SameOrigin(&self_url, &win_url) { Some(window.r().Document()) @@ -284,7 +288,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser fn Mozbrowser(self) -> bool { if opts::experimental_enabled() { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.has_attribute(&Atom::from_slice("mozbrowser")) } else { false @@ -293,7 +297,7 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { fn SetMozbrowser(self, value: bool) -> ErrorResult { if opts::experimental_enabled() { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.set_bool_attribute(&Atom::from_slice("mozbrowser"), value); } Ok(()) @@ -302,9 +306,9 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack fn GoBack(self) -> Fallible<()> { if self.Mozbrowser() { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if node.is_in_doc() { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(), @@ -324,9 +328,9 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goForward fn GoForward(self) -> Fallible<()> { if self.Mozbrowser() { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if node.is_in_doc() { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let pipeline_info = Some((self.containing_page_pipeline_id().unwrap(), @@ -362,13 +366,13 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> { make_setter!(SetHeight, "height"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { +impl<'a> VirtualMethods for &'a HTMLIFrameElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -392,7 +396,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { self.sandbox.set(Some(modes)); } &atom!("src") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if node.is_in_doc() { self.process_the_iframe_attributes() } @@ -408,7 +412,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } @@ -437,7 +441,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> { // https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded match (self.containing_page_pipeline_id(), self.subpage_id()) { (Some(containing_pipeline_id), Some(subpage_id)) => { - let window = window_from_node(*self).root(); + let window = window_from_node(*self); let window = window.r(); let ConstellationChan(ref chan) = window.constellation_chan(); diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index a01664f249d..2ea5442bff6 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -10,10 +10,9 @@ use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementM use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, EventTargetCast, HTMLElementCast, HTMLImageElementDerived}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, LayoutJS, Rootable, Temporary}; +use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::refcounted::Trusted; use dom::document::{Document, DocumentHelpers}; -use dom::element::Element; use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -51,7 +50,7 @@ pub trait HTMLImageElementHelpers { fn get_url(&self) -> Option<Url>; } -impl<'a> HTMLImageElementHelpers for JSRef<'a, HTMLImageElement> { +impl<'a> HTMLImageElementHelpers for &'a HTMLImageElement { fn get_url(&self) -> Option<Url>{ self.url.borrow().clone() } @@ -79,7 +78,7 @@ impl Responder { impl ImageResponder for Responder { fn respond(&self, image: ImageResponse) { // Update the image field - let element = self.element.to_temporary().root(); + let element = self.element.root(); let element_ref = element.r(); *element_ref.image.borrow_mut() = match image { ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => { @@ -90,17 +89,17 @@ impl ImageResponder for Responder { // Mark the node dirty let node = NodeCast::from_ref(element.r()); - let document = document_from_node(node).root(); + let document = document_from_node(node); document.r().content_changed(node, NodeDamage::OtherNodeDamage); // Fire image.onload - let window = window_from_node(document.r()).root(); + let window = window_from_node(document.r()); let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); + EventCancelable::NotCancelable); let event = event.r(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(node); + let target = EventTargetCast::from_ref(node); event.fire(target); // Trigger reflow @@ -108,13 +107,13 @@ impl ImageResponder for Responder { } } -impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> { +impl<'a> PrivateHTMLImageElementHelpers for &'a HTMLImageElement { /// Makes the local `image` member match the status of the `src` attribute and starts /// prefetching the image. This method must be called after `src` is changed. fn update_image(self, value: Option<(DOMString, &Url)>) { - let node: JSRef<Node> = NodeCast::from_ref(self); - let document = node.owner_doc().root(); - let window = document.r().window().root(); + let node = NodeCast::from_ref(self); + let document = node.owner_doc(); + let window = document.r().window(); let window = window.r(); let image_cache = window.image_cache_task(); match value { @@ -137,7 +136,7 @@ impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> { } impl HTMLImageElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLImageElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLImageElement { HTMLImageElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLImageElement, localName, prefix, document), url: DOMRefCell::new(None), @@ -148,7 +147,7 @@ impl HTMLImageElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLImageElement> { + document: &Document) -> Root<HTMLImageElement> { let element = HTMLImageElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLImageElementBinding::Wrap) } @@ -174,7 +173,7 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> { } } -impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { +impl<'a> HTMLImageElementMethods for &'a HTMLImageElement { make_getter!(Alt); make_setter!(SetAlt, "alt"); @@ -190,29 +189,29 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { make_bool_getter!(IsMap); fn SetIsMap(self, is_map: bool) { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.set_string_attribute(&atom!("ismap"), is_map.to_string()) } fn Width(self) -> u32 { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); rect.size.width.to_px() as u32 } fn SetWidth(self, width: u32) { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.set_uint_attribute(&atom!("width"), width) } fn Height(self) -> u32 { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let rect = node.get_bounding_content_box(); rect.size.height.to_px() as u32 } fn SetHeight(self, height: u32) { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.set_uint_attribute(&atom!("height"), height) } @@ -264,20 +263,20 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> { make_setter!(SetBorder, "border"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { +impl<'a> VirtualMethods for &'a HTMLImageElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("src") => { - let window = window_from_node(*self).root(); + let window = window_from_node(*self); let url = window.r().get_url(); self.update_image(Some(((**attr.value()).to_owned(), &url))); }, @@ -285,7 +284,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 1525d8f88e8..87c23d00bb9 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -15,9 +15,9 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInp use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast}; use dom::bindings::codegen::InheritTypes::KeyboardEventCast; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap}; -use dom::bindings::js::{OptionalRootable, ResultRootable, Root, Rootable}; -use dom::bindings::js::{RootedReference, Temporary}; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; +use dom::bindings::js::{Root}; +use dom::bindings::js::RootedReference; use dom::document::{Document, DocumentHelpers}; use dom::element::{AttributeHandlers, Element}; use dom::element::{RawLayoutElementHelpers, ActivationElementHelpers}; @@ -77,6 +77,12 @@ pub struct HTMLInputElement { activation_state: DOMRefCell<InputActivationState>, } +impl PartialEq for HTMLInputElement { + fn eq(&self, other: &HTMLInputElement) -> bool { + self as *const HTMLInputElement == &*other + } +} + #[jstraceable] #[must_root] struct InputActivationState { @@ -114,8 +120,8 @@ impl HTMLInputElementDerived for EventTarget { static DEFAULT_INPUT_SIZE: u32 = 20; impl HTMLInputElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLInputElement { - let chan = document.window().root().r().constellation_chan(); + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLInputElement { + let chan = document.window().r().constellation_chan(); HTMLInputElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLInputElement, localName, prefix, document), input_type: Cell::new(InputType::InputText), @@ -133,7 +139,7 @@ impl HTMLInputElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLInputElement> { + document: &Document) -> Root<HTMLInputElement> { let element = HTMLInputElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLInputElementBinding::Wrap) } @@ -217,7 +223,7 @@ impl RawLayoutHTMLInputElementHelpers for HTMLInputElement { } } -impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { +impl<'a> HTMLInputElementMethods for &'a HTMLInputElement { // https://www.whatwg.org/html/#dom-fe-disabled make_bool_getter!(Disabled); @@ -335,27 +341,26 @@ pub trait HTMLInputElementHelpers { fn radio_group_updated(self, group: Option<&str>); fn get_radio_group_name(self) -> Option<String>; fn update_checked_state(self, checked: bool, dirty: bool); - fn get_size(&self) -> u32; + fn get_size(self) -> u32; fn get_indeterminate_state(self) -> bool; fn mutable(self) -> bool; fn reset(self); } #[allow(unsafe_code)] -fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) { +fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&str>) { //TODO: if not in document, use root ancestor instead of document - let owner = broadcaster.form_owner().root(); - let doc = document_from_node(broadcaster).root(); - let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let owner = broadcaster.form_owner(); + let doc = document_from_node(broadcaster); + let doc_node = NodeCast::from_ref(doc.r()); // This function is a workaround for lifetime constraint difficulties. - fn do_broadcast<'a>(doc_node: JSRef<'a, Node>, broadcaster: JSRef<'a, HTMLInputElement>, - owner: Option<JSRef<'a, HTMLFormElement>>, group: Option<&str>) { + fn do_broadcast(doc_node: &Node, broadcaster: &HTMLInputElement, + owner: Option<&HTMLFormElement>, group: Option<&str>) { // There is no DOM tree manipulation here, so this is safe let iter = unsafe { doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap() - .filter_map(HTMLInputElementCast::to_temporary) - .map(|t| t.root()) + .filter_map(HTMLInputElementCast::to_root) .filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r()) }; for ref r in iter { @@ -368,10 +373,10 @@ fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<& do_broadcast(doc_node, broadcaster, owner.r(), group) } -fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>, - owner: Option<JSRef<'b, HTMLFormElement>>, +fn in_same_group<'a,'b>(other: &'a HTMLInputElement, + owner: Option<&'b HTMLFormElement>, group: Option<&str>) -> bool { - let other_owner = other.form_owner().root(); + let other_owner = other.form_owner(); let other_owner = other_owner.r(); other.input_type.get() == InputType::InputRadio && // TODO Both a and b are in the same home subtree. @@ -384,10 +389,10 @@ fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>, } } -impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { +impl<'a> HTMLInputElementHelpers for &'a HTMLInputElement { fn force_relayout(self) { - let doc = document_from_node(self).root(); - let node: JSRef<Node> = NodeCast::from_ref(self); + let doc = document_from_node(self); + let node = NodeCast::from_ref(self); doc.r().content_changed(node, NodeDamage::OtherNodeDamage) } @@ -399,9 +404,8 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { fn get_radio_group_name(self) -> Option<String> { //TODO: determine form owner - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.get_attribute(&ns!(""), &atom!("name")) - .root() .map(|name| name.r().Value()) } @@ -423,7 +427,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { //TODO: dispatch change event } - fn get_size(&self) -> u32 { + fn get_size(self) -> u32 { self.size.get() } @@ -435,7 +439,7 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { fn mutable(self) -> bool { // https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable // https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); !(node.get_disabled_state() || self.ReadOnly()) } @@ -456,20 +460,20 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> { } } -impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { +impl<'a> VirtualMethods for &'a HTMLInputElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); } @@ -525,14 +529,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); node.check_ancestors_disabled_state_for_form_control(); @@ -584,7 +588,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { s.bind_to_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.check_ancestors_disabled_state_for_form_control(); } @@ -593,15 +597,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { s.unbind_from_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); - if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) { + let node = NodeCast::from_ref(*self); + if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { node.check_ancestors_disabled_state_for_form_control(); } else { node.check_disabled_attribute(); } } - fn handle_event(&self, event: JSRef<Event>) { + fn handle_event(&self, event: &Event) { if let Some(s) = self.super_type() { s.handle_event(event); } @@ -617,12 +621,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { //TODO: set the editing position for text inputs - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); doc.r().request_focus(ElementCast::from_ref(*self)); } else if &*event.Type() == "keydown" && !event.DefaultPrevented() && (self.input_type.get() == InputType::InputText || self.input_type.get() == InputType::InputPassword) { - let keyevent: Option<JSRef<KeyboardEvent>> = KeyboardEventCast::to_ref(event); + let keyevent: Option<&KeyboardEvent> = KeyboardEventCast::to_ref(event); keyevent.map(|keyevent| { // This can't be inlined, as holding on to textinput.borrow_mut() // during self.implicit_submission will cause a panic. @@ -646,15 +650,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> { } } -impl<'a> FormControl<'a> for JSRef<'a, HTMLInputElement> { - fn to_element(self) -> JSRef<'a, Element> { +impl<'a> FormControl<'a> for &'a HTMLInputElement { + fn to_element(self) -> &'a Element { ElementCast::from_ref(self) } } -impl<'a> Activatable for JSRef<'a, HTMLInputElement> { - fn as_element(&self) -> Temporary<Element> { - Temporary::from_rooted(ElementCast::from_ref(*self)) +impl<'a> Activatable for &'a HTMLInputElement { + fn as_element<'b>(&'b self) -> &'b Element { + ElementCast::from_ref(*self) } fn is_instance_activatable(&self) -> bool { @@ -697,22 +701,21 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):pre-click-activation-steps InputType::InputRadio => { //TODO: if not in document, use root ancestor instead of document - let owner = self.form_owner().root(); - let doc = document_from_node(*self).root(); - let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let owner = self.form_owner(); + let doc = document_from_node(*self); + let doc_node = NodeCast::from_ref(doc.r()); let group = self.get_radio_group_name();; // Safe since we only manipulate the DOM tree after finding an element let checked_member = unsafe { doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap() - .filter_map(HTMLInputElementCast::to_temporary) - .map(|t| t.root()) + .filter_map(HTMLInputElementCast::to_root) .find(|r| { in_same_group(r.r(), owner.r(), group.as_ref().map(|gr| &**gr)) && r.r().Checked() }) }; - cache.checked_radio.set(checked_member.r().map(JS::from_rooted)); + cache.checked_radio.set(checked_member.r().map(JS::from_ref)); cache.checked_changed = self.checked_changed.get(); self.SetChecked(true); } @@ -748,7 +751,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { InputType::InputRadio => { // We want to restore state only if the element had been changed in the first place if cache.was_mutable { - let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.get().root(); + let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.get().map(|t| t.root()); let name = self.get_radio_group_name(); match old_checked { Some(ref o) => { @@ -773,7 +776,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { } // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps - fn activation_behavior(&self, _event: JSRef<Event>, _target: JSRef<EventTarget>) { + fn activation_behavior(&self, _event: &Event, _target: &EventTarget) { let ty = self.input_type.get(); if self.activation_state.borrow().old_type != ty { // Type changed, abandon ship @@ -786,8 +789,8 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // FIXME (Manishearth): support document owners (needs ability to get parent browsing context) if self.mutable() /* and document owner is fully active */ { self.form_owner().map(|o| { - o.root().r().submit(SubmittedFrom::NotFromFormSubmitMethod, - FormSubmitter::InputElement(self.clone())) + o.r().submit(SubmittedFrom::NotFromFormSubmitMethod, + FormSubmitter::InputElement(self.clone())) }); } }, @@ -796,7 +799,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // FIXME (Manishearth): support document owners (needs ability to get parent browsing context) if self.mutable() /* and document owner is fully active */ { self.form_owner().map(|o| { - o.root().r().reset(ResetFrom::NotFromFormResetMethod) + o.r().reset(ResetFrom::NotFromFormResetMethod) }); } }, @@ -804,19 +807,19 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior // https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior if self.mutable() { - let win = window_from_node(*self).root(); + let win = window_from_node(*self); let event = Event::new(GlobalRef::Window(win.r()), "input".to_owned(), EventBubbles::Bubbles, - EventCancelable::NotCancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self); + EventCancelable::NotCancelable); + let target = EventTargetCast::from_ref(*self); event.r().fire(target); let event = Event::new(GlobalRef::Window(win.r()), "change".to_owned(), EventBubbles::Bubbles, - EventCancelable::NotCancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self); + EventCancelable::NotCancelable); + let target = EventTargetCast::from_ref(*self); event.r().fire(target); } }, @@ -827,15 +830,15 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // https://html.spec.whatwg.org/multipage/#implicit-submission #[allow(unsafe_code)] fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) { - let doc = document_from_node(*self).root(); - let node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let doc = document_from_node(*self); + let node = NodeCast::from_ref(doc.r()); let owner = self.form_owner(); let form = match owner { None => return, - Some(ref f) => f.root() + Some(ref f) => f }; - let elem: JSRef<Element> = ElementCast::from_ref(*self); + let elem = ElementCast::from_ref(*self); if elem.click_in_progress() { return; } @@ -844,8 +847,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { let submit_button; unsafe { submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap() - .filter_map(HTMLInputElementCast::to_temporary) - .map(|t| t.root()) + .filter_map(HTMLInputElementCast::to_root) .find(|r| r.r().form_owner() == owner); } match submit_button { @@ -859,9 +861,8 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> { // Safe because we don't perform any DOM modification // until we're done with the iterator. let inputs = node.query_selector_iter("input".to_owned()).unwrap() - .filter_map(HTMLInputElementCast::to_temporary) + .filter_map(HTMLInputElementCast::to_root) .filter(|input| { - let input = input.root(); input.r().form_owner() == owner && match &*input.r().Type() { "text" | "search" | "url" | "tel" | "email" | "password" | "datetime" | diff --git a/components/script/dom/htmllabelelement.rs b/components/script/dom/htmllabelelement.rs index 926b789e98c..45d10e9bf89 100644 --- a/components/script/dom/htmllabelelement.rs +++ b/components/script/dom/htmllabelelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLLabelElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLabelElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLLabelElementDerived for EventTarget { impl HTMLLabelElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLLabelElement { + document: &Document) -> HTMLLabelElement { HTMLLabelElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLabelElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLLabelElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLLabelElement> { + document: &Document) -> Root<HTMLLabelElement> { let element = HTMLLabelElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLLabelElementBinding::Wrap) } diff --git a/components/script/dom/htmllegendelement.rs b/components/script/dom/htmllegendelement.rs index 49f3e712b9f..7795af24806 100644 --- a/components/script/dom/htmllegendelement.rs +++ b/components/script/dom/htmllegendelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLLegendElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLegendElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLLegendElementDerived for EventTarget { impl HTMLLegendElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLLegendElement { + document: &Document) -> HTMLLegendElement { HTMLLegendElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLegendElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLLegendElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLLegendElement> { + document: &Document) -> Root<HTMLLegendElement> { let element = HTMLLegendElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLLegendElementBinding::Wrap) } diff --git a/components/script/dom/htmllielement.rs b/components/script/dom/htmllielement.rs index f8d8b0939c8..658664c82c4 100644 --- a/components/script/dom/htmllielement.rs +++ b/components/script/dom/htmllielement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLLIElementBinding; use dom::bindings::codegen::InheritTypes::HTMLLIElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLLIElementDerived for EventTarget { } impl HTMLLIElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLLIElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLLIElement { HTMLLIElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLIElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLLIElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLLIElement> { + document: &Document) -> Root<HTMLLIElement> { let element = HTMLLIElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLLIElementBinding::Wrap) } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index a707942544f..0389cd85de4 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -11,8 +11,8 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLLinkElementDerived}; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, Temporary}; -use dom::bindings::js::{OptionalRootable, RootedReference}; +use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{RootedReference}; use dom::bindings::refcounted::Trusted; use dom::document::{Document, DocumentHelpers}; use dom::domtokenlist::DOMTokenList; @@ -53,7 +53,7 @@ impl HTMLLinkElementDerived for EventTarget { } impl HTMLLinkElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLLinkElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLLinkElement { HTMLLinkElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLLinkElement, localName, prefix, document), rel_list: Default::default(), @@ -63,14 +63,14 @@ impl HTMLLinkElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLLinkElement> { + document: &Document) -> Root<HTMLLinkElement> { let element = HTMLLinkElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLLinkElementBinding::Wrap) } } -fn get_attr(element: JSRef<Element>, local_name: &Atom) -> Option<String> { - let elem = element.get_attribute(&ns!(""), local_name).root(); +fn get_attr(element: &Element, local_name: &Atom) -> Option<String> { + let elem = element.get_attribute(&ns!(""), local_name); elem.r().map(|e| { let value = e.value(); (**value).to_owned() @@ -100,23 +100,23 @@ fn is_favicon(value: &Option<String>) -> bool { } } -impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { +impl<'a> VirtualMethods for &'a HTMLLinkElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if !node.is_in_doc() { return; } - let element: JSRef<Element> = ElementCast::from_ref(*self); + let element = ElementCast::from_ref(*self); let rel = get_attr(element, &atom!("rel")); match (rel, attr.local_name()) { @@ -149,7 +149,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> { } if tree_in_doc { - let element: JSRef<Element> = ElementCast::from_ref(*self); + let element = ElementCast::from_ref(*self); let rel = get_attr(element, &atom!("rel")); let href = get_attr(element, &atom!("href")); @@ -172,15 +172,15 @@ trait PrivateHTMLLinkElementHelpers { fn handle_favicon_url(self, href: &str); } -impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { +impl<'a> PrivateHTMLLinkElementHelpers for &'a HTMLLinkElement { fn handle_stylesheet_url(self, href: &str) { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); match UrlParser::new().base_url(&window.get_url()).parse(href) { Ok(url) => { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); - let mq_attribute = element.get_attribute(&ns!(""), &atom!("media")).root(); + let mq_attribute = element.get_attribute(&ns!(""), &atom!("media")); let value = mq_attribute.r().map(|a| a.value()); let mq_str = match value { Some(ref value) => &***value, @@ -189,7 +189,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { let mut css_parser = CssParser::new(&mq_str); let media = parse_media_query_list(&mut css_parser); - let doc = window.Document().root(); + let doc = window.Document(); let link_element = Trusted::new(window.get_cx(), self, window.script_chan().clone()); let load_dispatcher = StylesheetLoadDispatcher::new(link_element); @@ -202,7 +202,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { } fn handle_favicon_url(self, href: &str) { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); match UrlParser::new().base_url(&window.get_url()).parse(href) { Ok(url) => { @@ -215,7 +215,7 @@ impl<'a> PrivateHTMLLinkElementHelpers for JSRef<'a, HTMLLinkElement> { } } -impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> { +impl<'a> HTMLLinkElementMethods for &'a HTMLLinkElement { make_url_getter!(Href); make_setter!(SetHref, "href"); @@ -231,7 +231,7 @@ impl<'a> HTMLLinkElementMethods for JSRef<'a, HTMLLinkElement> { make_getter!(Type); make_setter!(SetType, "type"); - fn RelList(self) -> Temporary<DOMTokenList> { + fn RelList(self) -> Root<DOMTokenList> { self.rel_list.or_init(|| { DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel")) }) @@ -252,11 +252,11 @@ impl StylesheetLoadDispatcher { impl StylesheetLoadResponder for StylesheetLoadDispatcher { fn respond(self: Box<StylesheetLoadDispatcher>) { - let elem = self.elem.to_temporary().root(); - let window = window_from_node(elem.r()).root(); + let elem = self.elem.root(); + let window = window_from_node(elem.r()); let event = Event::new(GlobalRef::Window(window.r()), "load".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); + EventCancelable::NotCancelable); let target = EventTargetCast::from_ref(elem.r()); event.r().fire(target); } diff --git a/components/script/dom/htmlmapelement.rs b/components/script/dom/htmlmapelement.rs index 4e3654e47c1..98927d6357c 100644 --- a/components/script/dom/htmlmapelement.rs +++ b/components/script/dom/htmlmapelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLMapElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMapElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLMapElementDerived for EventTarget { impl HTMLMapElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLMapElement { + document: &Document) -> HTMLMapElement { HTMLMapElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMapElement, localName, prefix, document) } @@ -37,7 +37,7 @@ impl HTMLMapElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLMapElement> { + document: &Document) -> Root<HTMLMapElement> { let element = HTMLMapElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLMapElementBinding::Wrap) } diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index c9dcfd36ccd..40700c69629 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -2,7 +2,6 @@ * 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::{JSRef}; use dom::bindings::codegen::InheritTypes::HTMLMediaElementDerived; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -28,7 +27,7 @@ impl HTMLMediaElementDerived for EventTarget { impl HTMLMediaElement { pub fn new_inherited(type_id: HTMLMediaElementTypeId, tag_name: DOMString, - prefix: Option<DOMString>, document: JSRef<Document>) + prefix: Option<DOMString>, document: &Document) -> HTMLMediaElement { HTMLMediaElement { htmlelement: diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 9b6967e036b..926fbf2c11f 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::HTMLMetaElementBinding; use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods; use dom::bindings::codegen::InheritTypes::HTMLMetaElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -29,7 +29,7 @@ impl HTMLMetaElementDerived for EventTarget { impl HTMLMetaElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLMetaElement { + document: &Document) -> HTMLMetaElement { HTMLMetaElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMetaElement, localName, prefix, document) } @@ -38,13 +38,13 @@ impl HTMLMetaElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLMetaElement> { + document: &Document) -> Root<HTMLMetaElement> { let element = HTMLMetaElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLMetaElementBinding::Wrap) } } -impl<'a> HTMLMetaElementMethods for JSRef<'a, HTMLMetaElement> { +impl<'a> HTMLMetaElementMethods for &'a HTMLMetaElement { // https://html.spec.whatwg.org/multipage/#dom-meta-name make_getter!(Name, "name"); diff --git a/components/script/dom/htmlmeterelement.rs b/components/script/dom/htmlmeterelement.rs index f81fd57346e..ee9e556308d 100644 --- a/components/script/dom/htmlmeterelement.rs +++ b/components/script/dom/htmlmeterelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLMeterElementBinding; use dom::bindings::codegen::InheritTypes::HTMLMeterElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLMeterElementDerived for EventTarget { impl HTMLMeterElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLMeterElement { + document: &Document) -> HTMLMeterElement { HTMLMeterElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLMeterElement, localName, prefix, document) } @@ -37,7 +37,7 @@ impl HTMLMeterElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLMeterElement> { + document: &Document) -> Root<HTMLMeterElement> { let element = HTMLMeterElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLMeterElementBinding::Wrap) } diff --git a/components/script/dom/htmlmodelement.rs b/components/script/dom/htmlmodelement.rs index 015381228bf..c7888ea2046 100644 --- a/components/script/dom/htmlmodelement.rs +++ b/components/script/dom/htmlmodelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLModElementBinding; use dom::bindings::codegen::InheritTypes::HTMLModElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLModElementDerived for EventTarget { impl HTMLModElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLModElement { + document: &Document) -> HTMLModElement { HTMLModElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLModElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLModElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLModElement> { + document: &Document) -> Root<HTMLModElement> { let element = HTMLModElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLModElementBinding::Wrap) } diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs index bb247aa52c1..3ea6db1bd4e 100644 --- a/components/script/dom/htmlobjectelement.rs +++ b/components/script/dom/htmlobjectelement.rs @@ -10,9 +10,8 @@ use dom::bindings::codegen::Bindings::HTMLObjectElementBinding; use dom::bindings::codegen::Bindings::HTMLObjectElementBinding::HTMLObjectElementMethods; use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; -use dom::element::Element; use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -42,7 +41,7 @@ impl HTMLObjectElementDerived for EventTarget { impl HTMLObjectElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLObjectElement { + document: &Document) -> HTMLObjectElement { HTMLObjectElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLObjectElement, localName, prefix, document), @@ -53,7 +52,7 @@ impl HTMLObjectElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLObjectElement> { + document: &Document) -> Root<HTMLObjectElement> { let element = HTMLObjectElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLObjectElementBinding::Wrap) } @@ -63,15 +62,15 @@ trait ProcessDataURL { fn process_data_url(&self); } -impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> { +impl<'a> ProcessDataURL for &'a HTMLObjectElement { // Makes the local `data` member match the status of the `data` attribute and starts /// prefetching the image. This method must be called after `data` is changed. fn process_data_url(&self) { - let elem: JSRef<Element> = ElementCast::from_ref(*self); + let elem = ElementCast::from_ref(*self); // TODO: support other values - match (elem.get_attribute(&ns!(""), &atom!("type")).map(|x| x.root().r().Value()), - elem.get_attribute(&ns!(""), &atom!("data")).map(|x| x.root().r().Value())) { + match (elem.get_attribute(&ns!(""), &atom!("type")).map(|x| x.r().Value()), + elem.get_attribute(&ns!(""), &atom!("data")).map(|x| x.r().Value())) { (None, Some(_uri)) => { // TODO(gw): Prefetch the image here. } @@ -85,9 +84,9 @@ pub fn is_image_data(uri: &str) -> bool { TYPES.iter().any(|&type_| uri.starts_with(type_)) } -impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> { - fn Validity(self) -> Temporary<ValidityState> { - let window = window_from_node(self).root(); +impl<'a> HTMLObjectElementMethods for &'a HTMLObjectElement { + fn Validity(self) -> Root<ValidityState> { + let window = window_from_node(self); ValidityState::new(window.r()) } @@ -98,13 +97,13 @@ impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> { make_setter!(SetType, "type"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> { +impl<'a> VirtualMethods for &'a HTMLObjectElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } diff --git a/components/script/dom/htmlolistelement.rs b/components/script/dom/htmlolistelement.rs index 0441dc636e5..c71028709de 100644 --- a/components/script/dom/htmlolistelement.rs +++ b/components/script/dom/htmlolistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLOListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLOListElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLOListElementDerived for EventTarget { impl HTMLOListElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLOListElement { + document: &Document) -> HTMLOListElement { HTMLOListElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOListElement, localName, prefix, document) } @@ -37,7 +37,7 @@ impl HTMLOListElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLOListElement> { + document: &Document) -> Root<HTMLOListElement> { let element = HTMLOListElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLOListElementBinding::Wrap) } diff --git a/components/script/dom/htmloptgroupelement.rs b/components/script/dom/htmloptgroupelement.rs index 15e70190ba3..76f0a3c283e 100644 --- a/components/script/dom/htmloptgroupelement.rs +++ b/components/script/dom/htmloptgroupelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding; use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, HTMLOptionElementDerived}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -35,7 +35,7 @@ impl HTMLOptGroupElementDerived for EventTarget { impl HTMLOptGroupElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLOptGroupElement { + document: &Document) -> HTMLOptGroupElement { HTMLOptGroupElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptGroupElement, localName, prefix, document) @@ -45,13 +45,13 @@ impl HTMLOptGroupElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLOptGroupElement> { + document: &Document) -> Root<HTMLOptGroupElement> { let element = HTMLOptGroupElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLOptGroupElementBinding::Wrap) } } -impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> { +impl<'a> HTMLOptGroupElementMethods for &'a HTMLOptGroupElement { // https://www.whatwg.org/html#dom-optgroup-disabled make_bool_getter!(Disabled); @@ -59,24 +59,23 @@ impl<'a> HTMLOptGroupElementMethods for JSRef<'a, HTMLOptGroupElement> { make_bool_setter!(SetDisabled, "disabled"); } -impl<'a> VirtualMethods for JSRef<'a, HTMLOptGroupElement> { +impl<'a> VirtualMethods for &'a HTMLOptGroupElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); for child in node.children() { - let child = child.root(); if child.r().is_htmloptionelement() { child.r().set_disabled_state(true); child.r().set_enabled_state(false); @@ -87,18 +86,17 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptGroupElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); for child in node.children() { - let child = child.root(); if child.r().is_htmloptionelement() { child.r().check_disabled_attribute(); } diff --git a/components/script/dom/htmloptionelement.rs b/components/script/dom/htmloptionelement.rs index ec40d819b2c..b675f30ac03 100644 --- a/components/script/dom/htmloptionelement.rs +++ b/components/script/dom/htmloptionelement.rs @@ -7,14 +7,13 @@ use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods; use dom::bindings::codegen::Bindings::HTMLOptionElementBinding; use dom::bindings::codegen::Bindings::HTMLOptionElementBinding::HTMLOptionElementMethods; -use dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast, HTMLElementCast, NodeCast}; +use dom::bindings::codegen::InheritTypes::{CharacterDataCast, ElementCast, HTMLElementCast, NodeCast, TextDerived}; use dom::bindings::codegen::InheritTypes::{HTMLOptionElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived}; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::js::{JSRef, Rootable, Temporary}; -use dom::characterdata::CharacterData; +use dom::bindings::js::Root; use dom::document::Document; -use dom::element::{AttributeHandlers, Element, ElementHelpers}; +use dom::element::{AttributeHandlers, ElementHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; @@ -39,7 +38,7 @@ impl HTMLOptionElementDerived for EventTarget { impl HTMLOptionElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLOptionElement { + document: &Document) -> HTMLOptionElement { HTMLOptionElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOptionElement, localName, prefix, document) @@ -49,23 +48,22 @@ impl HTMLOptionElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLOptionElement> { + document: &Document) -> Root<HTMLOptionElement> { let element = HTMLOptionElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLOptionElementBinding::Wrap) } } -fn collect_text(node: &JSRef<Node>, value: &mut DOMString) { - let elem: JSRef<Element> = ElementCast::to_ref(*node).unwrap(); +fn collect_text(node: &&Node, value: &mut DOMString) { + let elem = ElementCast::to_ref(*node).unwrap(); let svg_script = *elem.namespace() == ns!(SVG) && elem.local_name() == &atom!("script"); let html_script = node.is_htmlscriptelement(); if svg_script || html_script { return; } else { for child in node.children() { - let child = child.root(); if child.r().is_text() { - let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(child.r()).unwrap(); + let characterdata = CharacterDataCast::to_ref(child.r()).unwrap(); value.push_str(&characterdata.Data()); } else { collect_text(&child.r(), value); @@ -74,19 +72,19 @@ fn collect_text(node: &JSRef<Node>, value: &mut DOMString) { } } -impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { +impl<'a> HTMLOptionElementMethods for &'a HTMLOptionElement { // https://www.whatwg.org/html/#dom-option-disabled make_bool_getter!(Disabled); // https://www.whatwg.org/html/#dom-option-disabled fn SetDisabled(self, disabled: bool) { - let elem: JSRef<Element> = ElementCast::from_ref(self); + let elem = ElementCast::from_ref(self); elem.set_bool_attribute(&atom!("disabled"), disabled) } // https://www.whatwg.org/html/#dom-option-text fn Text(self) -> DOMString { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let mut content = String::new(); collect_text(&node, &mut content); let v: Vec<&str> = split_html_space_chars(&content).collect(); @@ -95,13 +93,13 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { // https://www.whatwg.org/html/#dom-option-text fn SetText(self, value: DOMString) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.SetTextContent(Some(value)) } // https://html.spec.whatwg.org/multipage/#attr-option-value fn Value(self) -> DOMString { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let attr = &atom!("value"); if element.has_attribute(attr) { element.get_string_attribute(attr) @@ -115,7 +113,7 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { // https://html.spec.whatwg.org/multipage/#attr-option-label fn Label(self) -> DOMString { - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let attr = &atom!("label"); if element.has_attribute(attr) { element.get_string_attribute(attr) @@ -129,20 +127,20 @@ impl<'a> HTMLOptionElementMethods for JSRef<'a, HTMLOptionElement> { } -impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> { +impl<'a> VirtualMethods for &'a HTMLOptionElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); }, @@ -150,14 +148,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); node.check_parent_disabled_state_for_option(); @@ -171,7 +169,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> { s.bind_to_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.check_parent_disabled_state_for_option(); } @@ -180,7 +178,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLOptionElement> { s.unbind_from_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if node.GetParentNode().is_some() { node.check_parent_disabled_state_for_option(); } else { diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs index 79cba6418df..9b6ac86e365 100644 --- a/components/script/dom/htmloutputelement.rs +++ b/components/script/dom/htmloutputelement.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::HTMLOutputElementBinding; use dom::bindings::codegen::Bindings::HTMLOutputElementBinding::HTMLOutputElementMethods; use dom::bindings::codegen::InheritTypes::HTMLOutputElementDerived; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -30,7 +30,7 @@ impl HTMLOutputElementDerived for EventTarget { impl HTMLOutputElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLOutputElement { + document: &Document) -> HTMLOutputElement { HTMLOutputElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLOutputElement, localName, prefix, document) @@ -40,15 +40,15 @@ impl HTMLOutputElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLOutputElement> { + document: &Document) -> Root<HTMLOutputElement> { let element = HTMLOutputElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLOutputElementBinding::Wrap) } } -impl<'a> HTMLOutputElementMethods for JSRef<'a, HTMLOutputElement> { - fn Validity(self) -> Temporary<ValidityState> { - let window = window_from_node(self).root(); +impl<'a> HTMLOutputElementMethods for &'a HTMLOutputElement { + fn Validity(self) -> Root<ValidityState> { + let window = window_from_node(self); ValidityState::new(window.r()) } } diff --git a/components/script/dom/htmlparagraphelement.rs b/components/script/dom/htmlparagraphelement.rs index 3d580c11928..62f7d271c4a 100644 --- a/components/script/dom/htmlparagraphelement.rs +++ b/components/script/dom/htmlparagraphelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLParagraphElementBinding; use dom::bindings::codegen::InheritTypes::HTMLParagraphElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLParagraphElementDerived for EventTarget { impl HTMLParagraphElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLParagraphElement { + document: &Document) -> HTMLParagraphElement { HTMLParagraphElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLParagraphElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLParagraphElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLParagraphElement> { + document: &Document) -> Root<HTMLParagraphElement> { let element = HTMLParagraphElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLParagraphElementBinding::Wrap) } diff --git a/components/script/dom/htmlparamelement.rs b/components/script/dom/htmlparamelement.rs index 491064de085..2942ccf49ca 100644 --- a/components/script/dom/htmlparamelement.rs +++ b/components/script/dom/htmlparamelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLParamElementBinding; use dom::bindings::codegen::InheritTypes::HTMLParamElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLParamElementDerived for EventTarget { impl HTMLParamElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLParamElement { + document: &Document) -> HTMLParamElement { HTMLParamElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLParamElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLParamElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLParamElement> { + document: &Document) -> Root<HTMLParamElement> { let element = HTMLParamElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLParamElementBinding::Wrap) } diff --git a/components/script/dom/htmlpreelement.rs b/components/script/dom/htmlpreelement.rs index 6b7fdc2825e..956301296ef 100644 --- a/components/script/dom/htmlpreelement.rs +++ b/components/script/dom/htmlpreelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLPreElementBinding; use dom::bindings::codegen::InheritTypes::HTMLPreElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLPreElementDerived for EventTarget { impl HTMLPreElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLPreElement { + document: &Document) -> HTMLPreElement { HTMLPreElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLPreElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLPreElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLPreElement> { + document: &Document) -> Root<HTMLPreElement> { let element = HTMLPreElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLPreElementBinding::Wrap) } diff --git a/components/script/dom/htmlprogresselement.rs b/components/script/dom/htmlprogresselement.rs index 4a58ac6d835..7449f79dcac 100644 --- a/components/script/dom/htmlprogresselement.rs +++ b/components/script/dom/htmlprogresselement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLProgressElementBinding; use dom::bindings::codegen::InheritTypes::HTMLProgressElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLProgressElementDerived for EventTarget { impl HTMLProgressElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLProgressElement { + document: &Document) -> HTMLProgressElement { HTMLProgressElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLProgressElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLProgressElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLProgressElement> { + document: &Document) -> Root<HTMLProgressElement> { let element = HTMLProgressElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLProgressElementBinding::Wrap) } diff --git a/components/script/dom/htmlquoteelement.rs b/components/script/dom/htmlquoteelement.rs index f89e4004e57..a08f95147e4 100644 --- a/components/script/dom/htmlquoteelement.rs +++ b/components/script/dom/htmlquoteelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLQuoteElementBinding; use dom::bindings::codegen::InheritTypes::HTMLQuoteElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLQuoteElementDerived for EventTarget { impl HTMLQuoteElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLQuoteElement { + document: &Document) -> HTMLQuoteElement { HTMLQuoteElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLQuoteElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLQuoteElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLQuoteElement> { + document: &Document) -> Root<HTMLQuoteElement> { let element = HTMLQuoteElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLQuoteElementBinding::Wrap) } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 35a5d83ad03..8bdbdb8759e 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -17,12 +17,12 @@ use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, HTMLScriptE use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable, Rootable}; +use dom::bindings::js::{JS, Root}; use dom::bindings::js::RootedReference; use dom::bindings::refcounted::Trusted; use dom::bindings::trace::JSTraceable; use dom::document::{Document, DocumentHelpers}; -use dom::element::{Element, AttributeHandlers, ElementCreator}; +use dom::element::{AttributeHandlers, ElementCreator}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers}; use dom::element::ElementTypeId; @@ -33,6 +33,8 @@ use dom::virtualmethods::VirtualMethods; use dom::window::{WindowHelpers, ScriptHelpers}; use network_listener::{NetworkListener, PreInvoke}; use script_task::{ScriptChan, ScriptMsg, Runnable}; +use js::jsapi::RootedValue; +use js::jsval::UndefinedValue; use encoding::all::UTF_8; use encoding::label::encoding_from_whatwg_label; @@ -82,7 +84,7 @@ impl HTMLScriptElementDerived for EventTarget { } impl HTMLScriptElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>, + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document, creator: ElementCreator) -> HTMLScriptElement { HTMLScriptElement { htmlelement: @@ -91,14 +93,14 @@ impl HTMLScriptElement { parser_inserted: Cell::new(creator == ElementCreator::ParserCreated), non_blocking: Cell::new(creator != ElementCreator::ParserCreated), ready_to_be_parser_executed: Cell::new(false), - parser_document: JS::from_rooted(document), + parser_document: JS::from_ref(document), block_character_encoding: DOMRefCell::new(UTF_8 as EncodingRef), } } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>, - creator: ElementCreator) -> Temporary<HTMLScriptElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document, + creator: ElementCreator) -> Root<HTMLScriptElement> { let element = HTMLScriptElement::new_inherited(localName, prefix, document, creator); Node::reflect_node(box element, document, HTMLScriptElementBinding::Wrap) } @@ -190,22 +192,22 @@ impl AsyncResponseListener for ScriptContext { let metadata = self.metadata.borrow_mut().take().unwrap(); (metadata, data) }); - let elem = self.elem.to_temporary().root(); + let elem = self.elem.root(); elem.r().execute(ScriptOrigin::External(load)); - let document = document_from_node(elem.r()).root(); + let document = document_from_node(elem.r()); document.r().finish_load(LoadType::Script(self.url.clone())); if self.resume_on_completion { - document.r().get_current_parser().unwrap().root().r().resume(); + document.r().get_current_parser().unwrap().r().resume(); } } } impl PreInvoke for ScriptContext {} -impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { +impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement { fn prepare(self) -> NextParserState { // https://html.spec.whatwg.org/multipage/#prepare-a-script // Step 1. @@ -217,7 +219,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { self.parser_inserted.set(false); // Step 3. - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); if was_parser_inserted && element.has_attribute(&atom!("async")) { self.non_blocking.set(true); } @@ -227,7 +229,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { return NextParserState::Continue; } // Step 5. - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); if !node.is_in_doc() { return NextParserState::Continue; } @@ -244,7 +246,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { self.already_started.set(true); // Step 10. - let document_from_node_ref = document_from_node(self).root(); + let document_from_node_ref = document_from_node(self); let document_from_node_ref = document_from_node_ref.r(); if self.parser_inserted.get() && self.parser_document.root().r() != document_from_node_ref { return NextParserState::Continue; @@ -256,8 +258,8 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } // Step 12. - let for_attribute = element.get_attribute(&ns!(""), &atom!("for")).root(); - let event_attribute = element.get_attribute(&ns!(""), &Atom::from_slice("event")).root(); + let for_attribute = element.get_attribute(&ns!(""), &atom!("for")); + let event_attribute = element.get_attribute(&ns!(""), &Atom::from_slice("event")); match (for_attribute.r(), event_attribute.r()) { (Some(for_attribute), Some(event_attribute)) => { let for_value = for_attribute.Value() @@ -277,18 +279,18 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } // Step 13. - if let Some(ref charset) = element.get_attribute(&ns!(""), &Atom::from_slice("charset")).root() { + if let Some(ref charset) = element.get_attribute(&ns!(""), &Atom::from_slice("charset")) { if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) { *self.block_character_encoding.borrow_mut() = encodingRef; } } // Step 14. - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let base_url = window.get_url(); - let load = match element.get_attribute(&ns!(""), &atom!("src")).root() { + let load = match element.get_attribute(&ns!(""), &atom!("src")) { // Step 14. Some(ref src) => { // Step 14.1 @@ -314,7 +316,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // state of the element's `crossorigin` content attribute, the origin being // the origin of the script element's node document, and the default origin // behaviour set to taint. - let doc = document_from_node(self).root(); + let doc = document_from_node(self); let script_chan = window.script_chan(); let elem = Trusted::new(window.get_cx(), self, script_chan.clone()); @@ -335,7 +337,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { doc.r().load_async(LoadType::Script(url), listener); if self.parser_inserted.get() { - doc.r().get_current_parser().unwrap().root().r().suspend(); + doc.r().get_current_parser().unwrap().r().suspend(); } return NextParserState::Suspend; } @@ -409,18 +411,20 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { // document. Let neutralised doc be that Document. // Step 2.b.4. - let document = document_from_node(self).root(); + let document = document_from_node(self); let document = document.r(); - let old_script = document.GetCurrentScript().root(); + let old_script = document.GetCurrentScript(); // Step 2.b.5. document.set_current_script(Some(self)); // Step 2.b.6. // TODO: Create a script... - let window = window_from_node(self).root(); + let window = window_from_node(self); + let mut rval = RootedValue::new(window.r().get_cx(), UndefinedValue()); window.r().evaluate_script_on_global_with_result(&*source, - &*url.serialize()); + &*url.serialize(), + rval.handle_mut()); // Step 2.b.7. document.set_current_script(old_script.r()); @@ -447,7 +451,7 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } fn queue_error_event(self) { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let chan = window.script_chan(); let handler = Trusted::new(window.get_cx(), self, chan.clone()); @@ -483,8 +487,8 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { } fn is_javascript(self) -> bool { - let element: JSRef<Element> = ElementCast::from_ref(self); - match element.get_attribute(&ns!(""), &atom!("type")).root().map(|s| s.r().Value()) { + let element = ElementCast::from_ref(self); + match element.get_attribute(&ns!(""), &atom!("type")).map(|s| s.r().Value()) { Some(ref s) if s.is_empty() => { // type attr exists, but empty means js debug!("script type empty, inferring js"); @@ -497,7 +501,6 @@ impl<'a> HTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { None => { debug!("no script type"); match element.get_attribute(&ns!(""), &atom!("language")) - .root() .map(|s| s.r().Value()) { Some(ref s) if s.is_empty() => { debug!("script language empty, inferring js"); @@ -528,44 +531,44 @@ trait PrivateHTMLScriptElementHelpers { cancelable: EventCancelable) -> bool; } -impl<'a> PrivateHTMLScriptElementHelpers for JSRef<'a, HTMLScriptElement> { +impl<'a> PrivateHTMLScriptElementHelpers for &'a HTMLScriptElement { fn dispatch_event(self, type_: DOMString, bubbles: EventBubbles, cancelable: EventCancelable) -> bool { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let event = Event::new(GlobalRef::Window(window), type_, bubbles, - cancelable).root(); + cancelable); let event = event.r(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let target = EventTargetCast::from_ref(self); event.fire(target) } } -impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> { +impl<'a> VirtualMethods for &'a HTMLScriptElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if attr.local_name() == &atom!("src") && !self.parser_inserted.get() && node.is_in_doc() { self.prepare(); } } - fn child_inserted(&self, child: JSRef<Node>) { + fn child_inserted(&self, child: &Node) { if let Some(ref s) = self.super_type() { s.child_inserted(child); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if !self.parser_inserted.get() && node.is_in_doc() { self.prepare(); } @@ -581,7 +584,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> { } } - fn cloning_steps(&self, copy: JSRef<Node>, maybe_doc: Option<JSRef<Document>>, + fn cloning_steps(&self, copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag) { if let Some(ref s) = self.super_type() { s.cloning_steps(copy, maybe_doc, clone_children); @@ -589,13 +592,13 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLScriptElement> { // https://whatwg.org/html/#already-started if self.already_started.get() { - let copy_elem: JSRef<HTMLScriptElement> = HTMLScriptElementCast::to_ref(copy).unwrap(); + let copy_elem = HTMLScriptElementCast::to_ref(copy).unwrap(); copy_elem.mark_already_started(); } } } -impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> { +impl<'a> HTMLScriptElementMethods for &'a HTMLScriptElement { make_url_getter!(Src); make_setter!(SetSrc, "src"); @@ -607,7 +610,7 @@ impl<'a> HTMLScriptElementMethods for JSRef<'a, HTMLScriptElement> { // https://www.whatwg.org/html/#dom-script-text fn SetText(self, value: DOMString) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.SetTextContent(Some(value)) } } @@ -619,7 +622,7 @@ struct EventDispatcher { impl Runnable for EventDispatcher { fn handler(self: Box<EventDispatcher>) { - let target = self.element.to_temporary().root(); + let target = self.element.root(); if self.is_error { target.r().dispatch_error_event(); } else { diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index c2537a06d46..a33e8d419ba 100644 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{HTMLSelectElementDerived, HTMLFieldSetElementDerived}; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::AttributeHandlers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -42,7 +42,7 @@ static DEFAULT_SELECT_SIZE: u32 = 0; impl HTMLSelectElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLSelectElement { + document: &Document) -> HTMLSelectElement { HTMLSelectElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLSelectElement, localName, prefix, document) @@ -52,15 +52,15 @@ impl HTMLSelectElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLSelectElement> { + document: &Document) -> Root<HTMLSelectElement> { let element = HTMLSelectElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLSelectElementBinding::Wrap) } } -impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> { - fn Validity(self) -> Temporary<ValidityState> { - let window = window_from_node(self).root(); +impl<'a> HTMLSelectElementMethods for &'a HTMLSelectElement { + fn Validity(self) -> Root<ValidityState> { + let window = window_from_node(self); ValidityState::new(window.r()) } @@ -102,20 +102,20 @@ impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> { } } -impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> { +impl<'a> VirtualMethods for &'a HTMLSelectElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); }, @@ -123,14 +123,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); node.check_ancestors_disabled_state_for_form_control(); @@ -144,7 +144,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> { s.bind_to_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.check_ancestors_disabled_state_for_form_control(); } @@ -153,8 +153,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> { s.unbind_from_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); - if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) { + let node = NodeCast::from_ref(*self); + if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { node.check_ancestors_disabled_state_for_form_control(); } else { node.check_disabled_attribute(); diff --git a/components/script/dom/htmlsourceelement.rs b/components/script/dom/htmlsourceelement.rs index a30b2689843..d93eb56f132 100644 --- a/components/script/dom/htmlsourceelement.rs +++ b/components/script/dom/htmlsourceelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLSourceElementBinding; use dom::bindings::codegen::InheritTypes::HTMLSourceElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLSourceElementDerived for EventTarget { impl HTMLSourceElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLSourceElement { + document: &Document) -> HTMLSourceElement { HTMLSourceElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLSourceElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLSourceElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLSourceElement> { + document: &Document) -> Root<HTMLSourceElement> { let element = HTMLSourceElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLSourceElementBinding::Wrap) } diff --git a/components/script/dom/htmlspanelement.rs b/components/script/dom/htmlspanelement.rs index cbd68c1b186..8772b143871 100644 --- a/components/script/dom/htmlspanelement.rs +++ b/components/script/dom/htmlspanelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLSpanElementBinding; use dom::bindings::codegen::InheritTypes::HTMLSpanElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLSpanElementDerived for EventTarget { } impl HTMLSpanElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLSpanElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLSpanElement { HTMLSpanElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLSpanElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLSpanElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLSpanElement> { + document: &Document) -> Root<HTMLSpanElement> { let element = HTMLSpanElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLSpanElementBinding::Wrap) } diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 8ab295a24af..66ee4f79836 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -6,10 +6,10 @@ use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::HTMLStyleElementBinding; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLStyleElementDerived, NodeCast}; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, Temporary, RootedReference}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; -use dom::element::{Element, ElementTypeId, AttributeHandlers}; +use dom::element::{ElementTypeId, AttributeHandlers}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; @@ -36,7 +36,7 @@ impl HTMLStyleElementDerived for EventTarget { impl HTMLStyleElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLStyleElement { + document: &Document) -> HTMLStyleElement { HTMLStyleElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLStyleElement, localName, prefix, document) } @@ -45,7 +45,7 @@ impl HTMLStyleElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLStyleElement> { + document: &Document) -> Root<HTMLStyleElement> { let element = HTMLStyleElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLStyleElementBinding::Wrap) } @@ -55,21 +55,20 @@ pub trait StyleElementHelpers { fn parse_own_css(self); } -impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { +impl<'a> StyleElementHelpers for &'a HTMLStyleElement { fn parse_own_css(self) { - let node: JSRef<Node> = NodeCast::from_ref(self); - let element: JSRef<Element> = ElementCast::from_ref(self); + let node = NodeCast::from_ref(self); + let element = ElementCast::from_ref(self); assert!(node.is_in_doc()); - let win = window_from_node(node).root(); + let win = window_from_node(node); let win = win.r(); let url = win.get_url(); - let mq_attribute = element.get_attribute(&ns!(""), &atom!("media")).root(); - let value = mq_attribute.r().map(|a| a.value()); - let mq_str = match value { - Some(ref value) => &***value, - None => "", + let mq_attribute = element.get_attribute(&ns!(""), &atom!("media")); + let mq_str = match mq_attribute { + Some(a) => String::from_str(&**a.r().value()), + None => String::new(), }; let mut css_parser = CssParser::new(&mq_str); let media = parse_media_query_list(&mut css_parser); @@ -81,18 +80,18 @@ impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> { } } -impl<'a> VirtualMethods for JSRef<'a, HTMLStyleElement> { +impl<'a> VirtualMethods for &'a HTMLStyleElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn child_inserted(&self, child: JSRef<Node>) { + fn child_inserted(&self, child: &Node) { if let Some(ref s) = self.super_type() { s.child_inserted(child); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if node.is_in_doc() { self.parse_own_css(); } diff --git a/components/script/dom/htmltablecaptionelement.rs b/components/script/dom/htmltablecaptionelement.rs index ec60a9e3955..6f6c9223902 100644 --- a/components/script/dom/htmltablecaptionelement.rs +++ b/components/script/dom/htmltablecaptionelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTableCaptionElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableCaptionElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLTableCaptionElementDerived for EventTarget { impl HTMLTableCaptionElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTableCaptionElement { + document: &Document) -> HTMLTableCaptionElement { HTMLTableCaptionElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableCaptionElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLTableCaptionElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTableCaptionElement> { + document: &Document) -> Root<HTMLTableCaptionElement> { let element = HTMLTableCaptionElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableCaptionElementBinding::Wrap) } diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index 7acc0f7e4ec..76d04ae8217 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -5,7 +5,6 @@ use dom::attr::{Attr, AttrHelpers, AttrValue}; use dom::bindings::codegen::Bindings::HTMLTableCellElementBinding::HTMLTableCellElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCellElementDerived}; -use dom::bindings::js::JSRef; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -59,7 +58,7 @@ impl HTMLTableCellElement { pub fn new_inherited(type_id: HTMLTableCellElementTypeId, tag_name: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) + document: &Document) -> HTMLTableCellElement { HTMLTableCellElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableCellElement(type_id), @@ -76,39 +75,39 @@ impl HTMLTableCellElement { } } -impl<'a> HTMLTableCellElementMethods for JSRef<'a, HTMLTableCellElement> { +impl<'a> HTMLTableCellElementMethods for &'a HTMLTableCellElement { // https://html.spec.whatwg.org/multipage/#dom-tdth-colspan make_uint_getter!(ColSpan, "colspan", DEFAULT_COLSPAN); make_uint_setter!(SetColSpan, "colspan"); } pub trait HTMLTableCellElementHelpers { - fn get_background_color(&self) -> Option<RGBA>; - fn get_colspan(&self) -> Option<u32>; - fn get_width(&self) -> LengthOrPercentageOrAuto; + fn get_background_color(self) -> Option<RGBA>; + fn get_colspan(self) -> Option<u32>; + fn get_width(self) -> LengthOrPercentageOrAuto; } -impl HTMLTableCellElementHelpers for HTMLTableCellElement { - fn get_background_color(&self) -> Option<RGBA> { +impl<'a> HTMLTableCellElementHelpers for &'a HTMLTableCellElement { + fn get_background_color(self) -> Option<RGBA> { self.background_color.get() } - fn get_colspan(&self) -> Option<u32> { + fn get_colspan(self) -> Option<u32> { self.colspan.get() } - fn get_width(&self) -> LengthOrPercentageOrAuto { + fn get_width(self) -> LengthOrPercentageOrAuto { self.width.get() } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { +impl<'a> VirtualMethods for &'a HTMLTableCellElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -130,7 +129,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmltablecolelement.rs b/components/script/dom/htmltablecolelement.rs index 48262a71aba..37981cebc2d 100644 --- a/components/script/dom/htmltablecolelement.rs +++ b/components/script/dom/htmltablecolelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTableColElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableColElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLTableColElementDerived for EventTarget { impl HTMLTableColElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTableColElement { + document: &Document) -> HTMLTableColElement { HTMLTableColElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableColElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLTableColElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTableColElement> { + document: &Document) -> Root<HTMLTableColElement> { let element = HTMLTableColElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableColElementBinding::Wrap) } diff --git a/components/script/dom/htmltabledatacellelement.rs b/components/script/dom/htmltabledatacellelement.rs index 48dd4e21fe4..684ec8078a4 100644 --- a/components/script/dom/htmltabledatacellelement.rs +++ b/components/script/dom/htmltabledatacellelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTableDataCellElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableDataCellElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -30,7 +30,7 @@ impl HTMLTableDataCellElementDerived for EventTarget { impl HTMLTableDataCellElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTableDataCellElement { + document: &Document) -> HTMLTableDataCellElement { HTMLTableDataCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited( @@ -39,8 +39,8 @@ impl HTMLTableDataCellElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) - -> Temporary<HTMLTableDataCellElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) + -> Root<HTMLTableDataCellElement> { Node::reflect_node(box HTMLTableDataCellElement::new_inherited(localName, prefix, document), diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs index 0f254f07ad6..2ff2d69a0b5 100644 --- a/components/script/dom/htmltableelement.rs +++ b/components/script/dom/htmltableelement.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::HTMLTableElementBinding; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableCaptionElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLTableElementDerived, NodeCast}; -use dom::bindings::js::{JSRef, Rootable, Temporary, OptionalRootable, RootedReference}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -42,7 +42,7 @@ impl HTMLTableElementDerived for EventTarget { } impl HTMLTableElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTableElement { HTMLTableElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableElement, @@ -57,30 +57,29 @@ impl HTMLTableElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) - -> Temporary<HTMLTableElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) + -> Root<HTMLTableElement> { let element = HTMLTableElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableElementBinding::Wrap) } } -impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { +impl<'a> HTMLTableElementMethods for &'a HTMLTableElement { // https://www.whatwg.org/html/#dom-table-caption - fn GetCaption(self) -> Option<Temporary<HTMLTableCaptionElement>> { - let node: JSRef<Node> = NodeCast::from_ref(self); + fn GetCaption(self) -> Option<Root<HTMLTableCaptionElement>> { + let node = NodeCast::from_ref(self); node.children() - .map(|c| c.root()) .filter_map(|c| { - HTMLTableCaptionElementCast::to_ref(c.r()).map(Temporary::from_rooted) + HTMLTableCaptionElementCast::to_ref(c.r()).map(Root::from_ref) }) .next() } // https://www.whatwg.org/html/#dom-table-caption - fn SetCaption(self, new_caption: Option<JSRef<HTMLTableCaptionElement>>) { - let node: JSRef<Node> = NodeCast::from_ref(self); + fn SetCaption(self, new_caption: Option<&HTMLTableCaptionElement>) { + let node = NodeCast::from_ref(self); - if let Some(ref caption) = self.GetCaption().root() { + if let Some(ref caption) = self.GetCaption() { assert!(node.RemoveChild(NodeCast::from_ref(caption.r())).is_ok()); } @@ -91,37 +90,37 @@ impl<'a> HTMLTableElementMethods for JSRef<'a, HTMLTableElement> { } pub trait HTMLTableElementHelpers { - fn get_background_color(&self) -> Option<RGBA>; - fn get_border(&self) -> Option<u32>; - fn get_cellspacing(&self) -> Option<u32>; - fn get_width(&self) -> LengthOrPercentageOrAuto; + fn get_background_color(self) -> Option<RGBA>; + fn get_border(self) -> Option<u32>; + fn get_cellspacing(self) -> Option<u32>; + fn get_width(self) -> LengthOrPercentageOrAuto; } -impl HTMLTableElementHelpers for HTMLTableElement { - fn get_background_color(&self) -> Option<RGBA> { +impl<'a> HTMLTableElementHelpers for &'a HTMLTableElement { + fn get_background_color(self) -> Option<RGBA> { self.background_color.get() } - fn get_border(&self) -> Option<u32> { + fn get_border(self) -> Option<u32> { self.border.get() } - fn get_cellspacing(&self) -> Option<u32> { + fn get_cellspacing(self) -> Option<u32> { self.cellspacing.get() } - fn get_width(&self) -> LengthOrPercentageOrAuto { + fn get_width(self) -> LengthOrPercentageOrAuto { self.width.get() } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> { +impl<'a> VirtualMethods for &'a HTMLTableElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -143,7 +142,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmltableheadercellelement.rs b/components/script/dom/htmltableheadercellelement.rs index 48a31e5b0a6..c7aa052eb7d 100644 --- a/components/script/dom/htmltableheadercellelement.rs +++ b/components/script/dom/htmltableheadercellelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTableHeaderCellElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTableHeaderCellElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::htmlelement::HTMLElementTypeId; @@ -30,7 +30,7 @@ impl HTMLTableHeaderCellElementDerived for EventTarget { impl HTMLTableHeaderCellElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTableHeaderCellElement { + document: &Document) -> HTMLTableHeaderCellElement { HTMLTableHeaderCellElement { htmltablecellelement: HTMLTableCellElement::new_inherited( HTMLTableCellElementTypeId::HTMLTableHeaderCellElement, localName, prefix, document) @@ -40,7 +40,7 @@ impl HTMLTableHeaderCellElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTableHeaderCellElement> { + document: &Document) -> Root<HTMLTableHeaderCellElement> { let element = HTMLTableHeaderCellElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableHeaderCellElementBinding::Wrap) } diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs index 5f8be49d964..7ebae106632 100644 --- a/components/script/dom/htmltablerowelement.rs +++ b/components/script/dom/htmltablerowelement.rs @@ -5,7 +5,7 @@ use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableRowElementDerived}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -32,7 +32,7 @@ impl HTMLTableRowElementDerived for EventTarget { } impl HTMLTableRowElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTableRowElement { HTMLTableRowElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableRowElement, @@ -44,8 +44,8 @@ impl HTMLTableRowElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) - -> Temporary<HTMLTableRowElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) + -> Root<HTMLTableRowElement> { Node::reflect_node(box HTMLTableRowElement::new_inherited(localName, prefix, document), document, HTMLTableRowElementBinding::Wrap) @@ -54,22 +54,22 @@ impl HTMLTableRowElement { pub trait HTMLTableRowElementHelpers { - fn get_background_color(&self) -> Option<RGBA>; + fn get_background_color(self) -> Option<RGBA>; } -impl HTMLTableRowElementHelpers for HTMLTableRowElement { - fn get_background_color(&self) -> Option<RGBA> { +impl<'a> HTMLTableRowElementHelpers for &'a HTMLTableRowElement { + fn get_background_color(self) -> Option<RGBA> { self.background_color.get() } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTableRowElement> { +impl<'a> VirtualMethods for &'a HTMLTableRowElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -82,7 +82,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableRowElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmltablesectionelement.rs b/components/script/dom/htmltablesectionelement.rs index 10dbf4c7b6c..6c37c0923c3 100644 --- a/components/script/dom/htmltablesectionelement.rs +++ b/components/script/dom/htmltablesectionelement.rs @@ -5,7 +5,7 @@ use dom::attr::{Attr, AttrHelpers}; use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTableSectionElementDerived}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -32,7 +32,7 @@ impl HTMLTableSectionElementDerived for EventTarget { } impl HTMLTableSectionElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTableSectionElement { HTMLTableSectionElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTableSectionElement, @@ -44,30 +44,30 @@ impl HTMLTableSectionElement { } #[allow(unrooted_must_root)] - pub fn new(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) - -> Temporary<HTMLTableSectionElement> { + pub fn new(localName: DOMString, prefix: Option<DOMString>, document: &Document) + -> Root<HTMLTableSectionElement> { let element = HTMLTableSectionElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTableSectionElementBinding::Wrap) } } pub trait HTMLTableSectionElementHelpers { - fn get_background_color(&self) -> Option<RGBA>; + fn get_background_color(self) -> Option<RGBA>; } -impl HTMLTableSectionElementHelpers for HTMLTableSectionElement { - fn get_background_color(&self) -> Option<RGBA> { +impl<'a> HTMLTableSectionElementHelpers for &'a HTMLTableSectionElement { + fn get_background_color(self) -> Option<RGBA> { self.background_color.get() } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTableSectionElement> { +impl<'a> VirtualMethods for &'a HTMLTableSectionElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -80,7 +80,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableSectionElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } diff --git a/components/script/dom/htmltemplateelement.rs b/components/script/dom/htmltemplateelement.rs index 50678811ee0..2d37dd5593a 100644 --- a/components/script/dom/htmltemplateelement.rs +++ b/components/script/dom/htmltemplateelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTemplateElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -28,7 +28,7 @@ impl HTMLTemplateElementDerived for EventTarget { impl HTMLTemplateElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTemplateElement { + document: &Document) -> HTMLTemplateElement { HTMLTemplateElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTemplateElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLTemplateElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTemplateElement> { + document: &Document) -> Root<HTMLTemplateElement> { let element = HTMLTemplateElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTemplateElementBinding::Wrap) } diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 3fc78914173..21a7b9ab2af 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -13,8 +13,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLEle use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived}; use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, LayoutJS, OptionalRootable, Rootable}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::refcounted::Trusted; use dom::document::{Document, DocumentHelpers}; use dom::element::{Element, AttributeHandlers}; @@ -63,9 +62,9 @@ pub trait LayoutHTMLTextAreaElementHelpers { pub trait RawLayoutHTMLTextAreaElementHelpers { #[allow(unsafe_code)] - unsafe fn get_cols_for_layout(&self) -> u32; + unsafe fn get_cols_for_layout(self) -> u32; #[allow(unsafe_code)] - unsafe fn get_rows_for_layout(&self) -> u32; + unsafe fn get_rows_for_layout(self) -> u32; } impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> { @@ -76,16 +75,16 @@ impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> { } } -impl RawLayoutHTMLTextAreaElementHelpers for HTMLTextAreaElement { +impl<'a> RawLayoutHTMLTextAreaElementHelpers for &'a HTMLTextAreaElement { #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_cols_for_layout(&self) -> u32 { + unsafe fn get_cols_for_layout(self) -> u32 { self.cols.get() } #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn get_rows_for_layout(&self) -> u32 { + unsafe fn get_rows_for_layout(self) -> u32 { self.rows.get() } } @@ -96,8 +95,8 @@ static DEFAULT_ROWS: u32 = 2; impl HTMLTextAreaElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLTextAreaElement { - let chan = document.window().root().r().constellation_chan(); + document: &Document) -> HTMLTextAreaElement { + let chan = document.window().r().constellation_chan(); HTMLTextAreaElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTextAreaElement, localName, prefix, document), @@ -111,13 +110,13 @@ impl HTMLTextAreaElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTextAreaElement> { + document: &Document) -> Root<HTMLTextAreaElement> { let element = HTMLTextAreaElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTextAreaElementBinding::Wrap) } } -impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> { +impl<'a> HTMLTextAreaElementMethods for &'a HTMLTextAreaElement { // TODO A few of these attributes have default values and additional // constraints @@ -172,13 +171,13 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> { // https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue fn DefaultValue(self) -> DOMString { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.GetTextContent().unwrap() } // https://html.spec.whatwg.org/multipage/#dom-textarea-defaultvalue fn SetDefaultValue(self, value: DOMString) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.SetTextContent(Some(value)); // if the element's dirty value flag is false, then the element's @@ -210,7 +209,7 @@ pub trait HTMLTextAreaElementHelpers { fn reset(self); } -impl<'a> HTMLTextAreaElementHelpers for JSRef<'a, HTMLTextAreaElement> { +impl<'a> HTMLTextAreaElementHelpers for &'a HTMLTextAreaElement { // https://html.spec.whatwg.org/multipage/#concept-fe-mutable fn mutable(self) -> bool { // https://html.spec.whatwg.org/multipage/#the-textarea-element:concept-fe-mutable @@ -228,40 +227,40 @@ trait PrivateHTMLTextAreaElementHelpers { fn dispatch_change_event(self); } -impl<'a> PrivateHTMLTextAreaElementHelpers for JSRef<'a, HTMLTextAreaElement> { +impl<'a> PrivateHTMLTextAreaElementHelpers for &'a HTMLTextAreaElement { fn force_relayout(self) { - let doc = document_from_node(self).root(); - let node: JSRef<Node> = NodeCast::from_ref(self); + let doc = document_from_node(self); + let node = NodeCast::from_ref(self); doc.r().content_changed(node, NodeDamage::OtherNodeDamage) } fn dispatch_change_event(self) { - let window = window_from_node(self).root(); + let window = window_from_node(self); let window = window.r(); let event = Event::new(GlobalRef::Window(window), "input".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); + EventCancelable::NotCancelable); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let target = EventTargetCast::from_ref(self); target.dispatch_event(event.r()); } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { +impl<'a> VirtualMethods for &'a HTMLTextAreaElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(true); node.set_enabled_state(false); }, @@ -281,14 +280,14 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { } } - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } match attr.local_name() { &atom!("disabled") => { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.set_disabled_state(false); node.set_enabled_state(true); node.check_ancestors_disabled_state_for_form_control(); @@ -308,7 +307,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { s.bind_to_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); node.check_ancestors_disabled_state_for_form_control(); } @@ -325,15 +324,15 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { s.unbind_from_tree(tree_in_doc); } - let node: JSRef<Node> = NodeCast::from_ref(*self); - if node.ancestors().any(|ancestor| ancestor.root().r().is_htmlfieldsetelement()) { + let node = NodeCast::from_ref(*self); + if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { node.check_ancestors_disabled_state_for_form_control(); } else { node.check_disabled_attribute(); } } - fn child_inserted(&self, child: JSRef<Node>) { + fn child_inserted(&self, child: &Node) { if let Some(s) = self.super_type() { s.child_inserted(child); } @@ -344,7 +343,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { } // copied and modified from htmlinputelement.rs - fn handle_event(&self, event: JSRef<Event>) { + fn handle_event(&self, event: &Event) { if let Some(s) = self.super_type() { s.handle_event(event); } @@ -352,10 +351,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { if &*event.Type() == "click" && !event.DefaultPrevented() { //TODO: set the editing position for text inputs - let doc = document_from_node(*self).root(); + let doc = document_from_node(*self); doc.r().request_focus(ElementCast::from_ref(*self)); } else if &*event.Type() == "keydown" && !event.DefaultPrevented() { - let keyevent: Option<JSRef<KeyboardEvent>> = KeyboardEventCast::to_ref(event); + let keyevent: Option<&KeyboardEvent> = KeyboardEventCast::to_ref(event); keyevent.map(|kevent| { match self.textinput.borrow_mut().handle_keydown(kevent) { KeyReaction::TriggerDefaultAction => (), @@ -363,10 +362,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { self.value_changed.set(true); if event.IsTrusted() { - let window = window_from_node(*self).root(); + let window = window_from_node(*self); let window = window.r(); let chan = window.script_chan(); - let handler = Trusted::new(window.get_cx(), *self , chan.clone()); + let handler = Trusted::new(window.get_cx(), *self, chan.clone()); let dispatcher = ChangeEventRunnable { element: handler, }; @@ -382,8 +381,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> { } } -impl<'a> FormControl<'a> for JSRef<'a, HTMLTextAreaElement> { - fn to_element(self) -> JSRef<'a, Element> { +impl<'a> FormControl<'a> for &'a HTMLTextAreaElement { + fn to_element(self) -> &'a Element { ElementCast::from_ref(self) } } @@ -394,7 +393,7 @@ pub struct ChangeEventRunnable { impl Runnable for ChangeEventRunnable { fn handler(self: Box<ChangeEventRunnable>) { - let target = self.element.to_temporary().root(); + let target = self.element.root(); target.r().dispatch_change_event(); } } diff --git a/components/script/dom/htmltimeelement.rs b/components/script/dom/htmltimeelement.rs index 4fda22809b8..828ba4b912a 100644 --- a/components/script/dom/htmltimeelement.rs +++ b/components/script/dom/htmltimeelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTimeElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTimeElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLTimeElementDerived for EventTarget { } impl HTMLTimeElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTimeElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTimeElement { HTMLTimeElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTimeElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLTimeElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTimeElement> { + document: &Document) -> Root<HTMLTimeElement> { let element = HTMLTimeElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTimeElementBinding::Wrap) } diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs index 3ce8cd7db2c..a6585bd17b4 100644 --- a/components/script/dom/htmltitleelement.rs +++ b/components/script/dom/htmltitleelement.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::HTMLTitleElementBinding::HTMLTitleElementM use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLTitleElementDerived, NodeCast}; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, TextCast}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::characterdata::CharacterDataHelpers; use dom::document::{Document, DocumentHelpers}; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -32,7 +32,7 @@ impl HTMLTitleElementDerived for EventTarget { } impl HTMLTitleElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTitleElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTitleElement { HTMLTitleElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTitleElement, localName, prefix, document) } @@ -41,20 +41,19 @@ impl HTMLTitleElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTitleElement> { + document: &Document) -> Root<HTMLTitleElement> { let element = HTMLTitleElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTitleElementBinding::Wrap) } } -impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> { +impl<'a> HTMLTitleElementMethods for &'a HTMLTitleElement { // https://www.whatwg.org/html/#dom-title-text fn Text(self) -> DOMString { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); let mut content = String::new(); for child in node.children() { - let child = child.root(); - let text: Option<JSRef<Text>> = TextCast::to_ref(child.r()); + let text: Option<&Text> = TextCast::to_ref(child.r()); match text { Some(text) => content.push_str(&CharacterDataCast::from_ref(text).data()), None => (), @@ -65,33 +64,33 @@ impl<'a> HTMLTitleElementMethods for JSRef<'a, HTMLTitleElement> { // https://www.whatwg.org/html/#dom-title-text fn SetText(self, value: DOMString) { - let node: JSRef<Node> = NodeCast::from_ref(self); + let node = NodeCast::from_ref(self); node.SetTextContent(Some(value)) } } -impl<'a> VirtualMethods for JSRef<'a, HTMLTitleElement> { +impl<'a> VirtualMethods for &'a HTMLTitleElement { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let htmlelement: &JSRef<HTMLElement> = HTMLElementCast::from_borrowed_ref(self); + let htmlelement: &&HTMLElement = HTMLElementCast::from_borrowed_ref(self); Some(htmlelement as &VirtualMethods) } - fn child_inserted(&self, child: JSRef<Node>) { + fn child_inserted(&self, child: &Node) { if let Some(ref s) = self.super_type() { s.child_inserted(child); } - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if node.is_in_doc() { - let document = node.owner_doc().root(); + let document = node.owner_doc(); document.r().title_changed(); } } fn bind_to_tree(&self, is_in_doc: bool) { - let node: JSRef<Node> = NodeCast::from_ref(*self); + let node = NodeCast::from_ref(*self); if is_in_doc { - let document = node.owner_doc().root(); + let document = node.owner_doc(); document.r().title_changed(); } } diff --git a/components/script/dom/htmltrackelement.rs b/components/script/dom/htmltrackelement.rs index 1a07ced2ab5..ba13e20ed4d 100644 --- a/components/script/dom/htmltrackelement.rs +++ b/components/script/dom/htmltrackelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLTrackElementBinding; use dom::bindings::codegen::InheritTypes::HTMLTrackElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLTrackElementDerived for EventTarget { } impl HTMLTrackElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLTrackElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLTrackElement { HTMLTrackElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLTrackElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLTrackElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLTrackElement> { + document: &Document) -> Root<HTMLTrackElement> { let element = HTMLTrackElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLTrackElementBinding::Wrap) } diff --git a/components/script/dom/htmlulistelement.rs b/components/script/dom/htmlulistelement.rs index b5deb9f0b96..0287757d002 100644 --- a/components/script/dom/htmlulistelement.rs +++ b/components/script/dom/htmlulistelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLUListElementBinding; use dom::bindings::codegen::InheritTypes::HTMLUListElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::element::ElementTypeId; @@ -26,7 +26,7 @@ impl HTMLUListElementDerived for EventTarget { } impl HTMLUListElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLUListElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLUListElement { HTMLUListElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLUListElement, localName, prefix, document) } @@ -35,7 +35,7 @@ impl HTMLUListElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLUListElement> { + document: &Document) -> Root<HTMLUListElement> { let element = HTMLUListElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLUListElementBinding::Wrap) } diff --git a/components/script/dom/htmlunknownelement.rs b/components/script/dom/htmlunknownelement.rs index 35c04fc1f47..33bc8a72cb8 100644 --- a/components/script/dom/htmlunknownelement.rs +++ b/components/script/dom/htmlunknownelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLUnknownElementBinding; use dom::bindings::codegen::InheritTypes::HTMLUnknownElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -28,7 +28,7 @@ impl HTMLUnknownElementDerived for EventTarget { impl HTMLUnknownElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> HTMLUnknownElement { + document: &Document) -> HTMLUnknownElement { HTMLUnknownElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLUnknownElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLUnknownElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLUnknownElement> { + document: &Document) -> Root<HTMLUnknownElement> { let element = HTMLUnknownElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLUnknownElementBinding::Wrap) } diff --git a/components/script/dom/htmlvideoelement.rs b/components/script/dom/htmlvideoelement.rs index 69046ec0181..b95f683bcd2 100644 --- a/components/script/dom/htmlvideoelement.rs +++ b/components/script/dom/htmlvideoelement.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::HTMLVideoElementBinding; use dom::bindings::codegen::InheritTypes::HTMLVideoElementDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::document::Document; use dom::element::ElementTypeId; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -28,7 +28,7 @@ impl HTMLVideoElementDerived for EventTarget { } impl HTMLVideoElement { - fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLVideoElement { + fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: &Document) -> HTMLVideoElement { HTMLVideoElement { htmlmediaelement: HTMLMediaElement::new_inherited(HTMLMediaElementTypeId::HTMLVideoElement, localName, prefix, document) @@ -38,7 +38,7 @@ impl HTMLVideoElement { #[allow(unrooted_must_root)] pub fn new(localName: DOMString, prefix: Option<DOMString>, - document: JSRef<Document>) -> Temporary<HTMLVideoElement> { + document: &Document) -> Root<HTMLVideoElement> { let element = HTMLVideoElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLVideoElementBinding::Wrap) } diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index 04c99d08a64..513ef791689 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -5,15 +5,16 @@ use dom::bindings::codegen::Bindings::ImageDataBinding; use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use euclid::size::Size2D; -use js::jsapi::{JSContext, JSObject}; -use js::jsfriendapi::bindgen::{JS_NewUint8ClampedArray, JS_GetUint8ClampedArrayData}; +use js::jsapi::{JSContext, JSObject, Heap}; +use js::jsapi::{JS_NewUint8ClampedArray, JS_GetUint8ClampedArrayData}; use libc::uint8_t; use std::vec::Vec; use std::slice; use std::ptr; +use std::default::Default; #[dom_struct] #[allow(raw_pointer_derive)] @@ -21,58 +22,57 @@ pub struct ImageData { reflector_: Reflector, width: u32, height: u32, - data: *mut JSObject, + data: Heap<*mut JSObject>, } impl ImageData { #[allow(unsafe_code)] - fn new_inherited(width: u32, height: u32, data: Option<Vec<u8>>, global: GlobalRef) -> ImageData { + pub fn new(global: GlobalRef, width: u32, height: u32, data: Option<Vec<u8>>) -> Root<ImageData> { + let mut imagedata = box ImageData { + reflector_: Reflector::new(), + width: width, + height: height, + data: Heap::default(), + }; + unsafe { let cx = global.get_cx(); let js_object: *mut JSObject = JS_NewUint8ClampedArray(cx, width * height * 4); if let Some(vec) = data { - let js_object_data: *mut uint8_t = JS_GetUint8ClampedArrayData(js_object, cx); + let js_object_data: *mut uint8_t = JS_GetUint8ClampedArrayData(js_object, ptr::null()); ptr::copy_nonoverlapping(vec.as_ptr(), js_object_data, vec.len()) } - - ImageData { - reflector_: Reflector::new(), - width: width, - height: height, - data: js_object, - } + (*imagedata).data.set(js_object); } - } - pub fn new(global: GlobalRef, width: u32, height: u32, data: Option<Vec<u8>>) -> Temporary<ImageData> { - reflect_dom_object(box ImageData::new_inherited(width, height, data, global), + reflect_dom_object(imagedata, global, ImageDataBinding::Wrap) } } pub trait ImageDataHelpers { fn get_data_array(self, global: &GlobalRef) -> Vec<u8>; - fn get_size(&self) -> Size2D<i32>; + fn get_size(self) -> Size2D<i32>; } -impl<'a> ImageDataHelpers for JSRef<'a, ImageData> { +impl<'a> ImageDataHelpers for &'a ImageData { #[allow(unsafe_code)] fn get_data_array(self, global: &GlobalRef) -> Vec<u8> { unsafe { let cx = global.get_cx(); - let data: *const uint8_t = JS_GetUint8ClampedArrayData(self.Data(cx), cx) as *const uint8_t; + let data: *const uint8_t = JS_GetUint8ClampedArrayData(self.Data(cx), ptr::null()) as *const uint8_t; let len = self.Width() * self.Height() * 4; slice::from_raw_parts(data, len as usize).to_vec() } } - fn get_size(&self) -> Size2D<i32> { + fn get_size(self) -> Size2D<i32> { Size2D::new(self.Width() as i32, self.Height() as i32) } } -impl<'a> ImageDataMethods for JSRef<'a, ImageData> { +impl<'a> ImageDataMethods for &'a ImageData { // https://html.spec.whatwg.org/multipage/#dom-imagedata-width fn Width(self) -> u32 { self.width @@ -85,6 +85,6 @@ impl<'a> ImageDataMethods for JSRef<'a, ImageData> { // https://html.spec.whatwg.org/multipage/#dom-imagedata-data fn Data(self, _: *mut JSContext) -> *mut JSObject { - self.data + self.data.get() } } diff --git a/components/script/dom/keyboardevent.rs b/components/script/dom/keyboardevent.rs index d0ac71c814c..e98dd2fe90a 100644 --- a/components/script/dom/keyboardevent.rs +++ b/components/script/dom/keyboardevent.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, UIEventCast, KeyboardEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary, Rootable, RootedReference}; +use dom::bindings::js::{Root, RootedReference}; use dom::bindings::utils::{Reflectable, reflect_dom_object}; use dom::event::{Event, EventTypeId}; use dom::uievent::UIEvent; @@ -65,17 +65,17 @@ impl KeyboardEvent { } } - pub fn new_uninitialized(window: JSRef<Window>) -> Temporary<KeyboardEvent> { + pub fn new_uninitialized(window: &Window) -> Root<KeyboardEvent> { reflect_dom_object(box KeyboardEvent::new_inherited(), GlobalRef::Window(window), KeyboardEventBinding::Wrap) } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, type_: DOMString, canBubble: bool, cancelable: bool, - view: Option<JSRef<Window>>, + view: Option<&Window>, _detail: i32, key: Option<Key>, key_string: DOMString, @@ -88,27 +88,29 @@ impl KeyboardEvent { shiftKey: bool, metaKey: bool, char_code: Option<u32>, - key_code: u32) -> Temporary<KeyboardEvent> { - let ev = KeyboardEvent::new_uninitialized(window).root(); + key_code: u32) -> Root<KeyboardEvent> { + let ev = KeyboardEvent::new_uninitialized(window); ev.r().InitKeyboardEvent(type_, canBubble, cancelable, view, key_string, location, "".to_owned(), repeat, "".to_owned()); // FIXME(https://github.com/rust-lang/rust/issues/23338) - let ev = ev.r(); - ev.key.set(key); - *ev.code.borrow_mut() = code; - ev.ctrl.set(ctrlKey); - ev.alt.set(altKey); - ev.shift.set(shiftKey); - ev.meta.set(metaKey); - ev.char_code.set(char_code); - ev.key_code.set(key_code); - ev.is_composing.set(isComposing); - Temporary::from_rooted(ev) + { + let ev = ev.r(); + ev.key.set(key); + *ev.code.borrow_mut() = code; + ev.ctrl.set(ctrlKey); + ev.alt.set(altKey); + ev.shift.set(shiftKey); + ev.meta.set(metaKey); + ev.char_code.set(char_code); + ev.key_code.set(key_code); + ev.is_composing.set(isComposing); + } + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &KeyboardEventBinding::KeyboardEventInit) -> Fallible<Temporary<KeyboardEvent>> { + init: &KeyboardEventBinding::KeyboardEventInit) -> Fallible<Root<KeyboardEvent>> { let event = KeyboardEvent::new(global.as_window(), type_, init.parent.parent.parent.bubbles, init.parent.parent.parent.cancelable, @@ -134,16 +136,16 @@ impl KeyboardEvent { } pub trait KeyboardEventHelpers { - fn get_key(&self) -> Option<Key>; - fn get_key_modifiers(&self) -> KeyModifiers; + fn get_key(self) -> Option<Key>; + fn get_key_modifiers(self) -> KeyModifiers; } -impl<'a> KeyboardEventHelpers for JSRef<'a, KeyboardEvent> { - fn get_key(&self) -> Option<Key> { +impl<'a> KeyboardEventHelpers for &'a KeyboardEvent { + fn get_key(self) -> Option<Key> { self.key.get().clone() } - fn get_key_modifiers(&self) -> KeyModifiers { + fn get_key_modifiers(self) -> KeyModifiers { let mut result = KeyModifiers::empty(); if self.shift.get() { result = result | constellation_msg::SHIFT; @@ -758,23 +760,23 @@ impl KeyEventProperties { } } -impl<'a> KeyboardEventMethods for JSRef<'a, KeyboardEvent> { +impl<'a> KeyboardEventMethods for &'a KeyboardEvent { fn InitKeyboardEvent(self, typeArg: DOMString, canBubbleArg: bool, cancelableArg: bool, - viewArg: Option<JSRef<Window>>, + viewArg: Option<&Window>, keyArg: DOMString, locationArg: u32, _modifiersListArg: DOMString, repeat: bool, _locale: DOMString) { - let event: JSRef<Event> = EventCast::from_ref(self); + let event = EventCast::from_ref(self); if event.dispatching() { return; } - let uievent: JSRef<UIEvent> = UIEventCast::from_ref(self); + let uievent = UIEventCast::from_ref(self); uievent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, 0); *self.key_string.borrow_mut() = keyArg; self.location.set(locationArg); diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index 20ead7dc298..3bde73d6f73 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::LocationBinding; use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::str::USVString; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::urlhelper::UrlHelper; @@ -22,21 +22,21 @@ pub struct Location { } impl Location { - fn new_inherited(window: JSRef<Window>) -> Location { + fn new_inherited(window: &Window) -> Location { Location { reflector_: Reflector::new(), - window: JS::from_rooted(window) + window: JS::from_ref(window) } } - pub fn new(window: JSRef<Window>) -> Temporary<Location> { + pub fn new(window: &Window) -> Root<Location> { reflect_dom_object(box Location::new_inherited(window), GlobalRef::Window(window), LocationBinding::Wrap) } } -impl<'a> LocationMethods for JSRef<'a, Location> { +impl<'a> LocationMethods for &'a Location { // https://html.spec.whatwg.org/multipage/#dom-location-assign fn Assign(self, url: DOMString) { self.window.root().r().load_url(url); @@ -72,7 +72,7 @@ trait PrivateLocationHelpers { fn get_url(self) -> Url; } -impl<'a> PrivateLocationHelpers for JSRef<'a, Location> { +impl<'a> PrivateLocationHelpers for &'a Location { fn get_url(self) -> Url { let window = self.window.root(); window.r().get_url() diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 97a8e7a74d7..a5efaab5c2e 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -6,10 +6,10 @@ macro_rules! make_getter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self) -> DOMString { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); element.get_string_attribute(&Atom::from_slice($htmlname)) } ); @@ -22,10 +22,10 @@ macro_rules! make_getter( macro_rules! make_bool_getter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self) -> bool { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not runtime. element.has_attribute(&Atom::from_slice($htmlname)) } @@ -39,10 +39,10 @@ macro_rules! make_bool_getter( macro_rules! make_uint_getter( ($attr:ident, $htmlname:expr, $default:expr) => ( fn $attr(self) -> u32 { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not runtime. element.get_uint_attribute(&Atom::from_slice($htmlname), $default) } @@ -59,10 +59,10 @@ macro_rules! make_uint_getter( macro_rules! make_url_getter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self) -> DOMString { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not runtime. element.get_url_attribute(&Atom::from_slice($htmlname)) } @@ -77,14 +77,14 @@ macro_rules! make_url_getter( macro_rules! make_url_or_base_getter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self) -> DOMString { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use dom::window::WindowHelpers; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let url = element.get_url_attribute(&Atom::from_slice($htmlname)); if url.is_empty() { - let window = window_from_node(self).root(); + let window = window_from_node(self); window.r().get_url().serialize() } else { url @@ -100,11 +100,11 @@ macro_rules! make_url_or_base_getter( macro_rules! make_enumerated_getter( ( $attr:ident, $htmlname:expr, $default:expr, $(($choices: pat))|+) => ( fn $attr(self) -> DOMString { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; use std::borrow::ToOwned; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); let val = element.get_string_attribute(&Atom::from_slice($htmlname)) .into_ascii_lowercase(); // https://html.spec.whatwg.org/multipage/#attr-fs-method @@ -125,10 +125,10 @@ macro_rules! make_enumerated_getter( macro_rules! make_setter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self, value: DOMString) { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not at runtime. element.set_string_attribute(&Atom::from_slice($htmlname), value) } @@ -139,10 +139,10 @@ macro_rules! make_setter( macro_rules! make_bool_setter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self, value: bool) { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not at runtime. element.set_bool_attribute(&Atom::from_slice($htmlname), value) } @@ -153,7 +153,7 @@ macro_rules! make_bool_setter( macro_rules! make_uint_setter( ($attr:ident, $htmlname:expr, $default:expr) => ( fn $attr(self, value: u32) { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; let value = if value > 2147483647 { @@ -161,7 +161,7 @@ macro_rules! make_uint_setter( } else { value }; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not at runtime. element.set_uint_attribute(&Atom::from_slice($htmlname), value) } @@ -203,10 +203,10 @@ macro_rules! make_limited_uint_setter( macro_rules! make_atomic_setter( ( $attr:ident, $htmlname:expr ) => ( fn $attr(self, value: DOMString) { - use dom::element::{Element, AttributeHandlers}; + use dom::element::AttributeHandlers; use dom::bindings::codegen::InheritTypes::ElementCast; use string_cache::Atom; - let element: JSRef<Element> = ElementCast::from_ref(self); + let element = ElementCast::from_ref(self); // FIXME(pcwalton): Do this at compile time, not at runtime. element.set_atomic_attribute(&Atom::from_slice($htmlname), value) } @@ -239,13 +239,13 @@ macro_rules! no_jsmanaged_fields( /// These are used to generate a event handler which has no special case. macro_rules! define_event_handler( ($handler: ident, $event_type: ident, $getter: ident, $setter: ident) => ( - fn $getter(self) -> Option<$handler> { - let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self); + fn $getter(self) -> Option<::std::rc::Rc<$handler>> { + let eventtarget = EventTargetCast::from_ref(self); eventtarget.get_event_handler_common(stringify!($event_type)) } - fn $setter(self, listener: Option<$handler>) { - let eventtarget: JSRef<EventTarget> = EventTargetCast::from_ref(self); + fn $setter(self, listener: Option<::std::rc::Rc<$handler>>) { + let eventtarget = EventTargetCast::from_ref(self); eventtarget.set_event_handler_common(stringify!($event_type), listener) } ) diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs index e74e8c95e59..6ba929b1ce4 100644 --- a/components/script/dom/messageevent.rs +++ b/components/script/dom/messageevent.rs @@ -8,22 +8,23 @@ use dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, MessageEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventHelpers, EventTypeId}; use dom::eventtarget::EventTarget; use util::str::DOMString; -use js::jsapi::JSContext; -use js::jsval::{JSVal, UndefinedValue}; +use js::jsapi::{JSContext, Heap, HandleValue}; +use js::jsval::JSVal; use std::borrow::ToOwned; +use std::default::Default; #[dom_struct] pub struct MessageEvent { event: Event, - data: JSVal, + data: Heap<JSVal>, origin: DOMString, lastEventId: DOMString, } @@ -35,64 +36,62 @@ impl MessageEventDerived for Event { } impl MessageEvent { - fn new_inherited(data: JSVal, origin: DOMString, lastEventId: DOMString) - -> MessageEvent { - MessageEvent { - event: Event::new_inherited(EventTypeId::MessageEvent), - data: data, - origin: origin, - lastEventId: lastEventId, - } - } - - pub fn new_uninitialized(global: GlobalRef) -> Temporary<MessageEvent> { - MessageEvent::new_initialized(global, UndefinedValue(), "".to_owned(), "".to_owned()) + pub fn new_uninitialized(global: GlobalRef) -> Root<MessageEvent> { + MessageEvent::new_initialized(global, HandleValue::undefined(), "".to_owned(), "".to_owned()) } pub fn new_initialized(global: GlobalRef, - data: JSVal, + data: HandleValue, origin: DOMString, - lastEventId: DOMString) -> Temporary<MessageEvent> { - reflect_dom_object(box MessageEvent::new_inherited(data, origin, lastEventId), - global, - MessageEventBinding::Wrap) + lastEventId: DOMString) -> Root<MessageEvent> { + let mut ev = box MessageEvent { + event: Event::new_inherited(EventTypeId::MessageEvent), + data: Heap::default(), + origin: origin, + lastEventId: lastEventId, + }; + ev.data.set(data.get()); + reflect_dom_object(ev, global, MessageEventBinding::Wrap) } pub fn new(global: GlobalRef, type_: DOMString, bubbles: bool, cancelable: bool, - data: JSVal, origin: DOMString, lastEventId: DOMString) - -> Temporary<MessageEvent> { - let ev = MessageEvent::new_initialized(global, data, origin, lastEventId).root(); - let event: JSRef<Event> = EventCast::from_ref(ev.r()); - event.InitEvent(type_, bubbles, cancelable); - Temporary::from_rooted(ev.r()) + data: HandleValue, origin: DOMString, lastEventId: DOMString) + -> Root<MessageEvent> { + let ev = MessageEvent::new_initialized(global, data, origin, lastEventId); + { + let event = EventCast::from_ref(ev.r()); + event.InitEvent(type_, bubbles, cancelable); + } + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, init: &MessageEventBinding::MessageEventInit) - -> Fallible<Temporary<MessageEvent>> { + -> Fallible<Root<MessageEvent>> { let ev = MessageEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable, - init.data, init.origin.clone(), init.lastEventId.clone()); + HandleValue { ptr: &init.data }, + init.origin.clone(), init.lastEventId.clone()); Ok(ev) } } impl MessageEvent { - pub fn dispatch_jsval(target: JSRef<EventTarget>, + pub fn dispatch_jsval(target: &EventTarget, scope: GlobalRef, - message: JSVal) { + message: HandleValue) { let messageevent = MessageEvent::new( scope, "message".to_owned(), false, false, message, - "".to_owned(), "".to_owned()).root(); - let event: JSRef<Event> = EventCast::from_ref(messageevent.r()); + "".to_owned(), "".to_owned()); + let event = EventCast::from_ref(messageevent.r()); event.fire(target); } } -impl<'a> MessageEventMethods for JSRef<'a, MessageEvent> { +impl<'a> MessageEventMethods for &'a MessageEvent { fn Data(self, _cx: *mut JSContext) -> JSVal { - self.data + self.data.get() } fn Origin(self) -> DOMString { diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 51ef5ca3c05..8aef70f6368 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -29,14 +29,12 @@ //! //! For more information, see: //! -//! * rooting pointers on the stack: the [`Root`](bindings/js/struct.Root.html) -//! and [`JSRef`](bindings/js/struct.JSRef.html) smart pointers; +//! * rooting pointers on the stack: +//! the [`Root`](bindings/js/struct.Root.html) smart pointer; //! * tracing pointers in member fields: the [`JS`](bindings/js/struct.JS.html), //! [`MutNullableJS`](bindings/js/struct.MutNullableJS.html) and //! [`MutHeap`](bindings/js/struct.MutHeap.html) smart pointers and //! [the tracing implementation](bindings/trace/index.html); -//! * returning pointers from functions: the -//! [`Temporary`](bindings/js/struct.Temporary.html) smart pointer; //! * rooting pointers from across task boundaries or in channels: the //! [`Trusted`](bindings/refcounted/struct.Trusted.html) smart pointer; //! * extracting pointers to DOM objects from their reflectors: the @@ -62,7 +60,7 @@ //! DOM objects of type `T` in Servo have two constructors: //! //! * a `T::new_inherited` static method that returns a plain `T`, and -//! * a `T::new` static method that returns `Temporary<T>`. +//! * a `T::new` static method that returns `Root<T>`. //! //! (The result of either method can be wrapped in `Result`, if that is //! appropriate for the type in question.) @@ -111,6 +109,7 @@ //! Implementing methods for a DOM object //! ===================================== //! +//! XXX JSRef no longer exists - should we remove the *Helpers traits? //! In order to ensure that DOM objects are rooted when they are called, we //! require that all methods are implemented for `JSRef<'a, Foo>`. This means //! that all methods are defined on traits. Conventionally, those traits are @@ -121,24 +120,12 @@ //! * `FooHelpers` for public methods; //! * `PrivateFooHelpers` for private methods. //! -//! Calling methods on a DOM object -//! =============================== -//! -//! To call a method on a DOM object, we require that the object is rooted, by -//! calling `.root()` on a `Temporary` or `JS` pointer. This constructs a -//! `Root` on the stack, which ensures the DOM object stays alive for the -//! duration of its lifetime. A `JSRef` on which to call the method can then be -//! obtained by calling the `r()` method on the `Root`. -//! //! Accessing fields of a DOM object //! ================================ //! //! All fields of DOM objects are private; accessing them from outside their //! module is done through explicit getter or setter methods. //! -//! However, `JSRef<T>` dereferences to `&T`, so fields can be accessed on a -//! `JSRef<T>` directly within the module that defines the struct. -//! //! Inheritance and casting //! ======================= //! @@ -147,14 +134,13 @@ //! to other types in the inheritance chain. For example: //! //! ```ignore -//! # use script::dom::bindings::js::JSRef; //! # use script::dom::bindings::codegen::InheritTypes::{NodeCast, HTMLElementCast}; //! # use script::dom::element::Element; //! # use script::dom::node::Node; //! # use script::dom::htmlelement::HTMLElement; -//! fn f(element: JSRef<Element>) { -//! let base: JSRef<Node> = NodeCast::from_ref(element); -//! let derived: Option<JSRef<HTMLElement>> = HTMLElementCast::to_ref(element); +//! fn f(element: &Element) { +//! let base: &Node = NodeCast::from_ref(element); +//! let derived: Option<&HTMLElement> = HTMLElementCast::to_ref(element); //! } //! ``` //! @@ -170,7 +156,7 @@ //! superclass or `Reflector` member, and other members as appropriate; //! * implementing the //! `dom::bindings::codegen::Bindings::FooBindings::FooMethods` trait for -//! `JSRef<Foo>`. +//! `&'a Foo`. //! //! More information is available in the [bindings module](bindings/index.html). //! diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 131889952bf..44e6422ff1e 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -8,8 +8,7 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, UIEventCast, MouseEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, RootedReference}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; @@ -57,17 +56,17 @@ impl MouseEvent { } } - pub fn new_uninitialized(window: JSRef<Window>) -> Temporary<MouseEvent> { + pub fn new_uninitialized(window: &Window) -> Root<MouseEvent> { reflect_dom_object(box MouseEvent::new_inherited(), GlobalRef::Window(window), MouseEventBinding::Wrap) } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, type_: DOMString, canBubble: EventBubbles, cancelable: EventCancelable, - view: Option<JSRef<Window>>, + view: Option<&Window>, detail: i32, screenX: i32, screenY: i32, @@ -78,19 +77,19 @@ impl MouseEvent { shiftKey: bool, metaKey: bool, button: i16, - relatedTarget: Option<JSRef<EventTarget>>) -> Temporary<MouseEvent> { - let ev = MouseEvent::new_uninitialized(window).root(); + relatedTarget: Option<&EventTarget>) -> Root<MouseEvent> { + let ev = MouseEvent::new_uninitialized(window); ev.r().InitMouseEvent(type_, canBubble == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable, view, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget); - Temporary::from_rooted(ev.r()) + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &MouseEventBinding::MouseEventInit) -> Fallible<Temporary<MouseEvent>> { + init: &MouseEventBinding::MouseEventInit) -> Fallible<Root<MouseEvent>> { let bubbles = if init.parent.parent.parent.bubbles { EventBubbles::Bubbles } else { @@ -99,7 +98,7 @@ impl MouseEvent { let cancelable = if init.parent.parent.parent.cancelable { EventCancelable::Cancelable } else { - EventCancelable::NotCancelable + EventCancelable::NotCancelable }; let event = MouseEvent::new(global.as_window(), type_, bubbles, @@ -114,7 +113,7 @@ impl MouseEvent { } } -impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { +impl<'a> MouseEventMethods for &'a MouseEvent { fn ScreenX(self) -> i32 { self.screen_x.get() } @@ -151,15 +150,15 @@ impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { self.button.get() } - fn GetRelatedTarget(self) -> Option<Temporary<EventTarget>> { - self.related_target.get().map(Temporary::from_rooted) + fn GetRelatedTarget(self) -> Option<Root<EventTarget>> { + self.related_target.get().map(Root::from_rooted) } fn InitMouseEvent(self, typeArg: DOMString, canBubbleArg: bool, cancelableArg: bool, - viewArg: Option<JSRef<Window>>, + viewArg: Option<&Window>, detailArg: i32, screenXArg: i32, screenYArg: i32, @@ -170,13 +169,13 @@ impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { shiftKeyArg: bool, metaKeyArg: bool, buttonArg: i16, - relatedTargetArg: Option<JSRef<EventTarget>>) { - let event: JSRef<Event> = EventCast::from_ref(self); + relatedTargetArg: Option<&EventTarget>) { + let event: &Event = EventCast::from_ref(self); if event.dispatching() { return; } - let uievent: JSRef<UIEvent> = UIEventCast::from_ref(self); + let uievent: &UIEvent = UIEventCast::from_ref(self); uievent.InitUIEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg); self.screen_x.set(screenXArg); self.screen_y.set(screenYArg); @@ -187,7 +186,7 @@ impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { self.shift_key.set(shiftKeyArg); self.meta_key.set(metaKeyArg); self.button.set(buttonArg); - self.related_target.set(relatedTargetArg.map(JS::from_rooted)); + self.related_target.set(relatedTargetArg.map(JS::from_ref)); } } diff --git a/components/script/dom/namednodemap.rs b/components/script/dom/namednodemap.rs index 75ea2bcfeb3..b3bff47525d 100644 --- a/components/script/dom/namednodemap.rs +++ b/components/script/dom/namednodemap.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::element::{AttributeHandlers, Element, ElementHelpers}; use dom::window::Window; @@ -23,20 +23,20 @@ pub struct NamedNodeMap { } impl NamedNodeMap { - fn new_inherited(elem: JSRef<Element>) -> NamedNodeMap { + fn new_inherited(elem: &Element) -> NamedNodeMap { NamedNodeMap { reflector_: Reflector::new(), - owner: JS::from_rooted(elem), + owner: JS::from_ref(elem), } } - pub fn new(window: JSRef<Window>, elem: JSRef<Element>) -> Temporary<NamedNodeMap> { + pub fn new(window: &Window, elem: &Element) -> Root<NamedNodeMap> { reflect_dom_object(box NamedNodeMap::new_inherited(elem), GlobalRef::Window(window), NamedNodeMapBinding::Wrap) } } -impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { +impl<'a> NamedNodeMapMethods for &'a NamedNodeMap { // https://dom.spec.whatwg.org/#dom-namednodemap-length fn Length(self) -> u32 { let owner = self.owner.root(); @@ -47,16 +47,16 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { } // https://dom.spec.whatwg.org/#dom-namednodemap-item - fn Item(self, index: u32) -> Option<Temporary<Attr>> { + fn Item(self, index: u32) -> Option<Root<Attr>> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); let attrs = owner.attrs(); - attrs.get(index as usize).map(|x| Temporary::from_rooted(x.clone())) + attrs.get(index as usize).map(|t| t.root()) } // https://dom.spec.whatwg.org/#dom-namednodemap-getnameditem - fn GetNamedItem(self, name: DOMString) -> Option<Temporary<Attr>> { + fn GetNamedItem(self, name: DOMString) -> Option<Root<Attr>> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); @@ -65,7 +65,7 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { // https://dom.spec.whatwg.org/#dom-namednodemap-getnameditemns fn GetNamedItemNS(self, namespace: Option<DOMString>, local_name: DOMString) - -> Option<Temporary<Attr>> { + -> Option<Root<Attr>> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); @@ -74,7 +74,7 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { } // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem - fn RemoveNamedItem(self, name: DOMString) -> Fallible<Temporary<Attr>> { + fn RemoveNamedItem(self, name: DOMString) -> Fallible<Root<Attr>> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); @@ -84,7 +84,7 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { // https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns fn RemoveNamedItemNS(self, namespace: Option<DOMString>, local_name: DOMString) - -> Fallible<Temporary<Attr>> { + -> Fallible<Root<Attr>> { let owner = self.owner.root(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let owner = owner.r(); @@ -92,13 +92,13 @@ impl<'a> NamedNodeMapMethods for JSRef<'a, NamedNodeMap> { owner.remove_attribute(&ns, &Atom::from_slice(&local_name)).ok_or(Error::NotFound) } - fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Attr>> { + fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Attr>> { let item = self.Item(index); *found = item.is_some(); item } - fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Temporary<Attr>> { + fn NamedGetter(self, name: DOMString, found: &mut bool) -> Option<Root<Attr>> { let item = self.GetNamedItem(name); *found = item.is_some(); item diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 0b96e355a2f..1fa30b66b04 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::NavigatorBinding; use dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::navigatorinfo; use dom::window::Window; @@ -23,14 +23,14 @@ impl Navigator { } } - pub fn new(window: JSRef<Window>) -> Temporary<Navigator> { + pub fn new(window: &Window) -> Root<Navigator> { reflect_dom_object(box Navigator::new_inherited(), GlobalRef::Window(window), NavigatorBinding::Wrap) } } -impl<'a> NavigatorMethods for JSRef<'a, Navigator> { +impl<'a> NavigatorMethods for &'a Navigator { fn Product(self) -> DOMString { navigatorinfo::Product() } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index d971028fcec..4393e6ddc09 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -15,20 +15,19 @@ use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods}; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods; -use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentCast, DocumentTypeCast}; +use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentCast, DocumentDerived, DocumentTypeCast}; use dom::bindings::codegen::InheritTypes::{ElementCast, NodeCast, ElementDerived, EventTargetCast}; use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLFieldSetElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLOptGroupElementDerived, NodeBase, NodeDerived}; -use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast}; +use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast, TextDerived}; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::conversions; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, LayoutJS, MutNullableHeap}; -use dom::bindings::js::{OptionalRootable, ResultRootable, Root, Rootable}; -use dom::bindings::js::{RootedReference, Temporary, TemporaryPushable}; -use dom::bindings::js::Unrooted; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; +use dom::bindings::js::Root; +use dom::bindings::js::RootedReference; use dom::bindings::trace::JSTraceable; use dom::bindings::trace::RootedVec; use dom::bindings::utils::{Reflectable, reflect_dom_object}; @@ -61,7 +60,6 @@ use style::properties::ComputedValues; use style; use js::jsapi::{JSContext, JSObject, JSRuntime}; -use js::jsfriendapi; use core::nonzero::NonZero; use libc; use libc::{uintptr_t, c_void}; @@ -120,6 +118,12 @@ pub struct Node { unique_id: DOMRefCell<String>, } +impl PartialEq for Node { + fn eq(&self, other: &Node) -> bool { + self as *const Node == &*other + } +} + impl NodeDerived for EventTarget { fn is_node(&self) -> bool { match *self.type_id() { @@ -284,23 +288,22 @@ pub enum NodeTypeId { trait PrivateNodeHelpers { fn node_inserted(self); fn node_removed(self, parent_in_doc: bool); - fn add_child(self, new_child: JSRef<Node>, before: Option<JSRef<Node>>); - fn remove_child(self, child: JSRef<Node>); + fn add_child(self, new_child: &Node, before: Option<&Node>); + fn remove_child(self, child: &Node); } -impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { +impl<'a> PrivateNodeHelpers for &'a Node { // https://dom.spec.whatwg.org/#node-is-inserted fn node_inserted(self) { assert!(self.parent_node.get().is_some()); - let document = document_from_node(self).root(); + let document = document_from_node(self); let is_in_doc = self.is_in_doc(); for node in self.traverse_preorder() { - let node = node.root(); vtable_for(&node.r()).bind_to_tree(is_in_doc); } - let parent = self.parent_node.get().root(); + let parent = self.parent_node.get().map(Root::from_rooted); parent.r().map(|parent| vtable_for(&parent).child_inserted(self)); document.r().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage); } @@ -309,7 +312,6 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { fn node_removed(self, parent_in_doc: bool) { assert!(self.parent_node.get().is_none()); for node in self.traverse_preorder() { - let node = node.root(); node.r().set_flag(IS_IN_DOC, false); vtable_for(&node.r()).unbind_from_tree(parent_in_doc); } @@ -323,64 +325,66 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, 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(self, new_child: JSRef<Node>, before: Option<JSRef<Node>>) { + fn add_child(self, new_child: &Node, before: Option<&Node>) { assert!(new_child.parent_node.get().is_none()); assert!(new_child.prev_sibling.get().is_none()); assert!(new_child.next_sibling.get().is_none()); match before { Some(ref before) => { - assert!(before.parent_node.get().root().r() == Some(self)); - match before.prev_sibling.get().root() { + assert!(before.parent_node.get().map(Root::from_rooted).r() == Some(self)); + match before.prev_sibling.get() { None => { - assert!(Some(*before) == self.first_child.get().root().r()); - self.first_child.set(Some(JS::from_rooted(new_child))); + assert!(Some(*before) == self.first_child.get().map(Root::from_rooted).r()); + self.first_child.set(Some(JS::from_ref(new_child))); }, Some(ref prev_sibling) => { - prev_sibling.r().next_sibling.set(Some(JS::from_rooted(new_child))); - new_child.prev_sibling.set(Some(JS::from_rooted(prev_sibling.r()))); + let prev_sibling = prev_sibling.root(); + prev_sibling.r().next_sibling.set(Some(JS::from_ref(new_child))); + new_child.prev_sibling.set(Some(JS::from_ref(prev_sibling.r()))); }, } - before.prev_sibling.set(Some(JS::from_rooted(new_child))); - new_child.next_sibling.set(Some(JS::from_rooted(*before))); + before.prev_sibling.set(Some(JS::from_ref(new_child))); + new_child.next_sibling.set(Some(JS::from_ref(before))); }, None => { - match self.last_child.get().root() { - None => self.first_child.set(Some(JS::from_rooted(new_child))), + match self.last_child.get() { + None => self.first_child.set(Some(JS::from_ref(new_child))), Some(ref last_child) => { + let last_child = last_child.root(); assert!(last_child.r().next_sibling.get().is_none()); - last_child.r().next_sibling.set(Some(JS::from_rooted(new_child))); - new_child.prev_sibling.set(Some(JS::from_rooted(last_child.r()))); + last_child.r().next_sibling.set(Some(JS::from_ref(new_child))); + new_child.prev_sibling.set(Some(JS::from_rooted(&last_child))); } } - self.last_child.set(Some(JS::from_rooted(new_child))); + self.last_child.set(Some(JS::from_ref(new_child))); }, } - new_child.parent_node.set(Some(JS::from_rooted(self))); + new_child.parent_node.set(Some(JS::from_ref(self))); } /// Removes the given child from this node's list of children. /// /// Fails unless `child` is a child of this node. - fn remove_child(self, child: JSRef<Node>) { - assert!(child.parent_node.get().root().r() == Some(self)); + fn remove_child(self, child: &Node) { + assert!(child.parent_node.get().map(Root::from_rooted).r() == Some(self)); - match child.prev_sibling.get().root() { + match child.prev_sibling.get() { None => { self.first_child.set(child.next_sibling.get()); } Some(ref prev_sibling) => { - prev_sibling.r().next_sibling.set(child.next_sibling.get()); + prev_sibling.root().r().next_sibling.set(child.next_sibling.get()); } } - match child.next_sibling.get().root() { + match child.next_sibling.get() { None => { self.last_child.set(child.prev_sibling.get()); } Some(ref next_sibling) => { - next_sibling.r().prev_sibling.set(child.prev_sibling.get()); + next_sibling.root().r().prev_sibling.set(child.prev_sibling.get()); } } @@ -407,14 +411,13 @@ impl<'a> QuerySelectorIterator { } impl<'a> Iterator for QuerySelectorIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let selectors = &self.selectors; // TODO(cgaebel): Is it worth it to build a bloom filter here // (instead of passing `None`)? Probably. self.iterator.find(|node| { - let node = node.root(); node.r().is_element() && matches(selectors, &node.r(), &mut None) }) } @@ -428,25 +431,22 @@ pub trait NodeHelpers { fn child_elements(self) -> ChildElementIterator; fn following_siblings(self) -> NodeSiblingIterator; fn preceding_siblings(self) -> ReverseSiblingIterator; - fn following_nodes(self, root: JSRef<Node>) -> FollowingNodeIterator; - fn preceding_nodes(self, root: JSRef<Node>) -> PrecedingNodeIterator; + fn following_nodes(self, root: &Node) -> FollowingNodeIterator; + fn preceding_nodes(self, root: &Node) -> PrecedingNodeIterator; fn descending_last_children(self) -> LastChildIterator; fn is_in_doc(self) -> bool; - fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool; - fn is_parent_of(self, child: JSRef<Node>) -> bool; + fn is_inclusive_ancestor_of(self, parent: &Node) -> bool; + fn is_parent_of(self, child: &Node) -> bool; fn type_id(self) -> NodeTypeId; fn len(self) -> u32; fn index(self) -> u32; - fn owner_doc(self) -> Temporary<Document>; - fn set_owner_doc(self, document: JSRef<Document>); + fn owner_doc(self) -> Root<Document>; + fn set_owner_doc(self, document: &Document); fn is_in_html_doc(self) -> bool; - fn is_element(self) -> bool; - fn is_document(self) -> bool; fn is_doctype(self) -> bool; - fn is_text(self) -> bool; fn is_anchor_element(self) -> bool; fn get_flag(self, flag: NodeFlags) -> bool; @@ -511,10 +511,10 @@ pub trait NodeHelpers { fn prepend(self, nodes: Vec<NodeOrString>) -> ErrorResult; fn append(self, nodes: Vec<NodeOrString>) -> ErrorResult; - fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>>; + fn query_selector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>>; #[allow(unsafe_code)] unsafe fn query_selector_iter(self, selectors: DOMString) -> Fallible<QuerySelectorIterator>; - fn query_selector_all(self, selectors: DOMString) -> Fallible<Temporary<NodeList>>; + fn query_selector_all(self, selectors: DOMString) -> Fallible<Root<NodeList>>; fn remove_self(self); @@ -523,15 +523,14 @@ pub trait NodeHelpers { fn teardown(self); - fn parse_fragment(self, markup: DOMString) -> Fallible<Temporary<DocumentFragment>>; + fn parse_fragment(self, markup: DOMString) -> Fallible<Root<DocumentFragment>>; } -impl<'a> NodeHelpers for JSRef<'a, Node> { +impl<'a> NodeHelpers for &'a Node { fn teardown(self) { self.layout_data.dispose(); for kid in self.children() { - let kid = kid.root(); kid.r().teardown(); } } @@ -553,7 +552,6 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // FIXME: this should have a pure version? for kid in self.children() { - let kid = kid.root(); kid.r().dump_indent(indent + 1) } } @@ -589,19 +587,6 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } #[inline] - fn is_element(self) -> bool { - match self.type_id { - NodeTypeId::Element(..) => true, - _ => false - } - } - - #[inline] - fn is_document(self) -> bool { - self.type_id == NodeTypeId::Document - } - - #[inline] fn is_anchor_element(self) -> bool { self.type_id == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) } @@ -611,11 +596,6 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { self.type_id == NodeTypeId::DocumentType } - #[inline] - fn is_text(self) -> bool { - self.type_id == NodeTypeId::CharacterData(CharacterDataTypeId::Text) - } - fn get_flag(self, flag: NodeFlags) -> bool { self.flags.get().contains(flag) } @@ -718,14 +698,13 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } // 2. Dirty descendants. - fn dirty_subtree(node: JSRef<Node>) { + fn dirty_subtree(node: &Node) { // Stop if this subtree is already dirty. if node.get_is_dirty() { return } node.set_flag(IS_DIRTY | HAS_DIRTY_SIBLINGS | HAS_DIRTY_DESCENDANTS, true); for kid in node.children() { - let kid = kid.root(); dirty_subtree(kid.r()); } } @@ -744,14 +723,12 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { }.root(); for sibling in parent.r().children() { - let sibling = sibling.root(); sibling.r().set_has_dirty_siblings(true); } } // 4. Dirty ancestors. for ancestor in self.ancestors() { - let ancestor = ancestor.root(); if !force_ancestors && ancestor.r().get_has_dirty_descendants() { break } ancestor.r().set_has_dirty_descendants(true); } @@ -764,18 +741,18 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { fn inclusively_following_siblings(self) -> NodeSiblingIterator { NodeSiblingIterator { - current: Some(Temporary::from_rooted(self)), + current: Some(Root::from_ref(self)), } } fn inclusively_preceding_siblings(self) -> ReverseSiblingIterator { ReverseSiblingIterator { - current: Some(Temporary::from_rooted(self)), + current: Some(Root::from_ref(self)), } } - fn is_inclusive_ancestor_of(self, parent: JSRef<Node>) -> bool { - self == parent || parent.ancestors().any(|ancestor| ancestor.root().r() == self) + fn is_inclusive_ancestor_of(self, parent: &Node) -> bool { + self == parent || parent.ancestors().any(|ancestor| ancestor.r() == self) } fn following_siblings(self) -> NodeSiblingIterator { @@ -790,17 +767,17 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } } - fn following_nodes(self, root: JSRef<Node>) -> FollowingNodeIterator { + fn following_nodes(self, root: &Node) -> FollowingNodeIterator { FollowingNodeIterator { - current: Some(Temporary::from_rooted(self)), - root: Temporary::from_rooted(root), + current: Some(Root::from_ref(self)), + root: Root::from_ref(root), } } - fn preceding_nodes(self, root: JSRef<Node>) -> PrecedingNodeIterator { + fn preceding_nodes(self, root: &Node) -> PrecedingNodeIterator { PrecedingNodeIterator { - current: Some(Temporary::from_rooted(self)), - root: Temporary::from_rooted(root), + current: Some(Root::from_ref(self)), + root: Root::from_ref(root), } } @@ -810,9 +787,9 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } } - fn is_parent_of(self, child: JSRef<Node>) -> bool { - match child.parent_node.get().root() { - Some(ref parent) => parent.r() == self, + fn is_parent_of(self, child: &Node) -> bool { + match child.parent_node.get() { + Some(ref parent) => parent.root().r() == self, None => false, } } @@ -822,26 +799,26 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } fn get_bounding_content_box(self) -> Rect<Au> { - window_from_node(self).root().r().content_box_query(self.to_trusted_node_address()) + window_from_node(self).r().content_box_query(self.to_trusted_node_address()) } fn get_content_boxes(self) -> Vec<Rect<Au>> { - window_from_node(self).root().r().content_boxes_query(self.to_trusted_node_address()) + window_from_node(self).r().content_boxes_query(self.to_trusted_node_address()) } // https://dom.spec.whatwg.org/#dom-childnode-before fn before(self, nodes: Vec<NodeOrString>) -> ErrorResult { - match self.parent_node.get().root() { + match self.parent_node.get() { None => { // Step 1. Ok(()) }, Some(ref parent_node) => { // Step 2. - let doc = self.owner_doc().root(); - let node = try!(doc.r().node_from_nodes_and_strings(nodes)).root(); + let doc = self.owner_doc(); + let node = try!(doc.r().node_from_nodes_and_strings(nodes)); // Step 3. - Node::pre_insert(node.r(), parent_node.r(), + Node::pre_insert(node.r(), parent_node.root().r(), Some(self)).map(|_| ()) }, } @@ -849,19 +826,19 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // https://dom.spec.whatwg.org/#dom-childnode-after fn after(self, nodes: Vec<NodeOrString>) -> ErrorResult { - match self.parent_node.get().root() { + match self.parent_node.get() { None => { // Step 1. Ok(()) }, Some(ref parent_node) => { // Step 2. - let doc = self.owner_doc().root(); - let node = try!(doc.r().node_from_nodes_and_strings(nodes)).root(); + let doc = self.owner_doc(); + let node = try!(doc.r().node_from_nodes_and_strings(nodes)); // Step 3. // FIXME(https://github.com/servo/servo/issues/5720) - let next_sibling = self.next_sibling.get().root(); - Node::pre_insert(node.r(), parent_node.r(), + let next_sibling = self.next_sibling.get().map(Root::from_rooted); + Node::pre_insert(node.r(), parent_node.root().r(), next_sibling.r()).map(|_| ()) }, } @@ -869,17 +846,17 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // https://dom.spec.whatwg.org/#dom-childnode-replacewith fn replace_with(self, nodes: Vec<NodeOrString>) -> ErrorResult { - match self.parent_node.get().root() { + match self.parent_node.get() { None => { // Step 1. Ok(()) }, Some(ref parent_node) => { // Step 2. - let doc = self.owner_doc().root(); - let node = try!(doc.r().node_from_nodes_and_strings(nodes)).root(); + let doc = self.owner_doc(); + let node = try!(doc.r().node_from_nodes_and_strings(nodes)); // Step 3. - parent_node.r().ReplaceChild(node.r(), self).map(|_| ()) + parent_node.root().r().ReplaceChild(node.r(), self).map(|_| ()) }, } } @@ -887,34 +864,34 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // https://dom.spec.whatwg.org/#dom-parentnode-prepend fn prepend(self, nodes: Vec<NodeOrString>) -> ErrorResult { // Step 1. - let doc = self.owner_doc().root(); - let node = try!(doc.r().node_from_nodes_and_strings(nodes)).root(); + let doc = self.owner_doc(); + let node = try!(doc.r().node_from_nodes_and_strings(nodes)); // Step 2. - let first_child = self.first_child.get().root(); + let first_child = self.first_child.get().map(Root::from_rooted); Node::pre_insert(node.r(), self, first_child.r()).map(|_| ()) } // https://dom.spec.whatwg.org/#dom-parentnode-append fn append(self, nodes: Vec<NodeOrString>) -> ErrorResult { // Step 1. - let doc = self.owner_doc().root(); - let node = try!(doc.r().node_from_nodes_and_strings(nodes)).root(); + let doc = self.owner_doc(); + let node = try!(doc.r().node_from_nodes_and_strings(nodes)); // Step 2. self.AppendChild(node.r()).map(|_| ()) } // https://dom.spec.whatwg.org/#dom-parentnode-queryselector - fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> { + fn query_selector(self, selectors: DOMString) -> Fallible<Option<Root<Element>>> { // Step 1. match parse_author_origin_selector_list_from_str(&selectors) { // Step 2. Err(()) => return Err(Syntax), // Step 3. Ok(ref selectors) => { - let root = self.ancestors().last().root(); + let root = self.ancestors().last(); let root = root.r().unwrap_or(self.clone()); - Ok(root.traverse_preorder().filter_map(ElementCast::to_temporary).find(|element| { - matches(selectors, &NodeCast::from_ref(element.root().r()), &mut None) + Ok(root.traverse_preorder().filter_map(ElementCast::to_root).find(|element| { + matches(selectors, &NodeCast::from_ref(element.r()), &mut None) })) } } @@ -932,7 +909,7 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { Err(()) => Err(Syntax), // Step 3. Ok(selectors) => { - let root = self.ancestors().last().root(); + let root = self.ancestors().last(); let root = root.r().unwrap_or(self); Ok(QuerySelectorIterator::new(root.traverse_preorder(), selectors)) } @@ -941,8 +918,8 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // https://dom.spec.whatwg.org/#dom-parentnode-queryselectorall #[allow(unsafe_code)] - fn query_selector_all(self, selectors: DOMString) -> Fallible<Temporary<NodeList>> { - let window = window_from_node(self).root(); + fn query_selector_all(self, selectors: DOMString) -> Fallible<Root<NodeList>> { + let window = window_from_node(self); let iter = try!(unsafe { self.query_selector_iter(selectors) }); Ok(NodeList::new_simple_list(window.r(), iter)) } @@ -955,20 +932,20 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { fn inclusive_ancestors(self) -> AncestorIterator { AncestorIterator { - current: Some(Temporary::from_rooted(self)) + current: Some(Root::from_ref(self)) } } - fn owner_doc(self) -> Temporary<Document> { - Temporary::from_rooted(self.owner_doc.get().unwrap()) + fn owner_doc(self) -> Root<Document> { + self.owner_doc.get().unwrap().root() } - fn set_owner_doc(self, document: JSRef<Document>) { - self.owner_doc.set(Some(JS::from_rooted(document))); + fn set_owner_doc(self, document: &Document) { + self.owner_doc.set(Some(JS::from_ref(document))); } fn is_in_html_doc(self) -> bool { - self.owner_doc().root().r().is_html_document() + self.owner_doc().r().is_html_document() } fn children(self) -> NodeSiblingIterator { @@ -984,8 +961,8 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } fn child_elements(self) -> ChildElementIterator { - fn to_temporary(node: Temporary<Node>) -> Option<Temporary<Element>> { - ElementCast::to_temporary(node) + fn to_temporary(node: Root<Node>) -> Option<Root<Element>> { + ElementCast::to_root(node) } self.children() .filter_map(to_temporary as fn(_) -> _) @@ -993,8 +970,8 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } fn remove_self(self) { - match self.parent_node.get().root() { - Some(ref parent) => parent.r().remove_child(self), + match self.parent_node.get() { + Some(parent) => parent.root().r().remove_child(self), None => () } } @@ -1013,11 +990,11 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { NodeInfo { uniqueId: self.get_unique_id(), baseURI: self.GetBaseURI().unwrap_or("".to_owned()), - parent: self.GetParentNode().root().map(|node| node.r().get_unique_id()).unwrap_or("".to_owned()), + parent: self.GetParentNode().map(|node| node.r().get_unique_id()).unwrap_or("".to_owned()), nodeType: self.NodeType(), namespaceURI: "".to_owned(), //FIXME nodeName: self.NodeName(), - numChildren: self.ChildNodes().root().r().Length() as usize, + numChildren: self.ChildNodes().r().Length() as usize, //FIXME doctype nodes only name: "".to_owned(), @@ -1025,7 +1002,7 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { systemId: "".to_owned(), attrs: { - let e: Option<JSRef<Element>> = ElementCast::to_ref(self); + let e: Option<&Element> = ElementCast::to_ref(self); match e { Some(element) => element.summarize(), None => vec!(), @@ -1033,10 +1010,10 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { }, isDocumentElement: - self.owner_doc().root() + self.owner_doc() .r() .GetDocumentElement() - .map(|elem| NodeCast::from_ref(elem.root().r()) == self) + .map(|elem| NodeCast::from_ref(elem.r()) == self) .unwrap_or(false), shortValue: self.GetNodeValue().unwrap_or("".to_owned()), //FIXME: truncate @@ -1045,9 +1022,9 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#dfn-concept-parse-fragment - fn parse_fragment(self, markup: DOMString) -> Fallible<Temporary<DocumentFragment>> { - let context_node: JSRef<Node> = NodeCast::from_ref(self); - let context_document = document_from_node(self).root(); + fn parse_fragment(self, markup: DOMString) -> Fallible<Root<DocumentFragment>> { + let context_node: &Node = NodeCast::from_ref(self); + let context_document = document_from_node(self); let mut new_children: RootedVec<JS<Node>> = RootedVec::new(); if context_document.r().is_html_document() { parse_html_fragment(context_node, markup, &mut new_children); @@ -1055,12 +1032,14 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { // FIXME: XML case unimplemented!(); } - let fragment = DocumentFragment::new(context_document.r()).root(); - let fragment_node: JSRef<Node> = NodeCast::from_ref(fragment.r()); - for node in new_children.iter() { - fragment_node.AppendChild(node.root().r()).unwrap(); + let fragment = DocumentFragment::new(context_document.r()); + { + let fragment_node = NodeCast::from_ref(fragment.r()); + for node in new_children.iter() { + fragment_node.AppendChild(node.root().r()).unwrap(); + } } - Ok(Temporary::from_rooted(fragment.r())) + Ok(fragment) } } @@ -1068,16 +1047,18 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { /// returns it. #[allow(unsafe_code)] pub fn from_untrusted_node_address(runtime: *mut JSRuntime, candidate: UntrustedNodeAddress) - -> Temporary<Node> { + -> Root<Node> { unsafe { + // https://github.com/servo/servo/issues/6383 let candidate: uintptr_t = mem::transmute(candidate.0); - let object: *mut JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, - candidate); +// let object: *mut JSObject = jsfriendapi::bindgen::JS_GetAddressableObject(runtime, +// candidate); + let object: *mut JSObject = mem::transmute(candidate); if object.is_null() { panic!("Attempted to create a `JS<Node>` from an invalid pointer!") } let boxed_node: *const Node = conversions::native_from_reflector(object); - Temporary::from_unrooted(Unrooted::from_raw(boxed_node)) + Root::from_ref(&*boxed_node) } } @@ -1102,9 +1083,9 @@ pub trait LayoutNodeHelpers { #[allow(unsafe_code)] unsafe fn is_element_for_layout(&self) -> bool; #[allow(unsafe_code)] - unsafe fn get_flag(self, flag: NodeFlags) -> bool; + unsafe fn get_flag(&self, flag: NodeFlags) -> bool; #[allow(unsafe_code)] - unsafe fn set_flag(self, flag: NodeFlags, value: bool); + unsafe fn set_flag(&self, flag: NodeFlags, value: bool); } impl LayoutNodeHelpers for LayoutJS<Node> { @@ -1158,13 +1139,13 @@ impl LayoutNodeHelpers for LayoutJS<Node> { #[inline] #[allow(unsafe_code)] - unsafe fn get_flag(self, flag: NodeFlags) -> bool { + unsafe fn get_flag(&self, flag: NodeFlags) -> bool { (*self.unsafe_get()).flags.get().contains(flag) } #[inline] #[allow(unsafe_code)] - unsafe fn set_flag(self, flag: NodeFlags, value: bool) { + unsafe fn set_flag(&self, flag: NodeFlags, value: bool) { let this = self.unsafe_get(); let mut flags = (*this).flags.get(); @@ -1224,61 +1205,60 @@ impl RawLayoutNodeHelpers for Node { pub type ChildElementIterator = Peekable<FilterMap<NodeSiblingIterator, - fn(Temporary<Node>) -> Option<Temporary<Element>>>>; + fn(Root<Node>) -> Option<Root<Element>>>>; pub struct NodeSiblingIterator { - current: Option<Temporary<Node>>, + current: Option<Root<Node>>, } impl Iterator for NodeSiblingIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, - }.root(); + }; self.current = current.r().GetNextSibling(); - Some(Temporary::from_rooted(current.r())) + Some(current) } } pub struct ReverseSiblingIterator { - current: Option<Temporary<Node>>, + current: Option<Root<Node>>, } impl Iterator for ReverseSiblingIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, - }.root(); + }; self.current = current.r().GetPreviousSibling(); - Some(Temporary::from_rooted(current.r())) + Some(current) } } pub struct FollowingNodeIterator { - current: Option<Temporary<Node>>, - root: Temporary<Node>, + current: Option<Root<Node>>, + root: Root<Node>, } impl Iterator for FollowingNodeIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; // https://dom.spec.whatwg.org/#concept-tree-following - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, }; - let node = current.root(); - if let Some(first_child) = node.r().GetFirstChild() { + if let Some(first_child) = current.r().GetFirstChild() { self.current = Some(first_child); - return node.r().GetFirstChild() + return current.r().GetFirstChild() } if self.root == current { @@ -1286,18 +1266,18 @@ impl Iterator for FollowingNodeIterator { return None; } - if let Some(next_sibling) = node.r().GetNextSibling() { + if let Some(next_sibling) = current.r().GetNextSibling() { self.current = Some(next_sibling); - return node.r().GetNextSibling() + return current.r().GetNextSibling() } - for ancestor in node.r().inclusive_ancestors() { + for ancestor in current.r().inclusive_ancestors() { if self.root == ancestor { break; } - if let Some(next_sibling) = ancestor.root().r().GetNextSibling() { + if let Some(next_sibling) = ancestor.r().GetNextSibling() { self.current = Some(next_sibling); - return ancestor.root().r().GetNextSibling() + return ancestor.r().GetNextSibling() } } self.current = None; @@ -1306,15 +1286,15 @@ impl Iterator for FollowingNodeIterator { } pub struct PrecedingNodeIterator { - current: Option<Temporary<Node>>, - root: Temporary<Node>, + current: Option<Root<Node>>, + root: Root<Node>, } impl Iterator for PrecedingNodeIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; // https://dom.spec.whatwg.org/#concept-tree-preceding - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, @@ -1325,16 +1305,16 @@ impl Iterator for PrecedingNodeIterator { return None } - let node = current.root(); + let node = current; if let Some(previous_sibling) = node.r().GetPreviousSibling() { if self.root == previous_sibling { self.current = None; return None } - if let Some(last_child) = previous_sibling.root().r().descending_last_children().last() { + if let Some(last_child) = previous_sibling.r().descending_last_children().last() { self.current = Some(last_child); - return previous_sibling.root().r().descending_last_children().last() + return previous_sibling.r().descending_last_children().last() } self.current = Some(previous_sibling); @@ -1352,73 +1332,72 @@ impl Iterator for PrecedingNodeIterator { } pub struct LastChildIterator { - current: Option<Temporary<Node>>, + current: Option<Root<Node>>, } impl Iterator for LastChildIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, - }.root(); + }; self.current = current.r().GetLastChild(); - Some(Temporary::from_rooted(current.r())) + Some(current) } } pub struct AncestorIterator { - current: Option<Temporary<Node>>, + current: Option<Root<Node>>, } impl Iterator for AncestorIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, - }.root(); + }; self.current = current.r().GetParentNode(); - Some(Temporary::from_rooted(current.r())) + Some(current) } } pub struct TreeIterator { - current: Option<Temporary<Node>>, + current: Option<Root<Node>>, depth: usize, } -impl<'a> TreeIterator { - fn new(root: JSRef<'a, Node>) -> TreeIterator { +impl TreeIterator { + fn new(root: &Node) -> TreeIterator { TreeIterator { - current: Some(Temporary::from_rooted(root)), + current: Some(Root::from_ref(root)), depth: 0, } } } impl Iterator for TreeIterator { - type Item = Temporary<Node>; + type Item = Root<Node>; // https://dom.spec.whatwg.org/#concept-tree-order - fn next(&mut self) -> Option<Temporary<Node>> { + fn next(&mut self) -> Option<Root<Node>> { let current = match self.current.take() { None => return None, Some(current) => current, }; - let node = current.root(); - if let Some(first_child) = node.r().GetFirstChild() { + if let Some(first_child) = current.r().GetFirstChild() { self.current = Some(first_child); self.depth += 1; return Some(current); }; - for ancestor in node.r().inclusive_ancestors() { + for ancestor in current.r().inclusive_ancestors() { if self.depth == 0 { break; } - if let Some(next_sibling) = ancestor.root().r().GetNextSibling() { + if let Some(next_sibling) = ancestor.r().GetNextSibling() { self.current = Some(next_sibling); return Some(current); } @@ -1442,14 +1421,14 @@ fn as_uintptr<T>(t: &T) -> uintptr_t { t as *const T as uintptr_t } impl Node { pub fn reflect_node<N: Reflectable+NodeBase> (node: Box<N>, - document: JSRef<Document>, - wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<N>) -> Temporary<N>) - -> Temporary<N> { - let window = document.window().root(); + document: &Document, + wrap_fn: extern "Rust" fn(*mut JSContext, GlobalRef, Box<N>) -> Root<N>) + -> Root<N> { + let window = document.window(); reflect_dom_object(node, GlobalRef::Window(window.r()), wrap_fn) } - pub fn new_inherited(type_id: NodeTypeId, doc: JSRef<Document>) -> Node { + pub fn new_inherited(type_id: NodeTypeId, doc: &Document) -> Node { Node::new_(type_id, Some(doc.clone())) } @@ -1457,7 +1436,7 @@ impl Node { Node::new_(type_id, None) } - fn new_(type_id: NodeTypeId, doc: Option<JSRef<Document>>) -> Node { + fn new_(type_id: NodeTypeId, doc: Option<&Document>) -> Node { Node { eventtarget: EventTarget::new_inherited(EventTargetTypeId::Node(type_id)), type_id: type_id, @@ -1467,7 +1446,7 @@ impl Node { last_child: Default::default(), next_sibling: Default::default(), prev_sibling: Default::default(), - owner_doc: MutNullableHeap::new(doc.map(JS::from_rooted)), + owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)), child_list: Default::default(), flags: Cell::new(NodeFlags::new(type_id)), @@ -1494,20 +1473,20 @@ impl Node { } // https://dom.spec.whatwg.org/#concept-node-adopt - pub fn adopt(node: JSRef<Node>, document: JSRef<Document>) { + pub fn adopt(node: &Node, document: &Document) { // Step 1. - match node.parent_node.get().root() { + match node.parent_node.get() { Some(ref parent) => { - Node::remove(node, parent.r(), SuppressObserver::Unsuppressed); + Node::remove(node, parent.root().r(), SuppressObserver::Unsuppressed); } None => (), } // Step 2. - let node_doc = document_from_node(node).root(); + let node_doc = document_from_node(node); if node_doc.r() != document { for descendant in node.traverse_preorder() { - descendant.root().r().set_owner_doc(document); + descendant.r().set_owner_doc(document); } } @@ -1516,8 +1495,8 @@ impl Node { } // https://dom.spec.whatwg.org/#concept-node-pre-insert - fn pre_insert(node: JSRef<Node>, parent: JSRef<Node>, child: Option<JSRef<Node>>) - -> Fallible<Temporary<Node>> { + fn pre_insert(node: &Node, parent: &Node, child: Option<&Node>) + -> Fallible<Root<Node>> { // Step 1. match parent.type_id() { NodeTypeId::Document | @@ -1565,7 +1544,6 @@ impl Node { NodeTypeId::DocumentFragment => { // Step 6.1.1(b) if node.children() - .map(|c| c.root()) .any(|c| c.r().is_text()) { return Err(HierarchyRequest); @@ -1579,7 +1557,6 @@ impl Node { } if let Some(child) = child { if child.inclusively_following_siblings() - .map(|c| c.root()) .any(|child| child.r().is_doctype()) { return Err(HierarchyRequest); } @@ -1596,7 +1573,6 @@ impl Node { } if let Some(ref child) = child { if child.inclusively_following_siblings() - .map(|c| c.root()) .any(|child| child.r().is_doctype()) { return Err(HierarchyRequest); } @@ -1605,7 +1581,6 @@ impl Node { // Step 6.3 NodeTypeId::DocumentType => { if parent.children() - .map(|c| c.root()) .any(|c| c.r().is_doctype()) { return Err(HierarchyRequest); @@ -1613,7 +1588,6 @@ impl Node { match child { Some(child) => { if parent.children() - .map(|c| c.root()) .take_while(|c| c.r() != child) .any(|c| c.r().is_element()) { @@ -1638,30 +1612,29 @@ impl Node { let reference_child = match child { Some(child) if child == node => node.GetNextSibling(), _ => None - }.root(); + }; let reference_child = reference_child.r().or(child); // Step 9. - let document = document_from_node(parent).root(); + let document = document_from_node(parent); Node::adopt(node, document.r()); // Step 10. Node::insert(node, parent, reference_child, SuppressObserver::Unsuppressed); // Step 11. - return Ok(Temporary::from_rooted(node)) + return Ok(Root::from_ref(node)) } // https://dom.spec.whatwg.org/#concept-node-insert - fn insert(node: JSRef<Node>, - parent: JSRef<Node>, - child: Option<JSRef<Node>>, + fn insert(node: &Node, + parent: &Node, + child: Option<&Node>, suppress_observers: SuppressObserver) { - fn do_insert(node: JSRef<Node>, parent: JSRef<Node>, child: Option<JSRef<Node>>) { + fn do_insert(node: &Node, parent: &Node, child: Option<&Node>) { parent.add_child(node, child); let is_in_doc = parent.is_in_doc(); for kid in node.traverse_preorder() { - let kid = kid.root(); let mut flags = kid.r().flags.get(); if is_in_doc { flags.insert(IS_IN_DOC); @@ -1672,7 +1645,7 @@ impl Node { } } - fn fire_observer_if_necessary(node: JSRef<Node>, suppress_observers: SuppressObserver) { + fn fire_observer_if_necessary(node: &Node, suppress_observers: SuppressObserver) { match suppress_observers { SuppressObserver::Unsuppressed => node.node_inserted(), SuppressObserver::Suppressed => () @@ -1687,22 +1660,18 @@ impl Node { // Step 4. // Step 5: DocumentFragment, mutation records. // Step 6: DocumentFragment. - let mut kids = Vec::new(); - for kid in node.children() { - let kid = kid.root(); - kids.push(Temporary::from_rooted(kid.r())); + let kids: Vec<Root<Node>> = node.children().collect(); + for kid in &kids { Node::remove(kid.r(), node, SuppressObserver::Suppressed); } // Step 7: mutation records. // Step 8. - for kid in kids.clone().into_iter() { - let kid = kid.root(); + for kid in &kids { do_insert(kid.r(), parent, child); } - for kid in kids.into_iter() { - let kid = kid.root(); + for kid in kids { fire_observer_if_necessary(kid.r(), suppress_observers); } } @@ -1720,11 +1689,11 @@ impl Node { } // https://dom.spec.whatwg.org/#concept-node-replace-all - pub fn replace_all(node: Option<JSRef<Node>>, parent: JSRef<Node>) { + pub fn replace_all(node: Option<&Node>, parent: &Node) { // Step 1. match node { Some(node) => { - let document = document_from_node(parent).root(); + let document = document_from_node(parent); Node::adopt(node, document.r()); } None => (), @@ -1733,7 +1702,7 @@ impl Node { // Step 2. let mut removed_nodes: RootedVec<JS<Node>> = RootedVec::new(); for child in parent.children() { - removed_nodes.push(JS::from_rooted(child)); + removed_nodes.push(JS::from_rooted(&child)); } // Step 3. @@ -1741,13 +1710,12 @@ impl Node { None => vec!(), Some(node) => match node.type_id() { NodeTypeId::DocumentFragment => node.children().collect(), - _ => vec!(Temporary::from_rooted(node)), + _ => vec!(Root::from_ref(node)), }, }; // Step 4. for child in parent.children() { - let child = child.root(); Node::remove(child.r(), parent, SuppressObserver::Suppressed); } @@ -1762,20 +1730,18 @@ impl Node { // Step 7. let parent_in_doc = parent.is_in_doc(); for removed_node in removed_nodes.iter() { - let removed_node = removed_node.root(); - removed_node.r().node_removed(parent_in_doc); + removed_node.root().r().node_removed(parent_in_doc); } for added_node in added_nodes { - let added_node = added_node.root(); added_node.r().node_inserted(); } } // https://dom.spec.whatwg.org/#concept-node-pre-remove - fn pre_remove(child: JSRef<Node>, parent: JSRef<Node>) -> Fallible<Temporary<Node>> { + fn pre_remove(child: &Node, parent: &Node) -> Fallible<Root<Node>> { // Step 1. match child.GetParentNode() { - Some(ref node) if node != &Temporary::from_rooted(parent) => return Err(NotFound), + Some(ref node) if node.r() != parent => return Err(NotFound), None => return Err(NotFound), _ => () } @@ -1784,12 +1750,12 @@ impl Node { Node::remove(child, parent, SuppressObserver::Unsuppressed); // Step 3. - Ok(Temporary::from_rooted(child)) + Ok(Root::from_ref(child)) } // https://dom.spec.whatwg.org/#concept-node-remove - fn remove(node: JSRef<Node>, parent: JSRef<Node>, _suppress_observers: SuppressObserver) { - assert!(node.GetParentNode().map_or(false, |node_parent| node_parent == Temporary::from_rooted(parent))); + fn remove(node: &Node, parent: &Node, _suppress_observers: SuppressObserver) { + assert!(node.GetParentNode().map_or(false, |node_parent| node_parent.r() == parent)); // Step 1-5: ranges. // Step 6-7: mutation observers. @@ -1801,49 +1767,49 @@ impl Node { } // https://dom.spec.whatwg.org/#concept-node-clone - pub fn clone(node: JSRef<Node>, maybe_doc: Option<JSRef<Document>>, - clone_children: CloneChildrenFlag) -> Temporary<Node> { + pub fn clone(node: &Node, maybe_doc: Option<&Document>, + clone_children: CloneChildrenFlag) -> Root<Node> { // Step 1. let document = match maybe_doc { - Some(doc) => JS::from_rooted(doc).root(), - None => node.owner_doc().root() + Some(doc) => Root::from_ref(doc), + None => node.owner_doc() }; // Step 2. // XXXabinader: clone() for each node as trait? let copy: Root<Node> = match node.type_id() { NodeTypeId::DocumentType => { - let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); + let doctype: &DocumentType = DocumentTypeCast::to_ref(node).unwrap(); let doctype = DocumentType::new(doctype.name().clone(), Some(doctype.public_id().clone()), Some(doctype.system_id().clone()), document.r()); - NodeCast::from_temporary(doctype) + NodeCast::from_root(doctype) }, NodeTypeId::DocumentFragment => { let doc_fragment = DocumentFragment::new(document.r()); - NodeCast::from_temporary(doc_fragment) + NodeCast::from_root(doc_fragment) }, NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => { let cdata = CharacterDataCast::to_ref(node).unwrap(); let comment = Comment::new(cdata.Data(), document.r()); - NodeCast::from_temporary(comment) + NodeCast::from_root(comment) }, NodeTypeId::Document => { - let document: JSRef<Document> = DocumentCast::to_ref(node).unwrap(); + let document = DocumentCast::to_ref(node).unwrap(); let is_html_doc = match document.is_html_document() { true => IsHTMLDocument::HTMLDocument, false => IsHTMLDocument::NonHTMLDocument, }; - let window = document.window().root(); + let window = document.window(); let loader = DocumentLoader::new(&*document.loader()); let document = Document::new(window.r(), Some(document.url()), is_html_doc, None, None, DocumentSource::NotFromParser, loader); - NodeCast::from_temporary(document) + NodeCast::from_root(document) }, NodeTypeId::Element(..) => { - let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let element = ElementCast::to_ref(node).unwrap(); let name = QualName { ns: element.namespace().clone(), local: element.local_name().clone() @@ -1851,48 +1817,50 @@ impl Node { let element = Element::create(name, element.prefix().as_ref().map(|p| Atom::from_slice(&p)), document.r(), ElementCreator::ScriptCreated); - NodeCast::from_temporary(element) + NodeCast::from_root(element) }, NodeTypeId::CharacterData(CharacterDataTypeId::Text) => { let cdata = CharacterDataCast::to_ref(node).unwrap(); let text = Text::new(cdata.Data(), document.r()); - NodeCast::from_temporary(text) + NodeCast::from_root(text) }, NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => { - let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); + let pi = ProcessingInstructionCast::to_ref(node).unwrap(); let pi = ProcessingInstruction::new(pi.Target(), CharacterDataCast::from_ref(pi).Data(), document.r()); - NodeCast::from_temporary(pi) + NodeCast::from_root(pi) }, - }.root(); + }; // Step 3. let document = match DocumentCast::to_ref(copy.r()) { - Some(doc) => doc, - None => document.r(), + Some(doc) => Root::from_ref(doc), + None => Root::from_ref(document.r()), }; - assert!(copy.r().owner_doc().root().r() == document); + assert!(copy.r().owner_doc() == document); // Step 4 (some data already copied in step 2). match node.type_id() { NodeTypeId::Document => { - let node_doc: JSRef<Document> = DocumentCast::to_ref(node).unwrap(); - let copy_doc: JSRef<Document> = DocumentCast::to_ref(copy.r()).unwrap(); + let node_doc = DocumentCast::to_ref(node).unwrap(); + let copy_doc = DocumentCast::to_ref(copy.r()).unwrap(); copy_doc.set_encoding_name(node_doc.encoding_name().clone()); copy_doc.set_quirks_mode(node_doc.quirks_mode()); }, NodeTypeId::Element(..) => { - let node_elem: JSRef<Element> = ElementCast::to_ref(node).unwrap(); - let copy_elem: JSRef<Element> = ElementCast::to_ref(copy.r()).unwrap(); + let node_elem: &Element = ElementCast::to_ref(node).unwrap(); + let copy_elem: &Element = ElementCast::to_ref(copy.r()).unwrap(); // FIXME: https://github.com/mozilla/servo/issues/1737 - let window = document.window().root(); - for ref attr in node_elem.attrs().iter().map(|attr| attr.root()) { - copy_elem.attrs_mut().push_unrooted( - &Attr::new(window.r(), - attr.r().local_name().clone(), attr.r().value().clone(), - attr.r().name().clone(), attr.r().namespace().clone(), - attr.r().prefix().clone(), Some(copy_elem))); + let window = document.r().window(); + for ref attr in node_elem.attrs().iter() { + let attr = attr.root(); + let newattr = + Attr::new(window.r(), + attr.r().local_name().clone(), attr.r().value().clone(), + attr.r().name().clone(), attr.r().namespace().clone(), + attr.r().prefix().clone(), Some(copy_elem)); + copy_elem.attrs_mut().push(JS::from_rooted(&newattr)); } }, _ => () @@ -1904,21 +1872,19 @@ impl Node { // Step 6. if clone_children == CloneChildrenFlag::CloneChildren { for child in node.children() { - let child = child.root(); - let child_copy = Node::clone(child.r(), Some(document), - clone_children).root(); + let child_copy = Node::clone(child.r(), Some(document.r()), + clone_children); let _inserted_node = Node::pre_insert(child_copy.r(), copy.r(), None); } } // Step 7. - Temporary::from_rooted(copy.r()) + copy } - pub fn collect_text_contents<T: Iterator<Item=Temporary<Node>>>(iterator: T) -> String { + pub fn collect_text_contents<T: Iterator<Item=Root<Node>>>(iterator: T) -> String { let mut content = String::new(); for node in iterator { - let node = node.root(); let text = TextCast::to_ref(node.r()); match text { Some(text) => content.push_str(&CharacterDataCast::from_ref(text).Data()), @@ -1929,7 +1895,7 @@ impl Node { } } -impl<'a> NodeMethods for JSRef<'a, Node> { +impl<'a> NodeMethods for &'a Node { // https://dom.spec.whatwg.org/#dom-node-nodetype fn NodeType(self) -> u16 { match self.type_id { @@ -1954,18 +1920,18 @@ impl<'a> NodeMethods for JSRef<'a, Node> { fn NodeName(self) -> DOMString { match self.type_id { NodeTypeId::Element(..) => { - let elem: JSRef<Element> = ElementCast::to_ref(self).unwrap(); + let elem: &Element = ElementCast::to_ref(self).unwrap(); elem.TagName() } NodeTypeId::CharacterData(CharacterDataTypeId::Text) => "#text".to_owned(), NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => { - let processing_instruction: JSRef<ProcessingInstruction> = + let processing_instruction: &ProcessingInstruction = ProcessingInstructionCast::to_ref(self).unwrap(); processing_instruction.Target() } NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => "#comment".to_owned(), NodeTypeId::DocumentType => { - let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(self).unwrap(); + let doctype: &DocumentType = DocumentTypeCast::to_ref(self).unwrap(); doctype.name().clone() }, NodeTypeId::DocumentFragment => "#document-fragment".to_owned(), @@ -1980,7 +1946,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-ownerdocument - fn GetOwnerDocument(self) -> Option<Temporary<Document>> { + fn GetOwnerDocument(self) -> Option<Root<Document>> { match self.type_id { NodeTypeId::CharacterData(..) | NodeTypeId::Element(..) | @@ -1991,13 +1957,13 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-parentnode - fn GetParentNode(self) -> Option<Temporary<Node>> { - self.parent_node.get().map(Temporary::from_rooted) + fn GetParentNode(self) -> Option<Root<Node>> { + self.parent_node.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-node-parentelement - fn GetParentElement(self) -> Option<Temporary<Element>> { - self.GetParentNode().and_then(ElementCast::to_temporary) + fn GetParentElement(self) -> Option<Root<Element>> { + self.GetParentNode().and_then(ElementCast::to_root) } // https://dom.spec.whatwg.org/#dom-node-haschildnodes @@ -2006,39 +1972,39 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-childnodes - fn ChildNodes(self) -> Temporary<NodeList> { + fn ChildNodes(self) -> Root<NodeList> { self.child_list.or_init(|| { - let doc = self.owner_doc().root(); - let window = doc.r().window().root(); + let doc = self.owner_doc(); + let window = doc.r().window(); NodeList::new_child_list(window.r(), self) }) } // https://dom.spec.whatwg.org/#dom-node-firstchild - fn GetFirstChild(self) -> Option<Temporary<Node>> { - self.first_child.get().map(Temporary::from_rooted) + fn GetFirstChild(self) -> Option<Root<Node>> { + self.first_child.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-node-lastchild - fn GetLastChild(self) -> Option<Temporary<Node>> { - self.last_child.get().map(Temporary::from_rooted) + fn GetLastChild(self) -> Option<Root<Node>> { + self.last_child.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-node-previoussibling - fn GetPreviousSibling(self) -> Option<Temporary<Node>> { - self.prev_sibling.get().map(Temporary::from_rooted) + fn GetPreviousSibling(self) -> Option<Root<Node>> { + self.prev_sibling.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-node-nextsibling - fn GetNextSibling(self) -> Option<Temporary<Node>> { - self.next_sibling.get().map(Temporary::from_rooted) + fn GetNextSibling(self) -> Option<Root<Node>> { + self.next_sibling.get().map(Root::from_rooted) } // https://dom.spec.whatwg.org/#dom-node-nodevalue fn GetNodeValue(self) -> Option<DOMString> { match self.type_id { NodeTypeId::CharacterData(..) => { - let chardata: JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap(); + let chardata: &CharacterData = CharacterDataCast::to_ref(self).unwrap(); Some(chardata.Data()) } _ => { @@ -2066,7 +2032,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { Some(content) } NodeTypeId::CharacterData(..) => { - let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap(); + let characterdata: &CharacterData = CharacterDataCast::to_ref(self).unwrap(); Some(characterdata.Data()) } NodeTypeId::DocumentType | @@ -2086,19 +2052,19 @@ impl<'a> NodeMethods for JSRef<'a, Node> { let node = if value.len() == 0 { None } else { - let document = self.owner_doc().root(); - Some(NodeCast::from_temporary(document.r().CreateTextNode(value))) - }.root(); + let document = self.owner_doc(); + Some(NodeCast::from_root(document.r().CreateTextNode(value))) + }; // Step 3. Node::replace_all(node.r(), self); } NodeTypeId::CharacterData(..) => { - let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(self).unwrap(); + let characterdata: &CharacterData = CharacterDataCast::to_ref(self).unwrap(); characterdata.SetData(value); // Notify the document that the content of this node is different - let document = self.owner_doc().root(); + let document = self.owner_doc(); document.r().content_changed(self, NodeDamage::OtherNodeDamage); } NodeTypeId::DocumentType | @@ -2107,17 +2073,17 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-insertbefore - fn InsertBefore(self, node: JSRef<Node>, child: Option<JSRef<Node>>) -> Fallible<Temporary<Node>> { + fn InsertBefore(self, node: &Node, child: Option<&Node>) -> Fallible<Root<Node>> { Node::pre_insert(node, self, child) } // https://dom.spec.whatwg.org/#dom-node-appendchild - fn AppendChild(self, node: JSRef<Node>) -> Fallible<Temporary<Node>> { + fn AppendChild(self, node: &Node) -> Fallible<Root<Node>> { Node::pre_insert(node, self, None) } // https://dom.spec.whatwg.org/#concept-node-replace - fn ReplaceChild(self, node: JSRef<Node>, child: JSRef<Node>) -> Fallible<Temporary<Node>> { + fn ReplaceChild(self, node: &Node, child: &Node) -> Fallible<Root<Node>> { // Step 1. match self.type_id { @@ -2157,7 +2123,6 @@ impl<'a> NodeMethods for JSRef<'a, Node> { NodeTypeId::DocumentFragment => { // Step 6.1.1(b) if node.children() - .map(|c| c.root()) .any(|c| c.r().is_text()) { return Err(HierarchyRequest); @@ -2167,12 +2132,10 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Step 6.1.2 1 => { if self.child_elements() - .map(|c| c.root()) .any(|c| NodeCast::from_ref(c.r()) != child) { return Err(HierarchyRequest); } if child.following_siblings() - .map(|c| c.root()) .any(|child| child.r().is_doctype()) { return Err(HierarchyRequest); } @@ -2184,12 +2147,10 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Step 6.2 NodeTypeId::Element(..) => { if self.child_elements() - .map(|c| c.root()) .any(|c| NodeCast::from_ref(c.r()) != child) { return Err(HierarchyRequest); } if child.following_siblings() - .map(|c| c.root()) .any(|child| child.r().is_doctype()) { return Err(HierarchyRequest); @@ -2198,13 +2159,12 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Step 6.3 NodeTypeId::DocumentType => { if self.children() - .map(|c| c.root()) - .any(|c| c.r().is_doctype() && c.r() != child) + .any(|c| c.r().is_doctype() && + c.r() != child) { return Err(HierarchyRequest); } if self.children() - .map(|c| c.root()) .take_while(|c| c.r() != child) .any(|c| c.r().is_element()) { @@ -2220,12 +2180,12 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Ok if not caught by previous error checks. if node == child { - return Ok(Temporary::from_rooted(child)); + return Ok(Root::from_ref(child)); } // Step 7-8. - let child_next_sibling = child.next_sibling.get().root(); - let node_next_sibling = node.next_sibling.get().root(); + let child_next_sibling = child.next_sibling.get().map(Root::from_rooted); + let node_next_sibling = node.next_sibling.get().map(Root::from_rooted); let reference_child = if child_next_sibling.r() == Some(node) { node_next_sibling.r() } else { @@ -2233,7 +2193,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { }; // Step 9. - let document = document_from_node(self).root(); + let document = document_from_node(self); Node::adopt(node, document.r()); // Step 12. @@ -2245,11 +2205,10 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Issue filed against the spec: // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28330 for child_node in node.children() { - let child_node = child_node.root(); - nodes.push(JS::from_rooted(child_node.r())); + nodes.push(JS::from_rooted(&child_node)); } } else { - nodes.push(JS::from_rooted(node)); + nodes.push(JS::from_ref(node)); } { @@ -2263,40 +2222,38 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Step 13: mutation records. child.node_removed(self.is_in_doc()); for child_node in &*nodes { - let child_node = child_node.root(); - child_node.r().node_inserted(); + child_node.root().r().node_inserted(); } // Step 14. - Ok(Temporary::from_rooted(child)) + Ok(Root::from_ref(child)) } // https://dom.spec.whatwg.org/#dom-node-removechild - fn RemoveChild(self, node: JSRef<Node>) - -> Fallible<Temporary<Node>> { + fn RemoveChild(self, node: &Node) + -> Fallible<Root<Node>> { Node::pre_remove(node, self) } // https://dom.spec.whatwg.org/#dom-node-normalize fn Normalize(self) { - let mut prev_text: Option<Temporary<Text>> = None; + let mut prev_text: Option<Root<Text>> = None; for child in self.children() { - let child = child.root(); match TextCast::to_ref(child.r()) { Some(text) => { - let characterdata: JSRef<CharacterData> = CharacterDataCast::from_ref(text); + let characterdata: &CharacterData = CharacterDataCast::from_ref(text); if characterdata.Length() == 0 { self.remove_child(child.r()); } else { match prev_text { Some(ref text_node) => { - let text_node = text_node.clone().root(); - let prev_characterdata: JSRef<CharacterData> = + let text_node = text_node.clone(); + let prev_characterdata = CharacterDataCast::from_ref(text_node.r()); let _ = prev_characterdata.AppendData(characterdata.Data()); self.remove_child(child.r()); }, - None => prev_text = Some(Temporary::from_rooted(text)) + None => prev_text = Some(Root::from_ref(text)) } } }, @@ -2309,7 +2266,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-clonenode - fn CloneNode(self, deep: bool) -> Temporary<Node> { + fn CloneNode(self, deep: bool) -> Root<Node> { Node::clone(self, None, if deep { CloneChildrenFlag::CloneChildren } else { @@ -2318,51 +2275,53 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-isequalnode - fn IsEqualNode(self, maybe_node: Option<JSRef<Node>>) -> bool { - fn is_equal_doctype(node: JSRef<Node>, other: JSRef<Node>) -> bool { - let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); - let other_doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(other).unwrap(); + fn IsEqualNode(self, maybe_node: Option<&Node>) -> bool { + fn is_equal_doctype(node: &Node, other: &Node) -> bool { + let doctype: &DocumentType = DocumentTypeCast::to_ref(node).unwrap(); + let other_doctype: &DocumentType = DocumentTypeCast::to_ref(other).unwrap(); (*doctype.name() == *other_doctype.name()) && (*doctype.public_id() == *other_doctype.public_id()) && (*doctype.system_id() == *other_doctype.system_id()) } - fn is_equal_element(node: JSRef<Node>, other: JSRef<Node>) -> bool { - let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); - let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap(); + fn is_equal_element(node: &Node, other: &Node) -> bool { + let element: &Element = ElementCast::to_ref(node).unwrap(); + let other_element: &Element = ElementCast::to_ref(other).unwrap(); // FIXME: namespace prefix (*element.namespace() == *other_element.namespace()) && (*element.local_name() == *other_element.local_name()) && (element.attrs().len() == other_element.attrs().len()) } - fn is_equal_processinginstruction(node: JSRef<Node>, other: JSRef<Node>) -> bool { - let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); - let other_pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(other).unwrap(); + fn is_equal_processinginstruction(node: &Node, other: &Node) -> bool { + let pi: &ProcessingInstruction = ProcessingInstructionCast::to_ref(node).unwrap(); + let other_pi: &ProcessingInstruction = ProcessingInstructionCast::to_ref(other).unwrap(); (*pi.target() == *other_pi.target()) && (*CharacterDataCast::from_ref(pi).data() == *CharacterDataCast::from_ref(other_pi).data()) } - fn is_equal_characterdata(node: JSRef<Node>, other: JSRef<Node>) -> bool { - let characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(node).unwrap(); - let other_characterdata: JSRef<CharacterData> = CharacterDataCast::to_ref(other).unwrap(); + fn is_equal_characterdata(node: &Node, other: &Node) -> bool { + let characterdata: &CharacterData = CharacterDataCast::to_ref(node).unwrap(); + let other_characterdata: &CharacterData = CharacterDataCast::to_ref(other).unwrap(); // FIXME(https://github.com/rust-lang/rust/issues/23338) let own_data = characterdata.data(); let other_data = other_characterdata.data(); *own_data == *other_data } - fn is_equal_element_attrs(node: JSRef<Node>, other: JSRef<Node>) -> bool { - let element: JSRef<Element> = ElementCast::to_ref(node).unwrap(); - let other_element: JSRef<Element> = ElementCast::to_ref(other).unwrap(); + fn is_equal_element_attrs(node: &Node, other: &Node) -> bool { + let element: &Element = ElementCast::to_ref(node).unwrap(); + let other_element: &Element = ElementCast::to_ref(other).unwrap(); assert!(element.attrs().len() == other_element.attrs().len()); // FIXME(https://github.com/rust-lang/rust/issues/23338) let attrs = element.attrs(); - attrs.iter().map(|attr| attr.root()).all(|attr| { - other_element.attrs().iter().map(|attr| attr.root()).any(|other_attr| { + attrs.iter().all(|attr| { + let attr = attr.root(); + other_element.attrs().iter().any(|other_attr| { + let other_attr = other_attr.root(); (*attr.r().namespace() == *other_attr.r().namespace()) && (attr.r().local_name() == other_attr.r().local_name()) && (**attr.r().value() == **other_attr.r().value()) }) }) } - fn is_equal_node(this: JSRef<Node>, node: JSRef<Node>) -> bool { + fn is_equal_node(this: &Node, node: &Node) -> bool { // Step 2. if this.type_id() != node.type_id() { return false; @@ -2392,7 +2351,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // Step 6. this.children().zip(node.children()).all(|(child, other_child)| { - is_equal_node(child.root().r(), other_child.root().r()) + is_equal_node(child.r(), other_child.r()) }) } match maybe_node { @@ -2404,30 +2363,28 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-comparedocumentposition - fn CompareDocumentPosition(self, other: JSRef<Node>) -> u16 { + fn CompareDocumentPosition(self, other: &Node) -> u16 { if self == other { // step 2. 0 } else { - let mut lastself = Temporary::from_rooted(self.clone()); - let mut lastother = Temporary::from_rooted(other.clone()); + let mut lastself = Root::from_ref(self); + let mut lastother = Root::from_ref(other); for ancestor in self.ancestors() { - let ancestor = ancestor.root(); if ancestor.r() == other { // step 4. return NodeConstants::DOCUMENT_POSITION_CONTAINS + NodeConstants::DOCUMENT_POSITION_PRECEDING; } - lastself = Temporary::from_rooted(ancestor.r()); + lastself = ancestor; } for ancestor in other.ancestors() { - let ancestor = ancestor.root(); if ancestor.r() == self { // step 5. return NodeConstants::DOCUMENT_POSITION_CONTAINED_BY + NodeConstants::DOCUMENT_POSITION_FOLLOWING; } - lastother = Temporary::from_rooted(ancestor.r()); + lastother = ancestor; } if lastself != lastother { @@ -2445,9 +2402,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { NodeConstants::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; } - let lastself = lastself.root(); for child in lastself.r().traverse_preorder() { - let child = child.root(); if child.r() == other { // step 6. return NodeConstants::DOCUMENT_POSITION_PRECEDING; @@ -2462,7 +2417,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { } // https://dom.spec.whatwg.org/#dom-node-contains - fn Contains(self, maybe_other: Option<JSRef<Node>>) -> bool { + fn Contains(self, maybe_other: Option<&Node>) -> bool { match maybe_other { None => false, Some(other) => self.is_inclusive_ancestor_of(other) @@ -2483,13 +2438,13 @@ impl<'a> NodeMethods for JSRef<'a, Node> { NodeTypeId::Element(..) => ElementCast::to_ref(self).unwrap().lookup_prefix(namespace), NodeTypeId::Document => { DocumentCast::to_ref(self).unwrap().GetDocumentElement().and_then(|element| { - element.root().r().lookup_prefix(namespace) + element.r().lookup_prefix(namespace) }) }, NodeTypeId::DocumentType | NodeTypeId::DocumentFragment => None, _ => { self.GetParentElement().and_then(|element| { - element.root().r().lookup_prefix(namespace) + element.r().lookup_prefix(namespace) }) } } @@ -2520,47 +2475,47 @@ pub struct TrustedNodeAddress(pub *const c_void); #[allow(unsafe_code)] unsafe impl Send for TrustedNodeAddress {} -pub fn document_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Document> { - let node: JSRef<Node> = NodeCast::from_ref(derived); +pub fn document_from_node<T: NodeBase+Reflectable>(derived: &T) -> Root<Document> { + let node: &Node = NodeCast::from_ref(derived); node.owner_doc() } -pub fn window_from_node<T: NodeBase+Reflectable>(derived: JSRef<T>) -> Temporary<Window> { - let document = document_from_node(derived).root(); +pub fn window_from_node<T: NodeBase+Reflectable>(derived: &T) -> Root<Window> { + let document = document_from_node(derived); document.r().window() } -impl<'a> VirtualMethods for JSRef<'a, Node> { +impl<'a> VirtualMethods for &'a Node { fn super_type<'b>(&'b self) -> Option<&'b VirtualMethods> { - let eventtarget: &JSRef<EventTarget> = EventTargetCast::from_borrowed_ref(self); + let eventtarget: &&EventTarget = EventTargetCast::from_borrowed_ref(self); Some(eventtarget as &VirtualMethods) } } -impl<'a> style::node::TNode<'a> for JSRef<'a, Node> { - type Element = JSRef<'a, Element>; +impl<'a> style::node::TNode<'a> for &'a Node { + type Element = &'a Element; - fn parent_node(self) -> Option<JSRef<'a, Node>> { + fn parent_node(self) -> Option<&'a Node> { (*self).parent_node.get() .map(|node| node.root().get_unsound_ref_forever()) } - fn first_child(self) -> Option<JSRef<'a, Node>> { + fn first_child(self) -> Option<&'a Node> { (*self).first_child.get() .map(|node| node.root().get_unsound_ref_forever()) } - fn last_child(self) -> Option<JSRef<'a, Node>> { + fn last_child(self) -> Option<&'a Node> { (*self).last_child.get() .map(|node| node.root().get_unsound_ref_forever()) } - fn prev_sibling(self) -> Option<JSRef<'a, Node>> { + fn prev_sibling(self) -> Option<&'a Node> { (*self).prev_sibling.get() .map(|node| node.root().get_unsound_ref_forever()) } - fn next_sibling(self) -> Option<JSRef<'a, Node>> { + fn next_sibling(self) -> Option<&'a Node> { (*self).next_sibling.get() .map(|node| node.root().get_unsound_ref_forever()) } @@ -2568,7 +2523,7 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> { fn is_document(self) -> bool { // FIXME(zwarich): Remove this when UFCS lands and there is a better way // of disambiguating methods. - fn is_document<'a, T: NodeHelpers>(this: T) -> bool { + fn is_document<'a, T: DocumentDerived>(this: &T) -> bool { this.is_document() } @@ -2578,14 +2533,14 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> { fn is_element(self) -> bool { // FIXME(zwarich): Remove this when UFCS lands and there is a better way // of disambiguating methods. - fn is_element<'a, T: NodeHelpers>(this: T) -> bool { + fn is_element<'a, T: ElementDerived>(this: &T) -> bool { this.is_element() } is_element(self) } - fn as_element(self) -> JSRef<'a, Element> { + fn as_element(self) -> &'a Element { ElementCast::to_ref(self).unwrap() } @@ -2601,7 +2556,7 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> { }; match attr.namespace { NamespaceConstraint::Specific(ref ns) => { - self.as_element().get_attribute(ns, local_name).root() + self.as_element().get_attribute(ns, local_name) .map_or(false, |attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) let attr = attr.r(); @@ -2612,10 +2567,10 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> { NamespaceConstraint::Any => { let mut attributes: RootedVec<JS<Attr>> = RootedVec::new(); self.as_element().get_attributes(local_name, &mut attributes); - attributes.iter().map(|attr| attr.root()).any(|attr| { + attributes.iter().any(|attr| { // FIXME(https://github.com/rust-lang/rust/issues/23338) - let attr = attr.r(); - let value = attr.value(); + let attr = attr.root(); + let value = attr.r().value(); test(&value) }) } @@ -2649,11 +2604,11 @@ pub trait DisabledStateHelpers { fn check_disabled_attribute(self); } -impl<'a> DisabledStateHelpers for JSRef<'a, Node> { +impl<'a> DisabledStateHelpers for &'a Node { fn check_ancestors_disabled_state_for_form_control(self) { if self.get_disabled_state() { return; } for ancestor in self.ancestors() { - let ancestor = ancestor.root(); + let ancestor = ancestor; let ancestor = ancestor.r(); if !ancestor.is_htmlfieldsetelement() { continue; } if !ancestor.get_disabled_state() { continue; } @@ -2663,12 +2618,11 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { return; } match ancestor.children() - .map(|child| child.root()) .find(|child| child.r().is_htmllegendelement()) { Some(ref legend) => { // XXXabinader: should we save previous ancestor to avoid this iteration? - if self.ancestors().any(|ancestor| ancestor.root().r() == legend.r()) { continue; } + if self.ancestors().any(|ancestor| ancestor == *legend) { continue; } }, None => () } @@ -2680,7 +2634,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { fn check_parent_disabled_state_for_option(self) { if self.get_disabled_state() { return; } - if let Some(ref parent) = self.GetParentNode().root() { + if let Some(ref parent) = self.GetParentNode() { if parent.r().is_htmloptgroupelement() && parent.r().get_disabled_state() { self.set_disabled_state(true); self.set_enabled_state(false); @@ -2689,7 +2643,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { } fn check_disabled_attribute(self) { - let elem: JSRef<'a, Element> = ElementCast::to_ref(self).unwrap(); + let elem = ElementCast::to_ref(self).unwrap(); let has_disabled_attrib = elem.has_attribute(&atom!("disabled")); self.set_disabled_state(has_disabled_attrib); self.set_enabled_state(!has_disabled_attrib); diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs index 42c51ee8c55..69e9c145937 100644 --- a/components/script/dom/nodeiterator.rs +++ b/components/script/dom/nodeiterator.rs @@ -10,12 +10,13 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutHeap, OptionalRootable, Temporary, Rootable, RootedReference}; +use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers}; use dom::node::{Node, NodeHelpers}; use std::cell::Cell; +use std::rc::Rc; #[dom_struct] pub struct NodeIterator { @@ -28,33 +29,33 @@ pub struct NodeIterator { } impl NodeIterator { - fn new_inherited(root_node: JSRef<Node>, + fn new_inherited(root_node: &Node, what_to_show: u32, filter: Filter) -> NodeIterator { NodeIterator { reflector_: Reflector::new(), - root_node: JS::from_rooted(root_node), - reference_node: MutHeap::new(JS::from_rooted(root_node)), + root_node: JS::from_ref(root_node), + reference_node: MutHeap::new(JS::from_ref(root_node)), pointer_before_reference_node: Cell::new(true), what_to_show: what_to_show, filter: filter } } - pub fn new_with_filter(document: JSRef<Document>, - root_node: JSRef<Node>, + pub fn new_with_filter(document: &Document, + root_node: &Node, what_to_show: u32, - filter: Filter) -> Temporary<NodeIterator> { - let window = document.window().root(); + filter: Filter) -> Root<NodeIterator> { + let window = document.window(); reflect_dom_object(box NodeIterator::new_inherited(root_node, what_to_show, filter), GlobalRef::Window(window.r()), NodeIteratorBinding::Wrap) } - pub fn new(document: JSRef<Document>, - root_node: JSRef<Node>, + pub fn new(document: &Document, + root_node: &Node, what_to_show: u32, - node_filter: Option<NodeFilter>) -> Temporary<NodeIterator> { + node_filter: Option<Rc<NodeFilter>>) -> Root<NodeIterator> { let filter = match node_filter { None => Filter::None, Some(jsfilter) => Filter::Callback(jsfilter) @@ -63,10 +64,10 @@ impl NodeIterator { } } -impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { +impl<'a> NodeIteratorMethods for &'a NodeIterator { // https://dom.spec.whatwg.org/#dom-nodeiterator-root - fn Root(self) -> Temporary<Node> { - Temporary::from_rooted(self.root_node) + fn Root(self) -> Root<Node> { + self.root_node.root() } // https://dom.spec.whatwg.org/#dom-nodeiterator-whattoshow @@ -75,17 +76,17 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { } // https://dom.spec.whatwg.org/#dom-nodeiterator-filter - fn GetFilter(self) -> Option<NodeFilter> { + fn GetFilter(self) -> Option<Rc<NodeFilter>> { match self.filter { Filter::None => None, - Filter::Callback(nf) => Some(nf), + Filter::Callback(ref nf) => Some((*nf).clone()), Filter::Native(_) => panic!("Cannot convert native node filter to DOM NodeFilter") } } // https://dom.spec.whatwg.org/#dom-nodeiterator-referencenode - fn ReferenceNode(self) -> Temporary<Node> { - Temporary::from_rooted(self.reference_node.get()) + fn ReferenceNode(self) -> Root<Node> { + self.reference_node.get().root() } // https://dom.spec.whatwg.org/#dom-nodeiterator-pointerbeforereferencenode @@ -94,7 +95,7 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { } // https://dom.spec.whatwg.org/#dom-nodeiterator-nextnode - fn NextNode(self) -> Fallible<Option<Temporary<Node>>> { + fn NextNode(self) -> Fallible<Option<Root<Node>>> { // https://dom.spec.whatwg.org/#concept-NodeIterator-traverse // Step 1. let node = self.reference_node.get().root(); @@ -112,27 +113,25 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { // Step 4. - self.reference_node.set(JS::from_rooted(node.r())); + self.reference_node.set(JS::from_ref(node.r())); self.pointer_before_reference_node.set(before_node); - return Ok(Some(Temporary::from_rooted(node.r()))); + return Ok(Some(node)); } } // Step 3-1. for following_node in node.r().following_nodes(self.root_node.root().r()) { - let following_node = following_node.root(); - // Step 3-2. let result = try!(self.accept_node(following_node.r())); // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { // Step 4. - self.reference_node.set(JS::from_rooted(following_node.r())); + self.reference_node.set(JS::from_ref(following_node.r())); self.pointer_before_reference_node.set(before_node); - return Ok(Some(Temporary::from_rooted(following_node.r()))); + return Ok(Some(following_node)); } } @@ -140,7 +139,7 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { } // https://dom.spec.whatwg.org/#dom-nodeiterator-previousnode - fn PreviousNode(self) -> Fallible<Option<Temporary<Node>>> { + fn PreviousNode(self) -> Fallible<Option<Root<Node>>> { // https://dom.spec.whatwg.org/#concept-NodeIterator-traverse // Step 1. let node = self.reference_node.get().root(); @@ -158,16 +157,15 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { // Step 4. - self.reference_node.set(JS::from_rooted(node.r())); + self.reference_node.set(JS::from_ref(node.r())); self.pointer_before_reference_node.set(before_node); - return Ok(Some(Temporary::from_rooted(node.r()))); + return Ok(Some(node)); } } // Step 3-1. for preceding_node in node.r().preceding_nodes(self.root_node.root().r()) { - let preceding_node = preceding_node.root(); // Step 3-2. let result = try!(self.accept_node(preceding_node.r())); @@ -175,10 +173,10 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { // Step 4. - self.reference_node.set(JS::from_rooted(preceding_node.r())); + self.reference_node.set(JS::from_ref(preceding_node.r())); self.pointer_before_reference_node.set(before_node); - return Ok(Some(Temporary::from_rooted(preceding_node.r()))); + return Ok(Some(preceding_node)); } } @@ -192,13 +190,13 @@ impl<'a> NodeIteratorMethods for JSRef<'a, NodeIterator> { } trait PrivateNodeIteratorHelpers { - fn accept_node(self, node: JSRef<Node>) -> Fallible<u16>; - fn is_root_node(self, node: JSRef<Node>) -> bool; + fn accept_node(self, node: &Node) -> Fallible<u16>; + fn is_root_node(self, node: &Node) -> bool; } -impl<'a> PrivateNodeIteratorHelpers for JSRef<'a, NodeIterator> { +impl<'a> PrivateNodeIteratorHelpers for &'a NodeIterator { // https://dom.spec.whatwg.org/#concept-node-filter - fn accept_node(self, node: JSRef<Node>) -> Fallible<u16> { + fn accept_node(self, node: &Node) -> Fallible<u16> { // Step 1. let n = node.NodeType() - 1; // Step 2. @@ -209,12 +207,12 @@ impl<'a> PrivateNodeIteratorHelpers for JSRef<'a, NodeIterator> { match self.filter { Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT), Filter::Native(f) => Ok((f)(node)), - Filter::Callback(callback) => callback.AcceptNode_(self, node, Rethrow) + Filter::Callback(ref callback) => callback.AcceptNode_(self, node, Rethrow) } } - fn is_root_node(self, node: JSRef<Node>) -> bool { - JS::from_rooted(node) == self.root_node + fn is_root_node(self, node: &Node) -> bool { + JS::from_ref(node) == self.root_node } } @@ -222,6 +220,6 @@ impl<'a> PrivateNodeIteratorHelpers for JSRef<'a, NodeIterator> { #[jstraceable] pub enum Filter { None, - Native(fn (node: JSRef<Node>) -> u16), - Callback(NodeFilter) + Native(fn (node: &Node) -> u16), + Callback(Rc<NodeFilter>) } diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index bb3df75e920..0a81e9f865f 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::NodeListBinding; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::node::{Node, NodeHelpers}; use dom::window::Window; @@ -32,24 +32,24 @@ impl NodeList { } } - pub fn new(window: JSRef<Window>, - list_type: NodeListType) -> Temporary<NodeList> { + pub fn new(window: &Window, + list_type: NodeListType) -> Root<NodeList> { reflect_dom_object(box NodeList::new_inherited(list_type), GlobalRef::Window(window), NodeListBinding::Wrap) } - pub fn new_simple_list<T>(window: JSRef<Window>, iter: T) - -> Temporary<NodeList> - where T: Iterator<Item=Temporary<Node>> { - NodeList::new(window, NodeListType::Simple(iter.map(JS::from_rooted).collect())) + pub fn new_simple_list<T>(window: &Window, iter: T) + -> Root<NodeList> + where T: Iterator<Item=Root<Node>> { + NodeList::new(window, NodeListType::Simple(iter.map(|r| JS::from_rooted(&r)).collect())) } - pub fn new_child_list(window: JSRef<Window>, node: JSRef<Node>) -> Temporary<NodeList> { - NodeList::new(window, NodeListType::Children(JS::from_rooted(node))) + pub fn new_child_list(window: &Window, node: &Node) -> Root<NodeList> { + NodeList::new(window, NodeListType::Children(JS::from_ref(node))) } } -impl<'a> NodeListMethods for JSRef<'a, NodeList> { +impl<'a> NodeListMethods for &'a NodeList { // https://dom.spec.whatwg.org/#dom-nodelist-length fn Length(self) -> u32 { match self.list_type { @@ -62,10 +62,10 @@ impl<'a> NodeListMethods for JSRef<'a, NodeList> { } // https://dom.spec.whatwg.org/#dom-nodelist-item - fn Item(self, index: u32) -> Option<Temporary<Node>> { + fn Item(self, index: u32) -> Option<Root<Node>> { match self.list_type { _ if index >= self.Length() => None, - NodeListType::Simple(ref elems) => Some(Temporary::from_rooted(elems[index as usize].clone())), + NodeListType::Simple(ref elems) => Some(elems[index as usize].root()), NodeListType::Children(ref node) => { let node = node.root(); node.r().children().nth(index as usize) @@ -73,7 +73,7 @@ impl<'a> NodeListMethods for JSRef<'a, NodeList> { } } - fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Temporary<Node>> { + fn IndexedGetter(self, index: u32, found: &mut bool) -> Option<Root<Node>> { let item = self.Item(index); *found = item.is_some(); item diff --git a/components/script/dom/performance.rs b/components/script/dom/performance.rs index dcb5dd290e9..95efff68a44 100644 --- a/components/script/dom/performance.rs +++ b/components/script/dom/performance.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::PerformanceBinding; use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::num::Finite; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::performancetiming::{PerformanceTiming, PerformanceTimingHelpers}; @@ -21,20 +21,20 @@ pub struct Performance { } impl Performance { - fn new_inherited(window: JSRef<Window>, + fn new_inherited(window: &Window, navigation_start: u64, navigation_start_precise: f64) -> Performance { Performance { reflector_: Reflector::new(), - timing: JS::from_rooted(PerformanceTiming::new(window, - navigation_start, - navigation_start_precise)), + timing: JS::from_rooted(&PerformanceTiming::new(window, + navigation_start, + navigation_start_precise)), } } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, navigation_start: u64, - navigation_start_precise: f64) -> Temporary<Performance> { + navigation_start_precise: f64) -> Root<Performance> { reflect_dom_object(box Performance::new_inherited(window, navigation_start, navigation_start_precise), @@ -43,9 +43,9 @@ impl Performance { } } -impl<'a> PerformanceMethods for JSRef<'a, Performance> { - fn Timing(self) -> Temporary<PerformanceTiming> { - Temporary::from_rooted(self.timing.clone()) +impl<'a> PerformanceMethods for &'a Performance { + fn Timing(self) -> Root<PerformanceTiming> { + self.timing.root() } // https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now diff --git a/components/script/dom/performancetiming.rs b/components/script/dom/performancetiming.rs index 858e1e6c9ab..f75b1031963 100644 --- a/components/script/dom/performancetiming.rs +++ b/components/script/dom/performancetiming.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::PerformanceTimingBinding; use dom::bindings::codegen::Bindings::PerformanceTimingBinding::PerformanceTimingMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::Window; @@ -27,10 +27,10 @@ impl PerformanceTiming { } #[allow(unrooted_must_root)] - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, navigation_start: u64, navigation_start_precise: f64) - -> Temporary<PerformanceTiming> { + -> Root<PerformanceTiming> { let timing = PerformanceTiming::new_inherited(navigation_start, navigation_start_precise); reflect_dom_object(box timing, GlobalRef::Window(window), @@ -38,7 +38,7 @@ impl PerformanceTiming { } } -impl<'a> PerformanceTimingMethods for JSRef<'a, PerformanceTiming> { +impl<'a> PerformanceTimingMethods for &'a PerformanceTiming { fn NavigationStart(self) -> u64 { self.navigationStart } @@ -48,7 +48,7 @@ pub trait PerformanceTimingHelpers { fn NavigationStartPrecise(self) -> f64; } -impl<'a> PerformanceTimingHelpers for JSRef<'a, PerformanceTiming> { +impl<'a> PerformanceTimingHelpers for &'a PerformanceTiming { fn NavigationStartPrecise(self) -> f64 { self.navigationStartPrecise } diff --git a/components/script/dom/processinginstruction.rs b/components/script/dom/processinginstruction.rs index 3013cdb2f87..41dac86ed04 100644 --- a/components/script/dom/processinginstruction.rs +++ b/components/script/dom/processinginstruction.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::ProcessingInstructionBinding; use dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods; use dom::bindings::codegen::InheritTypes::ProcessingInstructionDerived; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::characterdata::{CharacterData, CharacterDataTypeId}; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -27,14 +27,14 @@ impl ProcessingInstructionDerived for EventTarget { } impl ProcessingInstruction { - fn new_inherited(target: DOMString, data: DOMString, document: JSRef<Document>) -> ProcessingInstruction { + fn new_inherited(target: DOMString, data: DOMString, document: &Document) -> ProcessingInstruction { ProcessingInstruction { characterdata: CharacterData::new_inherited(CharacterDataTypeId::ProcessingInstruction, data, document), target: target } } - pub fn new(target: DOMString, data: DOMString, document: JSRef<Document>) -> Temporary<ProcessingInstruction> { + pub fn new(target: DOMString, data: DOMString, document: &Document) -> Root<ProcessingInstruction> { Node::reflect_node(box ProcessingInstruction::new_inherited(target, data, document), document, ProcessingInstructionBinding::Wrap) } @@ -44,13 +44,13 @@ pub trait ProcessingInstructionHelpers<'a> { fn target(self) -> &'a DOMString; } -impl<'a> ProcessingInstructionHelpers<'a> for JSRef<'a, ProcessingInstruction> { +impl<'a> ProcessingInstructionHelpers<'a> for &'a ProcessingInstruction { fn target(self) -> &'a DOMString { - &self.extended_deref().target + &self.target } } -impl<'a> ProcessingInstructionMethods for JSRef<'a, ProcessingInstruction> { +impl<'a> ProcessingInstructionMethods for &'a ProcessingInstruction { // https://dom.spec.whatwg.org/#dom-processinginstruction-target fn Target(self) -> DOMString { self.target.clone() diff --git a/components/script/dom/progressevent.rs b/components/script/dom/progressevent.rs index 8294fd4b3e5..fd284e8d1b3 100644 --- a/components/script/dom/progressevent.rs +++ b/components/script/dom/progressevent.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::ProgressEventBinding::ProgressEventMethods use dom::bindings::codegen::InheritTypes::{EventCast, ProgressEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId}; use util::str::DOMString; @@ -38,25 +38,27 @@ impl ProgressEvent { } pub fn new(global: GlobalRef, type_: DOMString, can_bubble: bool, cancelable: bool, - length_computable: bool, loaded: u64, total: u64) -> Temporary<ProgressEvent> { + length_computable: bool, loaded: u64, total: u64) -> Root<ProgressEvent> { let ev = reflect_dom_object(box ProgressEvent::new_inherited(length_computable, loaded, total), global, - ProgressEventBinding::Wrap).root(); - let event: JSRef<Event> = EventCast::from_ref(ev.r()); - event.InitEvent(type_, can_bubble, cancelable); - Temporary::from_rooted(ev.r()) + ProgressEventBinding::Wrap); + { + let event = EventCast::from_ref(ev.r()); + event.InitEvent(type_, can_bubble, cancelable); + } + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, init: &ProgressEventBinding::ProgressEventInit) - -> Fallible<Temporary<ProgressEvent>> { + -> Fallible<Root<ProgressEvent>> { let ev = ProgressEvent::new(global, type_, init.parent.bubbles, init.parent.cancelable, init.lengthComputable, init.loaded, init.total); Ok(ev) } } -impl<'a> ProgressEventMethods for JSRef<'a, ProgressEvent> { +impl<'a> ProgressEventMethods for &'a ProgressEvent { fn LengthComputable(self) -> bool { self.length_computable } diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index bf5cf088953..9830e38f837 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutHeap, Rootable, Temporary}; +use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers}; use dom::node::{Node, NodeHelpers}; @@ -26,8 +26,8 @@ pub struct Range { } impl Range { - fn new_inherited(start_container: JSRef<Node>, start_offset: u32, - end_container: JSRef<Node>, end_offset: u32) -> Range { + fn new_inherited(start_container: &Node, start_offset: u32, + end_container: &Node, end_offset: u32) -> Range { Range { reflector_: Reflector::new(), inner: Rc::new(RefCell::new(RangeInner::new( @@ -36,16 +36,16 @@ impl Range { } } - pub fn new_with_doc(document: JSRef<Document>) -> Temporary<Range> { + pub fn new_with_doc(document: &Document) -> Root<Range> { let root = NodeCast::from_ref(document); Range::new(document, root, 0, root, 0) } - pub fn new(document: JSRef<Document>, - start_container: JSRef<Node>, start_offset: u32, - end_container: JSRef<Node>, end_offset: u32) - -> Temporary<Range> { - let window = document.window().root(); + pub fn new(document: &Document, + start_container: &Node, start_offset: u32, + end_container: &Node, end_offset: u32) + -> Root<Range> { + let window = document.window(); reflect_dom_object(box Range::new_inherited(start_container, start_offset, end_container, end_offset), GlobalRef::Window(window.r()), @@ -53,8 +53,8 @@ impl Range { } // https://dom.spec.whatwg.org/#dom-range - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<Range>> { - let document = global.as_window().Document().root(); + pub fn Constructor(global: GlobalRef) -> Fallible<Root<Range>> { + let document = global.as_window().Document(); Ok(Range::new_with_doc(document.r())) } } @@ -63,15 +63,15 @@ pub trait RangeHelpers<'a> { fn inner(self) -> &'a Rc<RefCell<RangeInner>>; } -impl<'a> RangeHelpers<'a> for JSRef<'a, Range> { +impl<'a> RangeHelpers<'a> for &'a Range { fn inner(self) -> &'a Rc<RefCell<RangeInner>> { - &self.extended_deref().inner + &self.inner } } -impl<'a> RangeMethods for JSRef<'a, Range> { +impl<'a> RangeMethods for &'a Range { // http://dom.spec.whatwg.org/#dom-range-startcontainer - fn StartContainer(self) -> Temporary<Node> { + fn StartContainer(self) -> Root<Node> { self.inner().borrow().start.node() } @@ -81,7 +81,7 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } /// http://dom.spec.whatwg.org/#dom-range-endcontainer - fn EndContainer(self) -> Temporary<Node> { + fn EndContainer(self) -> Root<Node> { self.inner().borrow().end.node() } @@ -97,12 +97,12 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-commonancestorcontainer - fn CommonAncestorContainer(self) -> Temporary<Node> { + fn CommonAncestorContainer(self) -> Root<Node> { self.inner().borrow().common_ancestor_container() } // https://dom.spec.whatwg.org/#dom-range-setstartnode-offset - fn SetStart(self, node: JSRef<Node>, offset: u32) -> ErrorResult { + fn SetStart(self, node: &Node, offset: u32) -> ErrorResult { if node.is_doctype() { // Step 1. Err(Error::InvalidNodeType) @@ -117,7 +117,7 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-setendnode-offset - fn SetEnd(self, node: JSRef<Node>, offset: u32) -> ErrorResult { + fn SetEnd(self, node: &Node, offset: u32) -> ErrorResult { if node.is_doctype() { // Step 1. Err(Error::InvalidNodeType) @@ -132,26 +132,26 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-setstartbeforenode - fn SetStartBefore(self, node: JSRef<Node>) -> ErrorResult { - let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)).root(); + fn SetStartBefore(self, node: &Node) -> ErrorResult { + let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)); self.SetStart(parent.r(), node.index()) } // https://dom.spec.whatwg.org/#dom-range-setstartafternode - fn SetStartAfter(self, node: JSRef<Node>) -> ErrorResult { - let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)).root(); + fn SetStartAfter(self, node: &Node) -> ErrorResult { + let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)); self.SetStart(parent.r(), node.index() + 1) } // https://dom.spec.whatwg.org/#dom-range-setendbeforenode - fn SetEndBefore(self, node: JSRef<Node>) -> ErrorResult { - let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)).root(); + fn SetEndBefore(self, node: &Node) -> ErrorResult { + let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)); self.SetEnd(parent.r(), node.index()) } // https://dom.spec.whatwg.org/#dom-range-setendafternode - fn SetEndAfter(self, node: JSRef<Node>) -> ErrorResult { - let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)).root(); + fn SetEndAfter(self, node: &Node) -> ErrorResult { + let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)); self.SetEnd(parent.r(), node.index() + 1) } @@ -161,17 +161,17 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-selectnodenode - fn SelectNode(self, node: JSRef<Node>) -> ErrorResult { + fn SelectNode(self, node: &Node) -> ErrorResult { self.inner().borrow_mut().select_node(node) } // https://dom.spec.whatwg.org/#dom-range-selectnodecontentsnode - fn SelectNodeContents(self, node: JSRef<Node>) -> ErrorResult { + fn SelectNodeContents(self, node: &Node) -> ErrorResult { self.inner().borrow_mut().select_node_contents(node) } // https://dom.spec.whatwg.org/#dom-range-compareboundarypointshow-sourcerange - fn CompareBoundaryPoints(self, how: u16, source_range: JSRef<Range>) + fn CompareBoundaryPoints(self, how: u16, source_range: &Range) -> Fallible<i16> { if how > RangeConstants::END_TO_START { // Step 1. @@ -179,8 +179,8 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } let this_inner = self.inner().borrow(); let other_inner = source_range.inner().borrow(); - let this_start_node = this_inner.start.node().root(); - let other_start_node = other_inner.start.node().root(); + let this_start_node = this_inner.start.node(); + let other_start_node = other_inner.start.node(); let this_root = this_start_node.r().inclusive_ancestors().last().unwrap(); let other_root = other_start_node.r().inclusive_ancestors().last().unwrap(); if this_root != other_root { @@ -212,18 +212,18 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-clonerange - fn CloneRange(self) -> Temporary<Range> { + fn CloneRange(self) -> Root<Range> { let inner = self.inner().borrow(); let start = &inner.start; let end = &inner.end; - let start_node = start.node().root(); - let owner_doc = NodeCast::from_ref(start_node.r()).owner_doc().root(); + let start_node = start.node(); + let owner_doc = NodeCast::from_ref(start_node.r()).owner_doc(); Range::new(owner_doc.r(), start_node.r(), start.offset, - end.node().root().r(), end.offset) + end.node().r(), end.offset) } // https://dom.spec.whatwg.org/#dom-range-ispointinrangenode-offset - fn IsPointInRange(self, node: JSRef<Node>, offset: u32) -> Fallible<bool> { + fn IsPointInRange(self, node: &Node, offset: u32) -> Fallible<bool> { match self.inner().borrow().compare_point(node, offset) { Ok(Ordering::Less) => Ok(false), Ok(Ordering::Equal) => Ok(true), @@ -237,7 +237,7 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-comparepointnode-offset - fn ComparePoint(self, node: JSRef<Node>, offset: u32) -> Fallible<i16> { + fn ComparePoint(self, node: &Node, offset: u32) -> Fallible<i16> { self.inner().borrow().compare_point(node, offset).map(|order| { match order { Ordering::Less => -1, @@ -248,14 +248,14 @@ impl<'a> RangeMethods for JSRef<'a, Range> { } // https://dom.spec.whatwg.org/#dom-range-intersectsnodenode - fn IntersectsNode(self, node: JSRef<Node>) -> bool { + fn IntersectsNode(self, node: &Node) -> bool { let inner = self.inner().borrow(); let start = &inner.start; - let start_node = start.node().root(); + let start_node = start.node(); let start_offset = start.offset; - let start_node_root = start_node.r().inclusive_ancestors().last().unwrap().root(); - let node_root = node.inclusive_ancestors().last().unwrap().root(); - if start_node_root.r() != node_root.r() { + let start_node_root = start_node.r().inclusive_ancestors().last().unwrap(); + let node_root = node.inclusive_ancestors().last().unwrap(); + if start_node_root != node_root { // Step 1. return false; } @@ -265,11 +265,11 @@ impl<'a> RangeMethods for JSRef<'a, Range> { // Step 3. return true; }, - }.root(); + }; // Step 4. let offset = node.index(); let end = &inner.end; - let end_node = end.node().root(); + let end_node = end.node(); let end_offset = end.offset; match (bp_position(parent.r(), offset + 1, start_node.r(), start_offset).unwrap(), bp_position(parent.r(), offset, end_node.r(), end_offset).unwrap()) { @@ -304,13 +304,13 @@ impl RangeInner { } // https://dom.spec.whatwg.org/#dom-range-commonancestorcontainer - fn common_ancestor_container(&self) -> Temporary<Node> { - let start_container = self.start.node().root(); - let end_container = self.end.node().root(); + fn common_ancestor_container(&self) -> Root<Node> { + let start_container = self.start.node(); + let end_container = self.end.node(); // Step 1. for container in start_container.r().inclusive_ancestors() { // Step 2. - if container.root().r().is_inclusive_ancestor_of(end_container.r()) { + if container.r().is_inclusive_ancestor_of(end_container.r()) { // Step 3. return container; } @@ -319,9 +319,9 @@ impl RangeInner { } // https://dom.spec.whatwg.org/#concept-range-bp-set - pub fn set_start(&mut self, bp_node: JSRef<Node>, bp_offset: u32) { + pub fn set_start(&mut self, bp_node: &Node, bp_offset: u32) { // Steps 1-3 handled in Range caller. - let end_node = self.end.node().root(); + let end_node = self.end.node(); let end_offset = self.end.offset; match bp_position(bp_node, bp_offset, end_node.r(), end_offset) { None | Some(Ordering::Greater) => { @@ -335,9 +335,9 @@ impl RangeInner { } // https://dom.spec.whatwg.org/#concept-range-bp-set - pub fn set_end(&mut self, bp_node: JSRef<Node>, bp_offset: u32) { + pub fn set_end(&mut self, bp_node: &Node, bp_offset: u32) { // Steps 1-3 handled in Range caller. - let start_node = self.start.node().root(); + let start_node = self.start.node(); let start_offset = self.start.offset; match bp_position(bp_node, bp_offset, start_node.r(), start_offset) { None | Some(Ordering::Less) => { @@ -353,18 +353,18 @@ impl RangeInner { // https://dom.spec.whatwg.org/#dom-range-collapsetostart fn collapse(&mut self, to_start: bool) { if to_start { - let start_node = self.start.node().root(); + let start_node = self.start.node(); self.end.set(start_node.r(), self.start.offset); } else { - let end_node = self.end.node().root(); + let end_node = self.end.node(); self.start.set(end_node.r(), self.end.offset); } } // https://dom.spec.whatwg.org/#dom-range-selectnodenode - fn select_node(&mut self, node: JSRef<Node>) -> ErrorResult { + fn select_node(&mut self, node: &Node) -> ErrorResult { // Steps 1, 2. - let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)).root(); + let parent = try!(node.GetParentNode().ok_or(Error::InvalidNodeType)); // Step 3. let index = node.index(); // Step 4. @@ -375,7 +375,7 @@ impl RangeInner { } // https://dom.spec.whatwg.org/#dom-range-selectnodecontentsnode - fn select_node_contents(&mut self, node: JSRef<Node>) -> ErrorResult { + fn select_node_contents(&mut self, node: &Node) -> ErrorResult { if node.is_doctype() { // Step 1. return Err(Error::InvalidNodeType); @@ -390,13 +390,13 @@ impl RangeInner { } // https://dom.spec.whatwg.org/#dom-range-comparepointnode-offset - fn compare_point(&self, node: JSRef<Node>, offset: u32) -> Fallible<Ordering> { + fn compare_point(&self, node: &Node, offset: u32) -> Fallible<Ordering> { let start = &self.start; - let start_node = start.node().root(); + let start_node = start.node(); let start_offset = start.offset; - let start_node_root = start_node.r().inclusive_ancestors().last().unwrap().root(); - let node_root = node.inclusive_ancestors().last().unwrap().root(); - if start_node_root.r() != node_root.r() { + let start_node_root = start_node.r().inclusive_ancestors().last().unwrap(); + let node_root = node.inclusive_ancestors().last().unwrap(); + if start_node_root != node_root { // Step 1. return Err(Error::WrongDocument); } @@ -413,7 +413,7 @@ impl RangeInner { return Ok(Ordering::Less); } let end = &self.end; - let end_node = end.node().root(); + let end_node = end.node(); let end_offset = end.offset; if let Ordering::Greater = bp_position(node, offset, end_node.r(), end_offset).unwrap() { // Step 5. @@ -433,27 +433,27 @@ pub struct BoundaryPoint { } impl BoundaryPoint { - fn new(node: JSRef<Node>, offset: u32) -> BoundaryPoint { + fn new(node: &Node, offset: u32) -> BoundaryPoint { debug_assert!(!node.is_doctype()); debug_assert!(offset <= node.len()); BoundaryPoint { - node: MutHeap::new(JS::from_rooted(node)), + node: MutHeap::new(JS::from_ref(node)), offset: offset, } } - pub fn node(&self) -> Temporary<Node> { - Temporary::from_rooted(self.node.get()) + pub fn node(&self) -> Root<Node> { + self.node.get().root() } pub fn offset(&self) -> u32 { self.offset } - fn set(&mut self, node: JSRef<Node>, offset: u32) { + fn set(&mut self, node: &Node, offset: u32) { debug_assert!(!node.is_doctype()); debug_assert!(offset <= node.len()); - self.node.set(JS::from_rooted(node)); + self.node.set(JS::from_ref(node)); self.offset = offset; } } @@ -461,24 +461,24 @@ impl BoundaryPoint { #[allow(unrooted_must_root)] impl PartialOrd for BoundaryPoint { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - bp_position(self.node().root().r(), self.offset, - other.node().root().r(), other.offset) + bp_position(self.node().r(), self.offset, + other.node().r(), other.offset) } } #[allow(unrooted_must_root)] impl PartialEq for BoundaryPoint { fn eq(&self, other: &Self) -> bool { - self.node().root().r() == other.node().root().r() && + self.node() == other.node() && self.offset == other.offset } } // https://dom.spec.whatwg.org/#concept-range-bp-position -fn bp_position(a_node: JSRef<Node>, a_offset: u32, - b_node: JSRef<Node>, b_offset: u32) +fn bp_position(a_node: &Node, a_offset: u32, + b_node: &Node, b_offset: u32) -> Option<Ordering> { - if a_node == b_node { + if a_node as *const Node == b_node as *const Node { // Step 1. return Some(a_offset.cmp(&b_offset)); } @@ -495,9 +495,9 @@ fn bp_position(a_node: JSRef<Node>, a_offset: u32, } } else if position & NodeConstants::DOCUMENT_POSITION_CONTAINS != 0 { // Step 3-1, 3-2. - let b_ancestors = b_node.inclusive_ancestors(); - let ref child = b_ancestors.map(|child| child.root()).find(|child| { - child.r().GetParentNode().unwrap().root().r() == a_node + let mut b_ancestors = b_node.inclusive_ancestors(); + let ref child = b_ancestors.find(|child| { + child.r().GetParentNode().unwrap().r() == a_node }).unwrap(); // Step 3-3. if child.r().index() < a_offset { diff --git a/components/script/dom/screen.rs b/components/script/dom/screen.rs index a78ec98e994..8c185ae77f1 100644 --- a/components/script/dom/screen.rs +++ b/components/script/dom/screen.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::ScreenBinding; use dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::Window; @@ -21,14 +21,14 @@ impl Screen { } } - pub fn new(window: JSRef<Window>) -> Temporary<Screen> { + pub fn new(window: &Window) -> Root<Screen> { reflect_dom_object(box Screen::new_inherited(), GlobalRef::Window(window), ScreenBinding::Wrap) } } -impl<'a> ScreenMethods for JSRef<'a, Screen> { +impl<'a> ScreenMethods for &'a Screen { fn ColorDepth(self) -> u32 { 24 } diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index 1d69b24c5c8..a7b3031587d 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -10,7 +10,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::ServoHTMLParserBinding; use dom::bindings::global::GlobalRef; use dom::bindings::trace::JSTraceable; -use dom::bindings::js::{JS, JSRef, Rootable, Temporary}; +use dom::bindings::js::{JS, Root}; use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers}; @@ -28,7 +28,7 @@ use encoding::types::{Encoding, DecoderTrap}; use std::cell::{Cell, RefCell}; use std::default::Default; use url::Url; -use js::jsapi::JSTracer; +use js::jsapi::{JSTracer, JSObject}; use html5ever::tokenizer; use html5ever::tree_builder; use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts}; @@ -46,8 +46,8 @@ pub struct Sink { /// into functions. #[derive(Copy, Clone)] pub struct FragmentContext<'a> { - pub context_elem: JSRef<'a, Node>, - pub form_elem: Option<JSRef<'a, Node>>, + pub context_elem: &'a Node, + pub form_elem: Option<&'a Node>, } pub type Tokenizer = tokenizer::Tokenizer<TreeBuilder<JS<Node>, Sink>>; @@ -91,10 +91,10 @@ impl AsyncResponseListener for ParserContext { let parser = match parser { Some(parser) => parser, None => return, - }.root(); + }; let parser = parser.r(); - let win = parser.window().root(); + let win = parser.window(); *self.parser.borrow_mut() = Some(Trusted::new(win.r().get_cx(), parser, self.script_chan.clone())); @@ -128,18 +128,18 @@ impl AsyncResponseListener for ParserContext { // FIXME: use Vec<u8> (html5ever #34) let data = UTF_8.decode(&payload, DecoderTrap::Replace).unwrap(); let parser = match self.parser.borrow().as_ref() { - Some(parser) => parser.to_temporary(), + Some(parser) => parser.root(), None => return, - }.root(); + }; parser.r().parse_chunk(data); } } fn response_complete(&self, status: Result<(), String>) { let parser = match self.parser.borrow().as_ref() { - Some(parser) => parser.to_temporary(), + Some(parser) => parser.root(), None => return, - }.root(); + }; let doc = parser.r().document.root(); doc.r().finish_load(LoadType::PageSource(self.url.clone())); @@ -176,7 +176,7 @@ pub struct ServoHTMLParser { pipeline: Option<PipelineId>, } -impl<'a> Parser for JSRef<'a, ServoHTMLParser> { +impl<'a> Parser for &'a ServoHTMLParser { fn parse_chunk(self, input: String) { self.document.root().r().set_current_parser(Some(self)); self.pending_input.borrow_mut().push(input); @@ -201,12 +201,12 @@ impl<'a> Parser for JSRef<'a, ServoHTMLParser> { impl ServoHTMLParser { #[allow(unrooted_must_root)] - pub fn new(base_url: Option<Url>, document: JSRef<Document>, pipeline: Option<PipelineId>) - -> Temporary<ServoHTMLParser> { - let window = document.window().root(); + pub fn new(base_url: Option<Url>, document: &Document, pipeline: Option<PipelineId>) + -> Root<ServoHTMLParser> { + let window = document.window(); let sink = Sink { base_url: base_url, - document: JS::from_rooted(document), + document: JS::from_ref(document), }; let tb = TreeBuilder::new(sink, TreeBuilderOpts { @@ -220,7 +220,7 @@ impl ServoHTMLParser { reflector_: Reflector::new(), tokenizer: DOMRefCell::new(tok), pending_input: DOMRefCell::new(vec!()), - document: JS::from_rooted(document), + document: JS::from_ref(document), suspended: Cell::new(false), last_chunk_received: Cell::new(false), pipeline: pipeline, @@ -231,12 +231,12 @@ impl ServoHTMLParser { } #[allow(unrooted_must_root)] - pub fn new_for_fragment(base_url: Option<Url>, document: JSRef<Document>, - fragment_context: FragmentContext) -> Temporary<ServoHTMLParser> { - let window = document.window().root(); + pub fn new_for_fragment(base_url: Option<Url>, document: &Document, + fragment_context: FragmentContext) -> Root<ServoHTMLParser> { + let window = document.window(); let sink = Sink { base_url: base_url, - document: JS::from_rooted(document), + document: JS::from_ref(document), }; let tb_opts = TreeBuilderOpts { @@ -244,8 +244,8 @@ impl ServoHTMLParser { .. Default::default() }; let tb = TreeBuilder::new_for_fragment(sink, - JS::from_rooted(fragment_context.context_elem), - fragment_context.form_elem.map(|n| JS::from_rooted(n)), + JS::from_ref(fragment_context.context_elem), + fragment_context.form_elem.map(|n| JS::from_ref(n)), tb_opts); let tok_opts = tokenizer::TokenizerOpts { @@ -258,7 +258,7 @@ impl ServoHTMLParser { reflector_: Reflector::new(), tokenizer: DOMRefCell::new(tok), pending_input: DOMRefCell::new(vec!()), - document: JS::from_rooted(document), + document: JS::from_ref(document), suspended: Cell::new(false), last_chunk_received: Cell::new(true), pipeline: None, @@ -278,6 +278,9 @@ impl Reflectable for ServoHTMLParser { fn reflector<'a>(&'a self) -> &'a Reflector { &self.reflector_ } + fn init_reflector(&mut self, obj: *mut JSObject) { + self.reflector_.set_jsobject(obj); + } } trait PrivateServoHTMLParserHelpers { @@ -285,10 +288,10 @@ trait PrivateServoHTMLParserHelpers { /// the tokenizer runs out of input. fn parse_sync(self); /// Retrieve the window object associated with this parser. - fn window(self) -> Temporary<Window>; + fn window(self) -> Root<Window>; } -impl<'a> PrivateServoHTMLParserHelpers for JSRef<'a, ServoHTMLParser> { +impl<'a> PrivateServoHTMLParserHelpers for &'a ServoHTMLParser { fn parse_sync(self) { let mut first = true; @@ -322,7 +325,7 @@ impl<'a> PrivateServoHTMLParserHelpers for JSRef<'a, ServoHTMLParser> { } } - fn window(self) -> Temporary<Window> { + fn window(self) -> Root<Window> { let doc = self.document.root(); window_from_node(doc.r()) } @@ -337,7 +340,7 @@ pub trait ServoHTMLParserHelpers { fn resume(self); } -impl<'a> ServoHTMLParserHelpers for JSRef<'a, ServoHTMLParser> { +impl<'a> ServoHTMLParserHelpers for &'a ServoHTMLParser { fn suspend(self) { assert!(!self.suspended.get()); self.suspended.set(true); diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 0e47e73fd90..42c564d9e2c 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -5,12 +5,11 @@ use dom::bindings::codegen::Bindings::StorageBinding; use dom::bindings::codegen::Bindings::StorageBinding::StorageMethods; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JSRef, Temporary, Rootable, RootedReference}; +use dom::bindings::js::{Root, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; -use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable}; -use dom::eventtarget::{EventTarget}; +use dom::event::{EventHelpers, EventBubbles, EventCancelable}; use dom::storageevent::StorageEvent; use dom::urlhelper::UrlHelper; use dom::window::WindowHelpers; @@ -39,7 +38,7 @@ impl Storage { } } - pub fn new(global: &GlobalRef, storage_type: StorageType) -> Temporary<Storage> { + pub fn new(global: &GlobalRef, storage_type: StorageType) -> Root<Storage> { reflect_dom_object(box Storage::new_inherited(global, storage_type), *global, StorageBinding::Wrap) } @@ -57,7 +56,7 @@ impl Storage { } -impl<'a> StorageMethods for JSRef<'a, Storage> { +impl<'a> StorageMethods for &'a Storage { fn Length(self) -> u32 { let (sender, receiver) = channel(); @@ -134,7 +133,7 @@ trait PrivateStorageHelpers { new_value: Option<DOMString>); } -impl<'a> PrivateStorageHelpers for JSRef<'a, Storage> { +impl<'a> PrivateStorageHelpers for &'a Storage { /// https://html.spec.whatwg.org/multipage/#send-a-storage-notification fn broadcast_change_notification(self, key: Option<DOMString>, old_value: Option<DOMString>, new_value: Option<DOMString>){ @@ -166,7 +165,7 @@ impl StorageEventRunnable { impl MainThreadRunnable for StorageEventRunnable { fn handler(self: Box<StorageEventRunnable>, script_task: &ScriptTask) { let this = *self; - let storage_root = this.element.to_temporary().root(); + let storage_root = this.element.root(); let storage = storage_root.r(); let global_root = storage.global.root(); let global_ref = global_root.r(); @@ -180,18 +179,18 @@ impl MainThreadRunnable for StorageEventRunnable { this.key, this.old_value, this.new_value, ev_url.to_string(), Some(storage) - ).root(); - let event: JSRef<Event> = EventCast::from_ref(storage_event.r()); + ); + let event = EventCast::from_ref(storage_event.r()); let root_page = script_task.root_page(); for it_page in root_page.iter() { - let it_window_root = it_page.window().root(); + let it_window_root = it_page.window(); let it_window = it_window_root.r(); assert!(UrlHelper::SameOrigin(&ev_url, &it_window.get_url())); // TODO: Such a Document object is not necessarily fully active, but events fired on such // objects are ignored by the event loop until the Document becomes fully active again. if ev_window.pipeline() != it_window.pipeline() { - let target: JSRef<EventTarget> = EventTargetCast::from_ref(it_window); + let target = EventTargetCast::from_ref(it_window); event.fire(target); } } diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs index e6de4b0575a..55cf51ed097 100644 --- a/components/script/dom/storageevent.rs +++ b/components/script/dom/storageevent.rs @@ -10,8 +10,7 @@ use dom::bindings::codegen::Bindings::StorageEventBinding::{StorageEventMethods} use dom::bindings::codegen::InheritTypes::{EventCast}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, RootedReference}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::utils::{reflect_dom_object}; use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable}; use dom::storage::Storage; @@ -34,14 +33,14 @@ impl StorageEvent { oldValue: Option<DOMString>, newValue: Option<DOMString>, url: DOMString, - storageArea: Option<JSRef<Storage>>) -> StorageEvent { + storageArea: Option<&Storage>) -> StorageEvent { StorageEvent { event: Event::new_inherited(type_id), key: DOMRefCell::new(key), oldValue: DOMRefCell::new(oldValue), newValue: DOMRefCell::new(newValue), url: DOMRefCell::new(url), - storageArea: MutNullableHeap::new(storageArea.map(JS::from_rooted)) + storageArea: MutNullableHeap::new(storageArea.map(JS::from_ref)) } } @@ -53,20 +52,22 @@ impl StorageEvent { oldValue: Option<DOMString>, newValue: Option<DOMString>, url: DOMString, - storageArea: Option<JSRef<Storage>>) -> Temporary<StorageEvent> { + storageArea: Option<&Storage>) -> Root<StorageEvent> { let ev = reflect_dom_object(box StorageEvent::new_inherited(EventTypeId::StorageEvent, key, oldValue, newValue, url, storageArea), global, - StorageEventBinding::Wrap).root(); - let event: JSRef<Event> = EventCast::from_ref(ev.r()); - event.InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable); - Temporary::from_rooted(ev.r()) + StorageEventBinding::Wrap); + { + let event = EventCast::from_ref(ev.r()); + event.InitEvent(type_, bubbles == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable); + } + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &StorageEventBinding::StorageEventInit) -> Fallible<Temporary<StorageEvent>> { + init: &StorageEventBinding::StorageEventInit) -> Fallible<Root<StorageEvent>> { let key = init.key.clone(); let oldValue = init.oldValue.clone(); let newValue = init.newValue.clone(); @@ -86,7 +87,7 @@ impl StorageEvent { } } -impl<'a> StorageEventMethods for JSRef<'a, StorageEvent> { +impl<'a> StorageEventMethods for &'a StorageEvent { fn GetKey(self) -> Option<DOMString> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let key = self.key.borrow(); @@ -111,8 +112,8 @@ impl<'a> StorageEventMethods for JSRef<'a, StorageEvent> { url.clone() } - fn GetStorageArea(self) -> Option<Temporary<Storage>> { - self.storageArea.get().map(Temporary::from_rooted) + fn GetStorageArea(self) -> Option<Root<Storage>> { + self.storageArea.get().map(Root::from_rooted) } } diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index c0379d6eac7..563fe59f280 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -13,18 +13,19 @@ use dom::bindings::codegen::UnionTypes::EventOrString::eString; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong::eLong; use dom::bindings::global::{GlobalField, GlobalRef}; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::str::{ByteString, USVString}; use dom::bindings::utils::Reflector; use dom::blob::Blob; use util::str::DOMString; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::{JSContext, JSObject, HandleValue}; use js::jsval::{JSVal, NullValue}; use std::borrow::ToOwned; use std::ptr; +use std::rc::Rc; #[dom_struct] pub struct TestBinding { @@ -32,7 +33,7 @@ pub struct TestBinding { global: GlobalField, } -impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { +impl<'a> TestBindingMethods for &'a TestBinding { fn BooleanAttribute(self) -> bool { false } fn SetBooleanAttribute(self, _: bool) {} fn ByteAttribute(self) -> i8 { 0 } @@ -67,18 +68,18 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn SetByteStringAttribute(self, _: ByteString) {} fn EnumAttribute(self) -> TestEnum { _empty } fn SetEnumAttribute(self, _: TestEnum) {} - fn InterfaceAttribute(self) -> Temporary<Blob> { + fn InterfaceAttribute(self) -> Root<Blob> { let global = self.global.root(); Blob::new(global.r(), None, "") } - fn SetInterfaceAttribute(self, _: JSRef<Blob>) {} + fn SetInterfaceAttribute(self, _: &Blob) {} fn UnionAttribute(self) -> HTMLElementOrLong { eLong(0) } fn SetUnionAttribute(self, _: HTMLElementOrLong) {} fn Union2Attribute(self) -> EventOrString { eString("".to_owned()) } fn SetUnion2Attribute(self, _: EventOrString) {} fn ArrayAttribute(self, _: *mut JSContext) -> *mut JSObject { NullValue().to_object_or_null() } fn AnyAttribute(self, _: *mut JSContext) -> JSVal { NullValue() } - fn SetAnyAttribute(self, _: *mut JSContext, _: JSVal) {} + fn SetAnyAttribute(self, _: *mut JSContext, _: HandleValue) {} fn ObjectAttribute(self, _: *mut JSContext) -> *mut JSObject { panic!() } fn SetObjectAttribute(self, _: *mut JSContext, _: *mut JSObject) {} @@ -115,14 +116,14 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn GetUsvstringAttributeNullable(self) -> Option<USVString> { Some(USVString("".to_owned())) } fn SetUsvstringAttributeNullable(self, _: Option<USVString>) {} fn SetBinaryRenamedAttribute(self, _: DOMString) {} - fn ForwardedAttribute(self) -> Temporary<TestBinding> { Temporary::from_rooted(self) } + fn ForwardedAttribute(self) -> Root<TestBinding> { Root::from_ref(self) } fn BinaryRenamedAttribute(self) -> DOMString { "".to_owned() } fn GetEnumAttributeNullable(self) -> Option<TestEnum> { Some(_empty) } - fn GetInterfaceAttributeNullable(self) -> Option<Temporary<Blob>> { + fn GetInterfaceAttributeNullable(self) -> Option<Root<Blob>> { let global = self.global.root(); Some(Blob::new(global.r(), None, "")) } - fn SetInterfaceAttributeNullable(self, _: Option<JSRef<Blob>>) {} + fn SetInterfaceAttributeNullable(self, _: Option<&Blob>) {} fn GetObjectAttributeNullable(self, _: *mut JSContext) -> *mut JSObject { ptr::null_mut() } fn SetObjectAttributeNullable(self, _: *mut JSContext, _: *mut JSObject) {} fn GetUnionAttributeNullable(self) -> Option<HTMLElementOrLong> { Some(eLong(0)) } @@ -148,7 +149,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveUsvstring(self) -> USVString { USVString("".to_owned()) } fn ReceiveByteString(self) -> ByteString { ByteString::new(vec!()) } fn ReceiveEnum(self) -> TestEnum { _empty } - fn ReceiveInterface(self) -> Temporary<Blob> { + fn ReceiveInterface(self) -> Root<Blob> { let global = self.global.root(); Blob::new(global.r(), None, "") } @@ -174,7 +175,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn ReceiveNullableUsvstring(self) -> Option<USVString> { Some(USVString("".to_owned())) } fn ReceiveNullableByteString(self) -> Option<ByteString> { Some(ByteString::new(vec!())) } fn ReceiveNullableEnum(self) -> Option<TestEnum> { Some(_empty) } - fn ReceiveNullableInterface(self) -> Option<Temporary<Blob>> { + fn ReceiveNullableInterface(self) -> Option<Root<Blob>> { let global = self.global.root(); Some(Blob::new(global.r(), None, "")) } @@ -199,14 +200,14 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassUsvstring(self, _: USVString) {} fn PassByteString(self, _: ByteString) {} fn PassEnum(self, _: TestEnum) {} - fn PassInterface(self, _: JSRef<Blob>) {} + fn PassInterface(self, _: &Blob) {} fn PassUnion(self, _: HTMLElementOrLong) {} fn PassUnion2(self, _: EventOrString) {} fn PassUnion3(self, _: BlobOrString) {} - fn PassAny(self, _: *mut JSContext, _: JSVal) {} + fn PassAny(self, _: *mut JSContext, _: HandleValue) {} fn PassObject(self, _: *mut JSContext, _: *mut JSObject) {} - fn PassCallbackFunction(self, _: Function) {} - fn PassCallbackInterface(self, _: EventListener) {} + fn PassCallbackFunction(self, _: Rc<Function>) {} + fn PassCallbackInterface(self, _: Rc<EventListener>) {} fn PassNullableBoolean(self, _: Option<bool>) {} fn PassNullableByte(self, _: Option<i8>) {} @@ -225,12 +226,12 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassNullableUsvstring(self, _: Option<USVString>) {} fn PassNullableByteString(self, _: Option<ByteString>) {} // fn PassNullableEnum(self, _: Option<TestEnum>) {} - fn PassNullableInterface(self, _: Option<JSRef<Blob>>) {} + fn PassNullableInterface(self, _: Option<&Blob>) {} fn PassNullableObject(self, _: *mut JSContext, _: *mut JSObject) {} fn PassNullableUnion(self, _: Option<HTMLElementOrLong>) {} fn PassNullableUnion2(self, _: Option<EventOrString>) {} - fn PassNullableCallbackFunction(self, _: Option<Function>) {} - fn PassNullableCallbackInterface(self, _: Option<EventListener>) {} + fn PassNullableCallbackFunction(self, _: Option<Rc<Function>>) {} + fn PassNullableCallbackInterface(self, _: Option<Rc<EventListener>>) {} fn PassOptionalBoolean(self, _: Option<bool>) {} fn PassOptionalByte(self, _: Option<i8>) {} @@ -249,13 +250,13 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalUsvstring(self, _: Option<USVString>) {} fn PassOptionalByteString(self, _: Option<ByteString>) {} fn PassOptionalEnum(self, _: Option<TestEnum>) {} - fn PassOptionalInterface(self, _: Option<JSRef<Blob>>) {} + fn PassOptionalInterface(self, _: Option<&Blob>) {} fn PassOptionalUnion(self, _: Option<HTMLElementOrLong>) {} fn PassOptionalUnion2(self, _: Option<EventOrString>) {} - fn PassOptionalAny(self, _: *mut JSContext, _: JSVal) {} + fn PassOptionalAny(self, _: *mut JSContext, _: HandleValue) {} fn PassOptionalObject(self, _: *mut JSContext, _: Option<*mut JSObject>) {} - fn PassOptionalCallbackFunction(self, _: Option<Function>) {} - fn PassOptionalCallbackInterface(self, _: Option<EventListener>) {} + fn PassOptionalCallbackFunction(self, _: Option<Rc<Function>>) {} + fn PassOptionalCallbackInterface(self, _: Option<Rc<EventListener>>) {} fn PassOptionalNullableBoolean(self, _: Option<Option<bool>>) {} fn PassOptionalNullableByte(self, _: Option<Option<i8>>) {} @@ -274,12 +275,12 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalNullableUsvstring(self, _: Option<Option<USVString>>) {} fn PassOptionalNullableByteString(self, _: Option<Option<ByteString>>) {} // fn PassOptionalNullableEnum(self, _: Option<Option<TestEnum>>) {} - fn PassOptionalNullableInterface(self, _: Option<Option<JSRef<Blob>>>) {} + fn PassOptionalNullableInterface(self, _: Option<Option<&Blob>>) {} fn PassOptionalNullableObject(self, _: *mut JSContext, _: Option<*mut JSObject>) {} fn PassOptionalNullableUnion(self, _: Option<Option<HTMLElementOrLong>>) {} fn PassOptionalNullableUnion2(self, _: Option<Option<EventOrString>>) {} - fn PassOptionalNullableCallbackFunction(self, _: Option<Option<Function>>) {} - fn PassOptionalNullableCallbackInterface(self, _: Option<Option<EventListener>>) {} + fn PassOptionalNullableCallbackFunction(self, _: Option<Option<Rc<Function>>>) {} + fn PassOptionalNullableCallbackInterface(self, _: Option<Option<Rc<EventListener>>>) {} fn PassOptionalBooleanWithDefault(self, _: bool) {} fn PassOptionalByteWithDefault(self, _: i8) {} @@ -311,13 +312,13 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassOptionalNullableUsvstringWithDefault(self, _: Option<USVString>) {} fn PassOptionalNullableByteStringWithDefault(self, _: Option<ByteString>) {} // fn PassOptionalNullableEnumWithDefault(self, _: Option<TestEnum>) {} - fn PassOptionalNullableInterfaceWithDefault(self, _: Option<JSRef<Blob>>) {} + fn PassOptionalNullableInterfaceWithDefault(self, _: Option<&Blob>) {} fn PassOptionalNullableObjectWithDefault(self, _: *mut JSContext, _: *mut JSObject) {} fn PassOptionalNullableUnionWithDefault(self, _: Option<HTMLElementOrLong>) {} fn PassOptionalNullableUnion2WithDefault(self, _: Option<EventOrString>) {} // fn PassOptionalNullableCallbackFunctionWithDefault(self, _: Option<Function>) {} - fn PassOptionalNullableCallbackInterfaceWithDefault(self, _: Option<EventListener>) {} - fn PassOptionalAnyWithDefault(self, _: *mut JSContext, _: JSVal) {} + fn PassOptionalNullableCallbackInterfaceWithDefault(self, _: Option<Rc<EventListener>>) {} + fn PassOptionalAnyWithDefault(self, _: *mut JSContext, _: HandleValue) {} fn PassOptionalNullableBooleanWithNonNullDefault(self, _: Option<bool>) {} fn PassOptionalNullableByteWithNonNullDefault(self, _: Option<i8>) {} @@ -353,11 +354,11 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> { fn PassVariadicUsvstring(self, _: Vec<USVString>) {} fn PassVariadicByteString(self, _: Vec<ByteString>) {} fn PassVariadicEnum(self, _: Vec<TestEnum>) {} - // fn PassVariadicInterface(self, _: Vec<JSRef<Blob>>) {} + // fn PassVariadicInterface(self, _: Vec<&Blob>) {} fn PassVariadicUnion(self, _: Vec<HTMLElementOrLong>) {} fn PassVariadicUnion2(self, _: Vec<EventOrString>) {} fn PassVariadicUnion3(self, _: Vec<BlobOrString>) {} - fn PassVariadicAny(self, _: *mut JSContext, _: Vec<JSVal>) {} + fn PassVariadicAny(self, _: *mut JSContext, _: Vec<HandleValue>) {} fn PassVariadicObject(self, _: *mut JSContext, _: Vec<*mut JSObject>) {} } diff --git a/components/script/dom/testbindingproxy.rs b/components/script/dom/testbindingproxy.rs index 39682a15496..52fb04cd3d3 100644 --- a/components/script/dom/testbindingproxy.rs +++ b/components/script/dom/testbindingproxy.rs @@ -2,7 +2,6 @@ * 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::codegen::Bindings::TestBindingProxyBinding::TestBindingProxyMethods; - use dom::bindings::js::JSRef; use dom::bindings::utils::Reflector; use util::str::DOMString; @@ -12,7 +11,7 @@ reflector_: Reflector } - impl<'a> TestBindingProxyMethods for JSRef<'a, TestBindingProxy> { + impl<'a> TestBindingProxyMethods for &'a TestBindingProxy { fn GetNamedItem(self, _: DOMString) -> DOMString {"".to_owned()} fn SetNamedItem(self, _: DOMString, _: DOMString) -> () {} diff --git a/components/script/dom/text.rs b/components/script/dom/text.rs index 217f1e1bca1..acc0f304bf2 100644 --- a/components/script/dom/text.rs +++ b/components/script/dom/text.rs @@ -11,8 +11,8 @@ use dom::bindings::codegen::InheritTypes::{CharacterDataCast, TextDerived}; use dom::bindings::codegen::InheritTypes::NodeCast; use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, RootedReference}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{RootedReference}; +use dom::bindings::js::Root; use dom::characterdata::{CharacterData, CharacterDataHelpers, CharacterDataTypeId}; use dom::document::Document; use dom::eventtarget::{EventTarget, EventTargetTypeId}; @@ -32,26 +32,26 @@ impl TextDerived for EventTarget { } impl Text { - fn new_inherited(text: DOMString, document: JSRef<Document>) -> Text { + fn new_inherited(text: DOMString, document: &Document) -> Text { Text { characterdata: CharacterData::new_inherited(CharacterDataTypeId::Text, text, document) } } - pub fn new(text: DOMString, document: JSRef<Document>) -> Temporary<Text> { + pub fn new(text: DOMString, document: &Document) -> Root<Text> { Node::reflect_node(box Text::new_inherited(text, document), document, TextBinding::Wrap) } - pub fn Constructor(global: GlobalRef, text: DOMString) -> Fallible<Temporary<Text>> { - let document = global.as_window().Document().root(); + pub fn Constructor(global: GlobalRef, text: DOMString) -> Fallible<Root<Text>> { + let document = global.as_window().Document(); Ok(Text::new(text, document.r())) } } -impl<'a> TextMethods for JSRef<'a, Text> { +impl<'a> TextMethods for &'a Text { // https://dom.spec.whatwg.org/#dom-text-splittextoffset - fn SplitText(self, offset: u32) -> Fallible<Temporary<Text>> { + fn SplitText(self, offset: u32) -> Fallible<Root<Text>> { let cdata = CharacterDataCast::from_ref(self); // Step 1. let length = cdata.Length(); @@ -65,14 +65,14 @@ impl<'a> TextMethods for JSRef<'a, Text> { let new_data = cdata.SubstringData(offset, count).unwrap(); // Step 5. let node = NodeCast::from_ref(self); - let owner_doc = node.owner_doc().root(); - let new_node = owner_doc.r().CreateTextNode(new_data).root(); + let owner_doc = node.owner_doc(); + let new_node = owner_doc.r().CreateTextNode(new_data); // Step 6. - let parent = node.GetParentNode().root(); + let parent = node.GetParentNode(); if let Some(ref parent) = parent { // Step 7. parent.r().InsertBefore(NodeCast::from_ref(new_node.r()), - node.GetNextSibling().root().r()) + node.GetNextSibling().r()) .unwrap(); // TODO: Ranges. } @@ -83,16 +83,15 @@ impl<'a> TextMethods for JSRef<'a, Text> { // TODO: Ranges } // Step 10. - Ok(Temporary::from_rooted(new_node.r())) + Ok(new_node) } // https://dom.spec.whatwg.org/#dom-text-wholetext fn WholeText(self) -> DOMString { let first = NodeCast::from_ref(self).inclusively_preceding_siblings() - .map(|node| node.root()) .take_while(|node| node.r().is_text()) .last().unwrap(); - let nodes = first.r().inclusively_following_siblings().map(|node| node.root()) + let nodes = first.r().inclusively_following_siblings() .take_while(|node| node.r().is_text()); let mut text = DOMString::new(); for ref node in nodes { diff --git a/components/script/dom/textdecoder.rs b/components/script/dom/textdecoder.rs index 4b3333234a3..308ca30527c 100644 --- a/components/script/dom/textdecoder.rs +++ b/components/script/dom/textdecoder.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::TextDecoderBinding; use dom::bindings::codegen::Bindings::TextDecoderBinding::TextDecoderMethods; use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::str::USVString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -17,7 +17,7 @@ use encoding::Encoding; use encoding::types::{EncodingRef, DecoderTrap}; use encoding::label::encoding_from_whatwg_label; use js::jsapi::{JSContext, JSObject}; -use js::jsfriendapi::bindgen::JS_GetObjectAsArrayBufferView; +use js::jsapi::JS_GetObjectAsArrayBufferView; use std::borrow::ToOwned; use std::ptr; @@ -39,11 +39,11 @@ impl TextDecoder { } } - fn make_range_error() -> Fallible<Temporary<TextDecoder>> { + fn make_range_error() -> Fallible<Root<TextDecoder>> { Err(Error::Range("The given encoding is not supported.".to_owned())) } - pub fn new(global: GlobalRef, encoding: EncodingRef, fatal: bool) -> Temporary<TextDecoder> { + pub fn new(global: GlobalRef, encoding: EncodingRef, fatal: bool) -> Root<TextDecoder> { reflect_dom_object(box TextDecoder::new_inherited(encoding, fatal), global, TextDecoderBinding::Wrap) @@ -53,7 +53,7 @@ impl TextDecoder { pub fn Constructor(global: GlobalRef, label: DOMString, options: &TextDecoderBinding::TextDecoderOptions) - -> Fallible<Temporary<TextDecoder>> { + -> Fallible<Root<TextDecoder>> { let encoding = match encoding_from_whatwg_label(&label) { None => return TextDecoder::make_range_error(), Some(enc) => enc @@ -72,7 +72,7 @@ impl TextDecoder { } -impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> { +impl<'a> TextDecoderMethods for &'a TextDecoder { fn Encoding(self) -> DOMString { self.encoding.whatwg_name().unwrap().to_owned() } @@ -82,7 +82,7 @@ impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> { } #[allow(unsafe_code)] - fn Decode(self, cx: *mut JSContext, input: Option<*mut JSObject>) + fn Decode(self, _cx: *mut JSContext, input: Option<*mut JSObject>) -> Fallible<USVString> { let input = match input { Some(input) => input, @@ -91,7 +91,7 @@ impl<'a> TextDecoderMethods for JSRef<'a, TextDecoder> { let mut length = 0; let mut data = ptr::null_mut(); - if unsafe { JS_GetObjectAsArrayBufferView(cx, input, &mut length, &mut data).is_null() } { + if unsafe { JS_GetObjectAsArrayBufferView(input, &mut length, &mut data).is_null() } { return Err(Error::Type("Argument to TextDecoder.decode is not an ArrayBufferView".to_owned())); } diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs index 09aeb01c5e4..9ca40bbd7a0 100644 --- a/components/script/dom/textencoder.rs +++ b/components/script/dom/textencoder.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::TextEncoderBinding::TextEncoderMethods; use dom::bindings::global::GlobalRef; use dom::bindings::error::Fallible; use dom::bindings::error::Error::Range; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::str::USVString; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -22,7 +22,7 @@ use encoding::label::encoding_from_whatwg_label; use libc::uint8_t; use js::jsapi::{JSContext, JSObject}; -use js::jsfriendapi::bindgen::{JS_NewUint8Array, JS_GetUint8ArrayData}; +use js::jsapi::{JS_NewUint8Array, JS_GetUint8ArrayData}; #[dom_struct] pub struct TextEncoder { @@ -40,7 +40,7 @@ impl TextEncoder { } } - pub fn new(global: GlobalRef, encoding: DOMString, encoder: EncodingRef) -> Temporary<TextEncoder> { + pub fn new(global: GlobalRef, encoding: DOMString, encoder: EncodingRef) -> Root<TextEncoder> { reflect_dom_object(box TextEncoder::new_inherited(encoding, encoder), global, TextEncoderBinding::Wrap) @@ -48,7 +48,7 @@ impl TextEncoder { // https://encoding.spec.whatwg.org/#dom-textencoder pub fn Constructor(global: GlobalRef, - label: DOMString) -> Fallible<Temporary<TextEncoder>> { + label: DOMString) -> Fallible<Root<TextEncoder>> { let encoding = match encoding_from_whatwg_label(&label) { Some(enc) => enc, None => { @@ -69,7 +69,7 @@ impl TextEncoder { } } -impl<'a> TextEncoderMethods for JSRef<'a, TextEncoder> { +impl<'a> TextEncoderMethods for &'a TextEncoder { // https://encoding.spec.whatwg.org/#dom-textencoder-encoding fn Encoding(self) -> DOMString { self.encoding.clone() @@ -83,7 +83,7 @@ impl<'a> TextEncoderMethods for JSRef<'a, TextEncoder> { let length = encoded.len() as u32; let js_object: *mut JSObject = JS_NewUint8Array(cx, length); - let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object, cx); + let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object, ptr::null()); ptr::copy_nonoverlapping(encoded.as_ptr(), js_object_data, length as usize); return js_object; } diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index 237bbfb892d..a85530df31e 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -10,11 +10,12 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter; use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutHeap, OptionalRootable, Rootable}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{JS, MutHeap}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::document::{Document, DocumentHelpers}; use dom::node::Node; +use std::rc::Rc; // https://dom.spec.whatwg.org/#interface-treewalker #[dom_struct] @@ -27,32 +28,32 @@ pub struct TreeWalker { } impl TreeWalker { - fn new_inherited(root_node: JSRef<Node>, + fn new_inherited(root_node: &Node, what_to_show: u32, filter: Filter) -> TreeWalker { TreeWalker { reflector_: Reflector::new(), - root_node: JS::from_rooted(root_node), - current_node: MutHeap::new(JS::from_rooted(root_node)), + root_node: JS::from_ref(root_node), + current_node: MutHeap::new(JS::from_ref(root_node)), what_to_show: what_to_show, filter: filter } } - pub fn new_with_filter(document: JSRef<Document>, - root_node: JSRef<Node>, + pub fn new_with_filter(document: &Document, + root_node: &Node, what_to_show: u32, - filter: Filter) -> Temporary<TreeWalker> { - let window = document.window().root(); + filter: Filter) -> Root<TreeWalker> { + let window = document.window(); reflect_dom_object(box TreeWalker::new_inherited(root_node, what_to_show, filter), GlobalRef::Window(window.r()), TreeWalkerBinding::Wrap) } - pub fn new(document: JSRef<Document>, - root_node: JSRef<Node>, + pub fn new(document: &Document, + root_node: &Node, what_to_show: u32, - node_filter: Option<NodeFilter>) -> Temporary<TreeWalker> { + node_filter: Option<Rc<NodeFilter>>) -> Root<TreeWalker> { let filter = match node_filter { None => Filter::None, Some(jsfilter) => Filter::JS(jsfilter) @@ -61,10 +62,10 @@ impl TreeWalker { } } -impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { +impl<'a> TreeWalkerMethods for &'a TreeWalker { // https://dom.spec.whatwg.org/#dom-treewalker-root - fn Root(self) -> Temporary<Node> { - Temporary::from_rooted(self.root_node) + fn Root(self) -> Root<Node> { + self.root_node.root() } // https://dom.spec.whatwg.org/#dom-treewalker-whattoshow @@ -73,40 +74,40 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } // https://dom.spec.whatwg.org/#dom-treewalker-filter - fn GetFilter(self) -> Option<NodeFilter> { + fn GetFilter(self) -> Option<Rc<NodeFilter>> { match self.filter { Filter::None => None, - Filter::JS(nf) => Some(nf), + Filter::JS(ref nf) => Some(nf.clone()), Filter::Native(_) => panic!("Cannot convert native node filter to DOM NodeFilter") } } // https://dom.spec.whatwg.org/#dom-treewalker-currentnode - fn CurrentNode(self) -> Temporary<Node> { - Temporary::from_rooted(self.current_node.get()) + fn CurrentNode(self) -> Root<Node> { + self.current_node.get().root() } // https://dom.spec.whatwg.org/#dom-treewalker-currentnode - fn SetCurrentNode(self, node: JSRef<Node>) { - self.current_node.set(JS::from_rooted(node)); + fn SetCurrentNode(self, node: &Node) { + self.current_node.set(JS::from_ref(node)); } // https://dom.spec.whatwg.org/#dom-treewalker-parentnode - fn ParentNode(self) -> Fallible<Option<Temporary<Node>>> { + fn ParentNode(self) -> Fallible<Option<Root<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().get_unsound_ref_forever(); + let mut node = self.current_node.get().root(); // "2. While node is not null and is not root, run these substeps:" - while !self.is_root_node(node) { + while !self.is_root_node(node.r()) { // "1. Let node be node's parent." match node.GetParentNode() { Some(n) => { - node = n.root().get_unsound_ref_forever(); + node = n; // "2. If node is not null and filtering node returns FILTER_ACCEPT, // then set the currentNode attribute to node, return node." - match try!(self.accept_node(node)) { + match try!(self.accept_node(node.r())) { NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => {} } @@ -119,45 +120,45 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } // https://dom.spec.whatwg.org/#dom-treewalker-firstchild - fn FirstChild(self) -> Fallible<Option<Temporary<Node>>> { + fn FirstChild(self) -> Fallible<Option<Root<Node>>> { // "The firstChild() method must traverse children of type first." self.traverse_children(|node| node.GetFirstChild(), |node| node.GetNextSibling()) } // https://dom.spec.whatwg.org/#dom-treewalker-lastchild - fn LastChild(self) -> Fallible<Option<Temporary<Node>>> { + fn LastChild(self) -> Fallible<Option<Root<Node>>> { // "The lastChild() method must traverse children of type last." self.traverse_children(|node| node.GetLastChild(), |node| node.GetPreviousSibling()) } // https://dom.spec.whatwg.org/#dom-treewalker-previoussibling - fn PreviousSibling(self) -> Fallible<Option<Temporary<Node>>> { + fn PreviousSibling(self) -> Fallible<Option<Root<Node>>> { // "The nextSibling() method must traverse siblings of type next." self.traverse_siblings(|node| node.GetLastChild(), |node| node.GetPreviousSibling()) } // https://dom.spec.whatwg.org/#dom-treewalker-nextsibling - fn NextSibling(self) -> Fallible<Option<Temporary<Node>>> { + fn NextSibling(self) -> Fallible<Option<Root<Node>>> { // "The previousSibling() method must traverse siblings of type previous." self.traverse_siblings(|node| node.GetFirstChild(), |node| node.GetNextSibling()) } // https://dom.spec.whatwg.org/#dom-treewalker-previousnode - fn PreviousNode(self) -> Fallible<Option<Temporary<Node>>> { + fn PreviousNode(self) -> Fallible<Option<Root<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().get_unsound_ref_forever(); + let mut node = self.current_node.get().root(); // "2. While node is not root, run these substeps:" - while !self.is_root_node(node) { + while !self.is_root_node(node.r()) { // "1. Let sibling be the previous sibling of node." - let mut sibling_op = node.GetPreviousSibling(); + let mut sibling_op = node.r().GetPreviousSibling(); // "2. While sibling is not null, run these subsubsteps:" while sibling_op.is_some() { // "1. Set node to sibling." - node = sibling_op.unwrap().root().get_unsound_ref_forever(); + node = sibling_op.unwrap(); // "2. Filter node and let result be the return value." // "3. While result is not FILTER_REJECT and node has a child, // set node to its last child and then filter node and @@ -165,15 +166,14 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { // "4. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." loop { - let result = try!(self.accept_node(node)); + let result = try!(self.accept_node(node.r())); match result { NodeFilterConstants::FILTER_REJECT => break, _ if node.GetFirstChild().is_some() => - node = node.GetLastChild().unwrap().root() - .get_unsound_ref_forever(), + node = node.GetLastChild().unwrap(), NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => break } @@ -182,23 +182,23 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { sibling_op = node.GetPreviousSibling() } // "3. If node is root or node's parent is null, return null." - if self.is_root_node(node) || node.GetParentNode().is_none() { + if self.is_root_node(node.r()) || node.GetParentNode().is_none() { return Ok(None) } // "4. Set node to its parent." - match node.GetParentNode() { + match node.r().GetParentNode() { None => // This can happen if the user set the current node to somewhere // outside of the tree rooted at the original root. return Ok(None), - Some(n) => node = n.root().get_unsound_ref_forever() + Some(n) => node = n } // "5. Filter node and if the return value is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." - match try!(self.accept_node(node)) { + match try!(self.accept_node(node.r())) { NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => {} } @@ -208,9 +208,9 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } // https://dom.spec.whatwg.org/#dom-treewalker-nextnode - fn NextNode(self) -> Fallible<Option<Temporary<Node>>> { + fn NextNode(self) -> Fallible<Option<Root<Node>>> { // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().get_unsound_ref_forever(); + let mut node = self.current_node.get().root(); // "2. Let result be FILTER_ACCEPT." let mut result = NodeFilterConstants::FILTER_ACCEPT; // "3. Run these substeps:" @@ -221,19 +221,19 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { NodeFilterConstants::FILTER_REJECT => break, _ => {} } - match node.GetFirstChild() { + match node.r().GetFirstChild() { None => break, Some (child) => { // "1. Set node to its first child." - node = child.root().get_unsound_ref_forever(); + node = child; // "2. Filter node and set result to the return value." - result = try!(self.accept_node(node)); + result = try!(self.accept_node(node.r())); // "3. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." match result { NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => {} } @@ -243,18 +243,18 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { // "2. If a node is following node and is not following root, // set node to the first such node." // "Otherwise, return null." - match self.first_following_node_not_following_root(node) { + match self.first_following_node_not_following_root(node.r()) { None => return Ok(None), Some(n) => { - node = n.root().get_unsound_ref_forever(); + node = n; // "3. Filter node and set result to the return value." - result = try!(self.accept_node(node)); + result = try!(self.accept_node(node.r())); // "4. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." match result { NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => {} } @@ -265,102 +265,95 @@ impl<'a> TreeWalkerMethods for JSRef<'a, TreeWalker> { } } -type NodeAdvancer<'a> = Fn(JSRef<'a, Node>) -> Option<Temporary<Node>> + 'a; +type NodeAdvancer<'a> = Fn(&Node) -> Option<Root<Node>> + 'a; trait PrivateTreeWalkerHelpers { fn traverse_children<F, G>(self, next_child: F, next_sibling: G) - -> Fallible<Option<Temporary<Node>>> - where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, - G: Fn(JSRef<Node>) -> Option<Temporary<Node>>; + -> Fallible<Option<Root<Node>>> + where F: Fn(&Node) -> Option<Root<Node>>, + G: Fn(&Node) -> Option<Root<Node>>; fn traverse_siblings<F, G>(self, next_child: F, next_sibling: G) - -> Fallible<Option<Temporary<Node>>> - where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, - G: Fn(JSRef<Node>) -> Option<Temporary<Node>>; - fn is_root_node(self, node: JSRef<Node>) -> bool; - fn is_current_node(self, node: JSRef<Node>) -> bool; - fn first_following_node_not_following_root(self, node: JSRef<Node>) - -> Option<Temporary<Node>>; - fn accept_node(self, node: JSRef<Node>) -> Fallible<u16>; + -> Fallible<Option<Root<Node>>> + where F: Fn(&Node) -> Option<Root<Node>>, + G: Fn(&Node) -> Option<Root<Node>>; + fn is_root_node(self, node: &Node) -> bool; + fn is_current_node(self, node: &Node) -> bool; + fn first_following_node_not_following_root(self, node: &Node) + -> Option<Root<Node>>; + fn accept_node(self, node: &Node) -> Fallible<u16>; } -impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { +impl<'a> PrivateTreeWalkerHelpers for &'a TreeWalker { // https://dom.spec.whatwg.org/#concept-traverse-children fn traverse_children<F, G>(self, next_child: F, next_sibling: G) - -> Fallible<Option<Temporary<Node>>> - where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, - G: Fn(JSRef<Node>) -> Option<Temporary<Node>> + -> Fallible<Option<Root<Node>>> + where F: Fn(&Node) -> Option<Root<Node>>, + G: Fn(&Node) -> Option<Root<Node>> { // "To **traverse children** of type *type*, run these steps:" // "1. Let node be the value of the currentNode attribute." // "2. Set node to node's first child if type is first, and node's last child if type is last." let cur = self.current_node.get().root(); - let mut node_op: Option<JSRef<Node>> = next_child(cur.r()).map(|node| node.root().get_unsound_ref_forever()); + let mut node = match next_child(cur.r()) { + Some(node) => node, + None => return Ok(None), + }; // 3. Main: While node is not null, run these substeps: 'main: loop { - match node_op { - None => break, - Some(node) => { - // "1. Filter node and let result be the return value." - let result = try!(self.accept_node(node)); - match result { - // "2. If result is FILTER_ACCEPT, then set the currentNode - // attribute to node and return node." - NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) - }, - // "3. If result is FILTER_SKIP, run these subsubsteps:" - NodeFilterConstants::FILTER_SKIP => { - // "1. Let child be node's first child if type is first, - // and node's last child if type is last." - match next_child(node) { - // "2. If child is not null, set node to child and goto Main." - Some(child) => { - node_op = Some(child.root().get_unsound_ref_forever()); - continue 'main - }, - None => {} - } + // "1. Filter node and let result be the return value." + let result = try!(self.accept_node(node.r())); + match result { + // "2. If result is FILTER_ACCEPT, then set the currentNode + // attribute to node and return node." + NodeFilterConstants::FILTER_ACCEPT => { + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(Root::from_ref(node.r()))) + }, + // "3. If result is FILTER_SKIP, run these subsubsteps:" + NodeFilterConstants::FILTER_SKIP => { + // "1. Let child be node's first child if type is first, + // and node's last child if type is last." + match next_child(node.r()) { + // "2. If child is not null, set node to child and goto Main." + Some(child) => { + node = child; + continue 'main }, - _ => {} + None => {} } - // "4. While node is not null, run these substeps:" - loop { - match node_op { - None => break, - Some(node) => { - // "1. Let sibling be node's next sibling if type is next, - // and node's previous sibling if type is previous." - match next_sibling(node) { - // "2. If sibling is not null, - // set node to sibling and goto Main." - Some(sibling) => { - node_op = Some(sibling.root().get_unsound_ref_forever()); - continue 'main - }, - None => { - // "3. Let parent be node's parent." - match node.GetParentNode().map(|p| p.root().get_unsound_ref_forever()) { - // "4. If parent is null, parent is root, - // or parent is currentNode attribute's value, - // return null." - None => return Ok(None), - Some(parent) if self.is_root_node(parent) - || self.is_current_node(parent) => - return Ok(None), - // "5. Otherwise, set node to parent." - Some(parent) => node_op = Some(parent) - } - } - } - } + }, + _ => {} + } + // "4. While node is not null, run these substeps:" + loop { + // "1. Let sibling be node's next sibling if type is next, + // and node's previous sibling if type is previous." + match next_sibling(node.r()) { + // "2. If sibling is not null, + // set node to sibling and goto Main." + Some(sibling) => { + node = sibling; + continue 'main + }, + None => { + // "3. Let parent be node's parent." + match node.GetParentNode() { + // "4. If parent is null, parent is root, + // or parent is currentNode attribute's value, + // return null." + None => return Ok(None), + Some(ref parent) if self.is_root_node(parent.r()) + || self.is_current_node(parent.r()) => + return Ok(None), + // "5. Otherwise, set node to parent." + Some(parent) => node = parent } } } @@ -374,58 +367,58 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { fn traverse_siblings<F, G>(self, next_child: F, next_sibling: G) - -> Fallible<Option<Temporary<Node>>> - where F: Fn(JSRef<Node>) -> Option<Temporary<Node>>, - G: Fn(JSRef<Node>) -> Option<Temporary<Node>> + -> Fallible<Option<Root<Node>>> + where F: Fn(&Node) -> Option<Root<Node>>, + G: Fn(&Node) -> Option<Root<Node>> { // "To **traverse siblings** of type *type* run these steps:" // "1. Let node be the value of the currentNode attribute." - let mut node = self.current_node.get().root().get_unsound_ref_forever(); + let mut node = self.current_node.get().root(); // "2. If node is root, return null." - if self.is_root_node(node) { + if self.is_root_node(node.r()) { return Ok(None) } // "3. Run these substeps:" loop { // "1. Let sibling be node's next sibling if type is next, // and node's previous sibling if type is previous." - let mut sibling_op = next_sibling(node); + let mut sibling_op = next_sibling(node.r()); // "2. While sibling is not null, run these subsubsteps:" while sibling_op.is_some() { // "1. Set node to sibling." - node = sibling_op.unwrap().root().get_unsound_ref_forever(); + node = sibling_op.unwrap(); // "2. Filter node and let result be the return value." - let result = try!(self.accept_node(node)); + let result = try!(self.accept_node(node.r())); // "3. If result is FILTER_ACCEPT, then set the currentNode // attribute to node and return node." match result { NodeFilterConstants::FILTER_ACCEPT => { - self.current_node.set(JS::from_rooted(node)); - return Ok(Some(Temporary::from_rooted(node))) + self.current_node.set(JS::from_rooted(&node)); + return Ok(Some(node)) }, _ => {} } // "4. Set sibling to node's first child if type is next, // and node's last child if type is previous." - sibling_op = next_child(node); + sibling_op = next_child(node.r()); // "5. If result is FILTER_REJECT or sibling is null, // then set sibling to node's next sibling if type is next, // and node's previous sibling if type is previous." match (result, &sibling_op) { (NodeFilterConstants::FILTER_REJECT, _) - | (_, &None) => sibling_op = next_sibling(node), + | (_, &None) => sibling_op = next_sibling(node.r()), _ => {} } } // "3. Set node to its parent." - match node.GetParentNode().map(|p| p.root().get_unsound_ref_forever()) { + match node.GetParentNode() { // "4. If node is null or is root, return null." None => return Ok(None), - Some(n) if self.is_root_node(n) => return Ok(None), + Some(ref n) if self.is_root_node(n.r()) => return Ok(None), // "5. Filter node and if the return value is FILTER_ACCEPT, then return null." Some(n) => { node = n; - match try!(self.accept_node(node)) { + match try!(self.accept_node(node.r())) { NodeFilterConstants::FILTER_ACCEPT => return Ok(None), _ => {} } @@ -436,23 +429,23 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { } // https://dom.spec.whatwg.org/#concept-tree-following - fn first_following_node_not_following_root(self, node: JSRef<Node>) - -> Option<Temporary<Node>> { + fn first_following_node_not_following_root(self, node: &Node) + -> Option<Root<Node>> { // "An object A is following an object B if A and B are in the same tree // and A comes after B in tree order." match node.GetNextSibling() { None => { - let mut candidate = node; - while !self.is_root_node(candidate) && candidate.GetNextSibling().is_none() { + let mut candidate = Root::from_ref(node); + while !self.is_root_node(candidate.r()) && candidate.GetNextSibling().is_none() { match candidate.GetParentNode() { None => // This can happen if the user set the current node to somewhere // outside of the tree rooted at the original root. return None, - Some(n) => candidate = n.root().get_unsound_ref_forever() + Some(n) => candidate = n } } - if self.is_root_node(candidate) { + if self.is_root_node(candidate.r()) { None } else { candidate.GetNextSibling() @@ -463,7 +456,7 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { } // https://dom.spec.whatwg.org/#concept-node-filter - fn accept_node(self, node: JSRef<Node>) -> Fallible<u16> { + fn accept_node(self, node: &Node) -> Fallible<u16> { // "To filter node run these steps:" // "1. Let n be node's nodeType attribute value minus 1." let n = node.NodeType() - 1; @@ -479,25 +472,25 @@ impl<'a> PrivateTreeWalkerHelpers for JSRef<'a, TreeWalker> { match self.filter { Filter::None => Ok(NodeFilterConstants::FILTER_ACCEPT), Filter::Native(f) => Ok((f)(node)), - Filter::JS(callback) => callback.AcceptNode_(self, node, Rethrow) + Filter::JS(ref callback) => callback.AcceptNode_(self, node, Rethrow) } } - fn is_root_node(self, node: JSRef<Node>) -> bool { - JS::from_rooted(node) == self.root_node + fn is_root_node(self, node: &Node) -> bool { + JS::from_ref(node) == self.root_node } - fn is_current_node(self, node: JSRef<Node>) -> bool { - JS::from_rooted(node) == self.current_node.get() + fn is_current_node(self, node: &Node) -> bool { + JS::from_ref(node) == self.current_node.get() } } -impl<'a> Iterator for JSRef<'a, TreeWalker> { - type Item = JSRef<'a, Node>; +impl<'a> Iterator for &'a TreeWalker { + type Item = Root<Node>; - fn next(&mut self) -> Option<JSRef<'a, Node>> { + fn next(&mut self) -> Option<Root<Node>> { match self.NextNode() { - Ok(node) => node.map(|n| n.root().get_unsound_ref_forever()), + Ok(node) => node, Err(_) => // The Err path happens only when a JavaScript // NodeFilter throws an exception. This iterator @@ -512,6 +505,6 @@ impl<'a> Iterator for JSRef<'a, TreeWalker> { #[jstraceable] pub enum Filter { None, - Native(fn (node: JSRef<Node>) -> u16), - JS(NodeFilter) + Native(fn (node: &Node) -> u16), + JS(Rc<NodeFilter>) } diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index 9c62346ff4a..70ac7e31fac 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -8,8 +8,8 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Rootable, RootedReference}; -use dom::bindings::js::Temporary; +use dom::bindings::js::{JS, MutNullableHeap, RootedReference}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::event::{Event, EventTypeId, EventBubbles, EventCancelable}; @@ -42,27 +42,27 @@ impl UIEvent { } } - pub fn new_uninitialized(window: JSRef<Window>) -> Temporary<UIEvent> { + pub fn new_uninitialized(window: &Window) -> Root<UIEvent> { reflect_dom_object(box UIEvent::new_inherited(EventTypeId::UIEvent), GlobalRef::Window(window), UIEventBinding::Wrap) } - pub fn new(window: JSRef<Window>, + pub fn new(window: &Window, type_: DOMString, can_bubble: EventBubbles, cancelable: EventCancelable, - view: Option<JSRef<Window>>, - detail: i32) -> Temporary<UIEvent> { - let ev = UIEvent::new_uninitialized(window).root(); + view: Option<&Window>, + detail: i32) -> Root<UIEvent> { + let ev = UIEvent::new_uninitialized(window); ev.r().InitUIEvent(type_, can_bubble == EventBubbles::Bubbles, cancelable == EventCancelable::Cancelable, view, detail); - Temporary::from_rooted(ev.r()) + ev } pub fn Constructor(global: GlobalRef, type_: DOMString, - init: &UIEventBinding::UIEventInit) -> Fallible<Temporary<UIEvent>> { + init: &UIEventBinding::UIEventInit) -> Fallible<Root<UIEvent>> { let bubbles = if init.parent.bubbles { EventBubbles::Bubbles } else { EventBubbles::DoesNotBubble }; let cancelable = if init.parent.cancelable { EventCancelable::Cancelable @@ -76,10 +76,10 @@ impl UIEvent { } } -impl<'a> UIEventMethods for JSRef<'a, UIEvent> { +impl<'a> UIEventMethods for &'a UIEvent { // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-view - fn GetView(self) -> Option<Temporary<Window>> { - self.view.get().map(Temporary::from_rooted) + fn GetView(self) -> Option<Root<Window>> { + self.view.get().map(Root::from_rooted) } // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#widl-UIEvent-detail @@ -91,15 +91,15 @@ impl<'a> UIEventMethods for JSRef<'a, UIEvent> { type_: DOMString, can_bubble: bool, cancelable: bool, - view: Option<JSRef<Window>>, + view: Option<&Window>, detail: i32) { - let event: JSRef<Event> = EventCast::from_ref(self); + let event: &Event = EventCast::from_ref(self); if event.dispatching() { return; } event.InitEvent(type_, can_bubble, cancelable); - self.view.set(view.map(JS::from_rooted)); + self.view.set(view.map(JS::from_ref)); self.detail.set(detail); } } diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs index f4b525418f8..0b2432cac31 100644 --- a/components/script/dom/urlsearchparams.rs +++ b/components/script/dom/urlsearchparams.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams; use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eURLSearchParams, eString}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use encoding::types::EncodingRef; @@ -32,16 +32,16 @@ impl URLSearchParams { } } - pub fn new(global: GlobalRef) -> Temporary<URLSearchParams> { + pub fn new(global: GlobalRef) -> Root<URLSearchParams> { reflect_dom_object(box URLSearchParams::new_inherited(), global, URLSearchParamsBinding::Wrap) } // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) -> - Fallible<Temporary<URLSearchParams>> { + Fallible<Root<URLSearchParams>> { // Step 1. - let query = URLSearchParams::new(global).root(); + let query = URLSearchParams::new(global); match init { Some(eString(init)) => { // Step 2. @@ -52,18 +52,17 @@ impl URLSearchParams { // Step 3. // FIXME(https://github.com/rust-lang/rust/issues/23338) let query = query.r(); - let init = init.root(); let init = init.r(); *query.list.borrow_mut() = init.list.borrow().clone(); }, None => {} } // Step 4. - Ok(Temporary::from_rooted(query.r())) + Ok(query) } } -impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> { +impl<'a> URLSearchParamsMethods for &'a URLSearchParams { // https://url.spec.whatwg.org/#dom-urlsearchparams-append fn Append(self, name: DOMString, value: DOMString) { // Step 1. @@ -132,7 +131,7 @@ pub trait URLSearchParamsHelpers { fn serialize(self, encoding: Option<EncodingRef>) -> DOMString; } -impl<'a> URLSearchParamsHelpers for JSRef<'a, URLSearchParams> { +impl<'a> URLSearchParamsHelpers for &'a URLSearchParams { // https://url.spec.whatwg.org/#concept-urlencoded-serializer fn serialize(self, encoding: Option<EncodingRef>) -> DOMString { let list = self.list.borrow(); @@ -144,7 +143,7 @@ trait PrivateURLSearchParamsHelpers { fn update_steps(self); } -impl<'a> PrivateURLSearchParamsHelpers for JSRef<'a, URLSearchParams> { +impl<'a> PrivateURLSearchParamsHelpers for &'a URLSearchParams { // https://url.spec.whatwg.org/#concept-uq-update fn update_steps(self) { // XXXManishearth Implement this when the URL interface is implemented diff --git a/components/script/dom/userscripts.rs b/components/script/dom/userscripts.rs index 1910784b0c5..a71ead38e52 100644 --- a/components/script/dom/userscripts.rs +++ b/components/script/dom/userscripts.rs @@ -5,10 +5,10 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::InheritTypes::NodeCast; -use dom::bindings::js::{JSRef, OptionalRootable, Rootable, RootedReference}; +use dom::bindings::js::{RootedReference}; use dom::element::AttributeHandlers; use dom::htmlheadelement::HTMLHeadElement; -use dom::node::{Node, NodeHelpers}; +use dom::node::NodeHelpers; use util::opts; use util::resource_files::resources_dir_path; use std::borrow::ToOwned; @@ -16,11 +16,11 @@ use std::fs::read_dir; use std::path::PathBuf; -pub fn load_script(head: JSRef<HTMLHeadElement>) { +pub fn load_script(head: &HTMLHeadElement) { if let Some(ref path_str) = opts::get().userscripts { - let node: &JSRef<Node> = NodeCast::from_borrowed_ref(&head); - let first_child = node.GetFirstChild().root(); - let doc = node.owner_doc().root(); + let node = NodeCast::from_borrowed_ref(&head); + let first_child = node.GetFirstChild(); + let doc = node.owner_doc(); let doc = doc.r(); let path = if &**path_str == "" { @@ -42,10 +42,10 @@ pub fn load_script(head: JSRef<HTMLHeadElement>) { Ok(ref s) if s.ends_with(".js") => "file://".to_owned() + &s[..], _ => continue }; - let new_script = doc.CreateElement("script".to_owned()).unwrap().root(); + let new_script = doc.CreateElement("script".to_owned()).unwrap(); let new_script = new_script.r(); new_script.set_string_attribute(&atom!("src"), name); - let new_script_node: &JSRef<Node> = NodeCast::from_borrowed_ref(&new_script); + let new_script_node = NodeCast::from_borrowed_ref(&new_script); node.InsertBefore(*new_script_node, first_child.r()).unwrap(); } } diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs index 6088279c980..71750f4315f 100644 --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::ValidityStateBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::window::Window; @@ -23,7 +23,7 @@ impl ValidityState { } } - pub fn new(window: JSRef<Window>) -> Temporary<ValidityState> { + pub fn new(window: &Window) -> Root<ValidityState> { reflect_dom_object(box ValidityState::new_inherited(), GlobalRef::Window(window), ValidityStateBinding::Wrap) diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index 4effc4daf33..8bb62637ac6 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -31,37 +31,10 @@ use dom::bindings::codegen::InheritTypes::HTMLTableRowElementCast; use dom::bindings::codegen::InheritTypes::HTMLTableSectionElementCast; use dom::bindings::codegen::InheritTypes::HTMLTextAreaElementCast; use dom::bindings::codegen::InheritTypes::HTMLTitleElementCast; -use dom::bindings::js::JSRef; use dom::document::Document; -use dom::element::Element; use dom::element::ElementTypeId; use dom::event::Event; -use dom::htmlanchorelement::HTMLAnchorElement; -use dom::htmlareaelement::HTMLAreaElement; -use dom::htmlbodyelement::HTMLBodyElement; -use dom::htmlbuttonelement::HTMLButtonElement; -use dom::htmlcanvaselement::HTMLCanvasElement; -use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; -use dom::htmlfieldsetelement::HTMLFieldSetElement; -use dom::htmlfontelement::HTMLFontElement; -use dom::htmlformelement::HTMLFormElement; -use dom::htmlheadelement::HTMLHeadElement; -use dom::htmliframeelement::HTMLIFrameElement; -use dom::htmlimageelement::HTMLImageElement; -use dom::htmlinputelement::HTMLInputElement; -use dom::htmllinkelement::HTMLLinkElement; -use dom::htmlobjectelement::HTMLObjectElement; -use dom::htmloptgroupelement::HTMLOptGroupElement; -use dom::htmloptionelement::HTMLOptionElement; -use dom::htmlscriptelement::HTMLScriptElement; -use dom::htmlselectelement::HTMLSelectElement; -use dom::htmlstyleelement::HTMLStyleElement; -use dom::htmltableelement::HTMLTableElement; -use dom::htmltablecellelement::HTMLTableCellElement; -use dom::htmltablerowelement::HTMLTableRowElement; -use dom::htmltablesectionelement::HTMLTableSectionElement; -use dom::htmltextareaelement::HTMLTextAreaElement; -use dom::htmltitleelement::HTMLTitleElement; +use dom::htmlelement::HTMLElementTypeId; use dom::node::{Node, NodeHelpers, NodeTypeId, CloneChildrenFlag}; use util::str::DOMString; @@ -77,7 +50,7 @@ pub trait VirtualMethods { /// Called when changing or adding attributes, after the attribute's value /// has been updated. - fn after_set_attr(&self, attr: JSRef<Attr>) { + fn after_set_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.after_set_attr(attr); } @@ -85,7 +58,7 @@ pub trait VirtualMethods { /// Called when changing or removing attributes, before any modification /// has taken place. - fn before_remove_attr(&self, attr: JSRef<Attr>) { + fn before_remove_attr(&self, attr: &Attr) { if let Some(ref s) = self.super_type() { s.before_remove_attr(attr); } @@ -125,21 +98,21 @@ pub trait VirtualMethods { } /// Called on the parent when a node is added to its child list. - fn child_inserted(&self, child: JSRef<Node>) { + fn child_inserted(&self, child: &Node) { if let Some(ref s) = self.super_type() { s.child_inserted(child); } } /// Called during event dispatch after the bubbling phase completes. - fn handle_event(&self, event: JSRef<Event>) { + fn handle_event(&self, event: &Event) { if let Some(s) = self.super_type() { s.handle_event(event); } } /// https://dom.spec.whatwg.org/#concept-node-clone (step 5) - fn cloning_steps(&self, copy: JSRef<Node>, maybe_doc: Option<JSRef<Document>>, + fn cloning_steps(&self, copy: &Node, maybe_doc: Option<&Document>, clone_children: CloneChildrenFlag) { if let Some(ref s) = self.super_type() { s.cloning_steps(copy, maybe_doc, clone_children); @@ -151,122 +124,122 @@ pub trait VirtualMethods { /// method call on the trait object will invoke the corresponding method on the /// concrete type, propagating up the parent hierarchy unless otherwise /// interrupted. -pub fn vtable_for<'a>(node: &'a JSRef<'a, Node>) -> &'a (VirtualMethods + 'a) { +pub fn vtable_for<'a>(node: &'a &'a Node) -> &'a (VirtualMethods + 'a) { match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) => { - let element: &'a JSRef<'a, HTMLAnchorElement> = HTMLAnchorElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLAnchorElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAppletElement)) => { HTMLAppletElementCast::to_borrowed_ref(node).unwrap() as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) => { - let element: &'a JSRef<'a, HTMLAreaElement> = HTMLAreaElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLAreaElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLBodyElement)) => { - let element: &'a JSRef<'a, HTMLBodyElement> = HTMLBodyElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLBodyElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => { - let element: &'a JSRef<'a, HTMLButtonElement> = HTMLButtonElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLButtonElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement)) => { - let element: &'a JSRef<'a, HTMLCanvasElement> = HTMLCanvasElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLCanvasElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFieldSetElement)) => { - let element: &'a JSRef<'a, HTMLFieldSetElement> = HTMLFieldSetElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLFieldSetElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFontElement)) => { - let element: &'a JSRef<'a, HTMLFontElement> = HTMLFontElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLFontElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFormElement)) => { - let element: &'a JSRef<'a, HTMLFormElement> = HTMLFormElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLFormElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLHeadElement)) => { - let element: &'a JSRef<'a, HTMLHeadElement> = HTMLHeadElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLHeadElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement)) => { - let element: &'a JSRef<'a, HTMLImageElement> = HTMLImageElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLImageElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement)) => { - let element: &'a JSRef<'a, HTMLIFrameElement> = HTMLIFrameElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLIFrameElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { - let element: &'a JSRef<'a, HTMLInputElement> = HTMLInputElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLInputElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => { - let element: &'a JSRef<'a, HTMLLinkElement> = HTMLLinkElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLLinkElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => { - let element: &'a JSRef<'a, HTMLObjectElement> = HTMLObjectElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLObjectElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptGroupElement)) => { - let element: &'a JSRef<'a, HTMLOptGroupElement> = HTMLOptGroupElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLOptGroupElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => { - let element: &'a JSRef<'a, HTMLOptionElement> = HTMLOptionElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLOptionElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLScriptElement)) => { - let element: &'a JSRef<'a, HTMLScriptElement> = HTMLScriptElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLScriptElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => { - let element: &'a JSRef<'a, HTMLSelectElement> = HTMLSelectElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLSelectElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLStyleElement)) => { - let element: &'a JSRef<'a, HTMLStyleElement> = HTMLStyleElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLStyleElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement)) => { - let element: &'a JSRef<'a, HTMLTableElement> = + let element = HTMLTableElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableCellElement(_))) => { - let element: &'a JSRef<'a, HTMLTableCellElement> = + let element = HTMLTableCellElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableRowElement)) => { - let element: &'a JSRef<'a, HTMLTableRowElement> = + let element = HTMLTableRowElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableSectionElement)) => { - let element: &'a JSRef<'a, HTMLTableSectionElement> = + let element = HTMLTableSectionElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => { - let element: &'a JSRef<'a, HTMLTextAreaElement> = HTMLTextAreaElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLTextAreaElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement)) => { - let element: &'a JSRef<'a, HTMLTitleElement> = + let element = HTMLTitleElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(ElementTypeId::Element) => { - let element: &'a JSRef<'a, Element> = ElementCast::to_borrowed_ref(node).unwrap(); + let element = ElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } NodeTypeId::Element(_) => { - let element: &'a JSRef<'a, HTMLElement> = HTMLElementCast::to_borrowed_ref(node).unwrap(); + let element = HTMLElementCast::to_borrowed_ref(node).unwrap(); element as &'a (VirtualMethods + 'a) } _ => { diff --git a/components/script/dom/webglactiveinfo.rs b/components/script/dom/webglactiveinfo.rs index 8edcb2bf806..8f96b98ed9c 100644 --- a/components/script/dom/webglactiveinfo.rs +++ b/components/script/dom/webglactiveinfo.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding; use dom::bindings::codegen::Bindings::WebGLActiveInfoBinding::WebGLActiveInfoMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector,reflect_dom_object}; use util::str::DOMString; @@ -29,12 +29,12 @@ impl WebGLActiveInfo { } } - pub fn new(global: GlobalRef, size: i32, ty: u32, name: String) -> Temporary<WebGLActiveInfo> { + pub fn new(global: GlobalRef, size: i32, ty: u32, name: String) -> Root<WebGLActiveInfo> { reflect_dom_object(box WebGLActiveInfo::new_inherited(size, ty, name), global, WebGLActiveInfoBinding::Wrap) } } -impl<'a> WebGLActiveInfoMethods for JSRef<'a, WebGLActiveInfo> { +impl<'a> WebGLActiveInfoMethods for &'a WebGLActiveInfo { fn Size(self) -> i32 { self.size } diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index ee19ff7d57c..f7c17cb8f04 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLBufferBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLBuffer { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLBuffer> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLBuffer> { reflect_dom_object(box WebGLBuffer::new_inherited(id), global, WebGLBufferBinding::Wrap) } } pub trait WebGLBufferHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLBufferHelpers for JSRef<'a, WebGLBuffer> { - fn get_id(&self) -> u32 { +impl<'a> WebGLBufferHelpers for &'a WebGLBuffer { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index c1489c99e72..f4bb4b2b043 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLFramebufferBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLFramebuffer { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLFramebuffer> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLFramebuffer> { reflect_dom_object(box WebGLFramebuffer::new_inherited(id), global, WebGLFramebufferBinding::Wrap) } } pub trait WebGLFramebufferHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLFramebufferHelpers for JSRef<'a, WebGLFramebuffer> { - fn get_id(&self) -> u32 { +impl<'a> WebGLFramebufferHelpers for &'a WebGLFramebuffer { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webglobject.rs b/components/script/dom/webglobject.rs index 0decbe1060d..82093b64aa7 100644 --- a/components/script/dom/webglobject.rs +++ b/components/script/dom/webglobject.rs @@ -5,8 +5,8 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLObjectBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary}; use dom::bindings::utils::{Reflector, reflect_dom_object}; +use dom::bindings::js::Root; #[dom_struct] pub struct WebGLObject { @@ -20,7 +20,7 @@ impl WebGLObject { } } - pub fn new(global: GlobalRef) -> Temporary<WebGLObject> { + pub fn new(global: GlobalRef) -> Root<WebGLObject> { reflect_dom_object(box WebGLObject::new_inherited(), global, WebGLObjectBinding::Wrap) } } diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 7839b0ffb03..3e6191d764c 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLProgramBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLProgram { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLProgram> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLProgram> { reflect_dom_object(box WebGLProgram::new_inherited(id), global, WebGLProgramBinding::Wrap) } } pub trait WebGLProgramHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLProgramHelpers for JSRef<'a, WebGLProgram> { - fn get_id(&self) -> u32 { +impl<'a> WebGLProgramHelpers for &'a WebGLProgram { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 12cdd8240c6..5165235acfb 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLRenderbuffer { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLRenderbuffer> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLRenderbuffer> { reflect_dom_object(box WebGLRenderbuffer::new_inherited(id), global, WebGLRenderbufferBinding::Wrap) } } pub trait WebGLRenderbufferHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLRenderbufferHelpers for JSRef<'a, WebGLRenderbuffer> { - fn get_id(&self) -> u32 { +impl<'a> WebGLRenderbufferHelpers for &'a WebGLRenderbuffer { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index a2745aaa143..d6d2c5b6144 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{ WebGLContextAttributes, WebGLRenderingContextMethods, WebGLRenderingContextConstants}; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary}; +use dom::bindings::js::{JS, LayoutJS, Root}; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::bindings::conversions::ToJSValConvertible; use dom::htmlcanvaselement::{HTMLCanvasElement}; @@ -20,9 +20,9 @@ use dom::webglshader::{WebGLShader, WebGLShaderHelpers}; use dom::webglprogram::{WebGLProgram, WebGLProgramHelpers}; use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelpers}; use euclid::size::Size2D; -use js::jsapi::{JSContext, JSObject}; -use js::jsfriendapi::bindgen::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView}; -use js::jsval::{JSVal, NullValue, Int32Value}; +use js::jsapi::{JSContext, JSObject, RootedValue}; +use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView}; +use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value}; use std::mem; use std::ptr; use std::sync::mpsc::{channel, Sender}; @@ -39,7 +39,7 @@ pub struct WebGLRenderingContext { impl WebGLRenderingContext { fn new_inherited(global: GlobalRef, - canvas: JSRef<HTMLCanvasElement>, + canvas: &HTMLCanvasElement, size: Size2D<i32>, attrs: GLContextAttributes) -> Result<WebGLRenderingContext, &'static str> { @@ -49,12 +49,12 @@ impl WebGLRenderingContext { reflector_: Reflector::new(), global: GlobalField::from_rooted(&global), renderer: chan, - canvas: JS::from_rooted(canvas), + canvas: JS::from_ref(canvas), }) } - pub fn new(global: GlobalRef, canvas: JSRef<HTMLCanvasElement>, size: Size2D<i32>, attrs: GLContextAttributes) - -> Option<Temporary<WebGLRenderingContext>> { + pub fn new(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>, attrs: GLContextAttributes) + -> Option<Root<WebGLRenderingContext>> { match WebGLRenderingContext::new_inherited(global, canvas, size, attrs) { Ok(ctx) => Some(reflect_dom_object(box ctx, global, WebGLRenderingContextBinding::Wrap)), @@ -76,10 +76,10 @@ impl Drop for WebGLRenderingContext { } } -impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { +impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1 - fn Canvas(self) -> Temporary<HTMLCanvasElement> { - Temporary::from_rooted(self.canvas) + fn Canvas(self) -> Root<HTMLCanvasElement> { + self.canvas.root() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1 @@ -99,14 +99,16 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 fn GetParameter(self, cx: *mut JSContext, parameter: u32) -> JSVal { // TODO(ecoal95): Implement the missing parameters from the spec + let mut rval = RootedValue::new(cx, UndefinedValue()); match parameter { WebGLRenderingContextConstants::VERSION => - "WebGL 1.0".to_jsval(cx), + "WebGL 1.0".to_jsval(cx, rval.handle_mut()), WebGLRenderingContextConstants::RENDERER | WebGLRenderingContextConstants::VENDOR => - "Mozilla/Servo".to_jsval(cx), - _ => NullValue(), + "Mozilla/Servo".to_jsval(cx, rval.handle_mut()), + _ => rval.ptr = NullValue(), } + rval.ptr } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2 @@ -170,7 +172,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn AttachShader(self, program: Option<JSRef<WebGLProgram>>, shader: Option<JSRef<WebGLShader>>) { + fn AttachShader(self, program: Option<&WebGLProgram>, shader: Option<&WebGLShader>) { let program_id = match program { Some(program) => program.get_id(), None => return, @@ -183,28 +185,28 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BindBuffer(self, target: u32, buffer: Option<JSRef<WebGLBuffer>>) { + fn BindBuffer(self, target: u32, buffer: Option<&WebGLBuffer>) { let id = buffer.map(|buf| buf.get_id()).unwrap_or(0); self.renderer.send( CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, id))).unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 - fn BindFramebuffer(self, target: u32, framebuffer: Option<JSRef<WebGLFramebuffer>>) { + fn BindFramebuffer(self, target: u32, framebuffer: Option<&WebGLFramebuffer>) { let id = framebuffer.map(|fb| fb.get_id()).unwrap_or(0); self.renderer.send( CanvasMsg::WebGL(CanvasWebGLMsg::BindFramebuffer(target, id))).unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 - fn BindRenderbuffer(self, target: u32, renderbuffer: Option<JSRef<WebGLRenderbuffer>>) { + fn BindRenderbuffer(self, target: u32, renderbuffer: Option<&WebGLRenderbuffer>) { let id = renderbuffer.map(|rb| rb.get_id()).unwrap_or(0); self.renderer.send( CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, id))).unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn BindTexture(self, target: u32, texture: Option<JSRef<WebGLTexture>>) { + fn BindTexture(self, target: u32, texture: Option<&WebGLTexture>) { let id = texture.map(|tex| tex.get_id()).unwrap_or(0); self.renderer.send( CanvasMsg::WebGL(CanvasWebGLMsg::BindTexture(target, id))).unwrap() @@ -212,7 +214,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 #[allow(unsafe_code)] - fn BufferData(self, cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) { + fn BufferData(self, _cx: *mut JSContext, target: u32, data: Option<*mut JSObject>, usage: u32) { let data = match data { Some(data) => data, None => return, @@ -221,11 +223,11 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { unsafe { let mut length = 0; let mut ptr = ptr::null_mut(); - let buffer_data = JS_GetObjectAsArrayBufferView(cx, data, &mut length, &mut ptr); + let buffer_data = JS_GetObjectAsArrayBufferView(data, &mut length, &mut ptr); if buffer_data.is_null() { panic!("Argument data to WebGLRenderingContext.bufferdata is not a Float32Array") } - let data_f32 = JS_GetFloat32ArrayData(buffer_data, cx); + let data_f32 = JS_GetFloat32ArrayData(buffer_data, ptr::null()); let data_vec_length = length / mem::size_of::<f32>() as u32; data_vec = Vec::from_raw_buf(data_f32, data_vec_length as usize); } @@ -243,7 +245,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn CompileShader(self, shader: Option<JSRef<WebGLShader>>) { + fn CompileShader(self, shader: Option<&WebGLShader>) { let shader_id = match shader { Some(shader) => shader.get_id(), None => return, @@ -254,7 +256,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // TODO(ecoal95): Probably in the future we should keep track of the // generated objects, either here or in the webgl task // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn CreateBuffer(self) -> Option<Temporary<WebGLBuffer>> { + fn CreateBuffer(self) -> Option<Root<WebGLBuffer>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap(); receiver.recv().unwrap() @@ -262,7 +264,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 - fn CreateFramebuffer(self) -> Option<Temporary<WebGLFramebuffer>> { + fn CreateFramebuffer(self) -> Option<Root<WebGLFramebuffer>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap(); receiver.recv().unwrap() @@ -270,7 +272,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 - fn CreateRenderbuffer(self) -> Option<Temporary<WebGLRenderbuffer>> { + fn CreateRenderbuffer(self) -> Option<Root<WebGLRenderbuffer>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap(); receiver.recv().unwrap() @@ -278,7 +280,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn CreateTexture(self) -> Option<Temporary<WebGLTexture>> { + fn CreateTexture(self) -> Option<Root<WebGLTexture>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap(); receiver.recv().unwrap() @@ -286,7 +288,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn CreateProgram(self) -> Option<Temporary<WebGLProgram>> { + fn CreateProgram(self) -> Option<Root<WebGLProgram>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap(); receiver.recv().unwrap() @@ -296,7 +298,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // TODO(ecoal95): Check if constants are cross-platform or if we must make a translation // between WebGL constants and native ones. - fn CreateShader(self, shader_type: u32) -> Option<Temporary<WebGLShader>> { + fn CreateShader(self, shader_type: u32) -> Option<Root<WebGLShader>> { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap(); receiver.recv().unwrap() @@ -304,42 +306,42 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn DeleteBuffer(self, buffer: Option<JSRef<WebGLBuffer>>) { + fn DeleteBuffer(self, buffer: Option<&WebGLBuffer>) { if let Some(buffer) = buffer { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteBuffer(buffer.get_id()))).unwrap(); } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 - fn DeleteFramebuffer(self, framebuffer: Option<JSRef<WebGLFramebuffer>>) { + fn DeleteFramebuffer(self, framebuffer: Option<&WebGLFramebuffer>) { if let Some(framebuffer) = framebuffer { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteFramebuffer(framebuffer.get_id()))).unwrap(); } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 - fn DeleteRenderbuffer(self, renderbuffer: Option<JSRef<WebGLRenderbuffer>>) { + fn DeleteRenderbuffer(self, renderbuffer: Option<&WebGLRenderbuffer>) { if let Some(renderbuffer) = renderbuffer { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteRenderbuffer(renderbuffer.get_id()))).unwrap(); } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn DeleteTexture(self, texture: Option<JSRef<WebGLTexture>>) { + fn DeleteTexture(self, texture: Option<&WebGLTexture>) { if let Some(texture) = texture { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteTexture(texture.get_id()))).unwrap(); } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn DeleteProgram(self, program: Option<JSRef<WebGLProgram>>) { + fn DeleteProgram(self, program: Option<&WebGLProgram>) { if let Some(program) = program { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteProgram(program.get_id()))).unwrap(); } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn DeleteShader(self, shader: Option<JSRef<WebGLShader>>) { + fn DeleteShader(self, shader: Option<&WebGLShader>) { if let Some(shader) = shader { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DeleteShader(shader.get_id()))).unwrap(); } @@ -356,7 +358,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - fn GetAttribLocation(self, program: Option<JSRef<WebGLProgram>>, name: DOMString) -> i32 { + fn GetAttribLocation(self, program: Option<&WebGLProgram>, name: DOMString) -> i32 { let program_id = match program { Some(program) => program.get_id(), None => return -1, @@ -367,7 +369,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetShaderInfoLog(self, shader: Option<JSRef<WebGLShader>>) -> Option<DOMString> { + fn GetShaderInfoLog(self, shader: Option<&WebGLShader>) -> Option<DOMString> { if let Some(shader) = shader { let (sender, receiver) = channel(); self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(shader.get_id(), sender))).unwrap(); @@ -378,7 +380,7 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetShaderParameter(self, _: *mut JSContext, shader: Option<JSRef<WebGLShader>>, param_id: u32) -> JSVal { + fn GetShaderParameter(self, _: *mut JSContext, shader: Option<&WebGLShader>, param_id: u32) -> JSVal { if let Some(shader) = shader { let (sender, receiver) = channel(); self.renderer.send( @@ -391,8 +393,8 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetUniformLocation(self, - program: Option<JSRef<WebGLProgram>>, - name: DOMString) -> Option<Temporary<WebGLUniformLocation>> { + program: Option<&WebGLProgram>, + name: DOMString) -> Option<Root<WebGLUniformLocation>> { if let Some(program) = program { let (sender, receiver) = channel(); self.renderer.send( @@ -405,14 +407,14 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn LinkProgram(self, program: Option<JSRef<WebGLProgram>>) { + fn LinkProgram(self, program: Option<&WebGLProgram>) { if let Some(program) = program { self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::LinkProgram(program.get_id()))).unwrap() } } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn ShaderSource(self, shader: Option<JSRef<WebGLShader>>, source: DOMString) { + fn ShaderSource(self, shader: Option<&WebGLShader>, source: DOMString) { if let Some(shader) = shader { self.renderer.send( CanvasMsg::WebGL(CanvasWebGLMsg::ShaderSource(shader.get_id(), source))).unwrap(); @@ -422,8 +424,8 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] fn Uniform4fv(self, - cx: *mut JSContext, - uniform: Option<JSRef<WebGLUniformLocation>>, + _cx: *mut JSContext, + uniform: Option<&WebGLUniformLocation>, data: Option<*mut JSObject>) { let uniform_id = match uniform { Some(uniform) => uniform.get_id(), @@ -437,14 +439,14 @@ impl<'a> WebGLRenderingContextMethods for JSRef<'a, WebGLRenderingContext> { let data_vec: Vec<f32>; unsafe { - let data_f32 = JS_GetFloat32ArrayData(data, cx); + let data_f32 = JS_GetFloat32ArrayData(data, ptr::null()); data_vec = Vec::from_raw_buf(data_f32, 4); } self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4fv(uniform_id, data_vec))).unwrap() } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn UseProgram(self, program: Option<JSRef<WebGLProgram>>) { + fn UseProgram(self, program: Option<&WebGLProgram>) { let program_id = match program { Some(program) => program.get_id(), None => return, diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs index ade6f6e93c9..7030b1fda99 100644 --- a/components/script/dom/webglshader.rs +++ b/components/script/dom/webglshader.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLShaderBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLShader { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLShader> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLShader> { reflect_dom_object(box WebGLShader::new_inherited(id), global, WebGLShaderBinding::Wrap) } } pub trait WebGLShaderHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLShaderHelpers for JSRef<'a, WebGLShader> { - fn get_id(&self) -> u32 { +impl<'a> WebGLShaderHelpers for &'a WebGLShader { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webglshaderprecisionformat.rs b/components/script/dom/webglshaderprecisionformat.rs index 368d57358f6..91b12883731 100644 --- a/components/script/dom/webglshaderprecisionformat.rs +++ b/components/script/dom/webglshaderprecisionformat.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding; use dom::bindings::codegen::Bindings::WebGLShaderPrecisionFormatBinding::WebGLShaderPrecisionFormatMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector,reflect_dom_object}; #[dom_struct] @@ -30,7 +30,7 @@ impl WebGLShaderPrecisionFormat { pub fn new(global: GlobalRef, range_min: i32, range_max: i32, - precision: i32) -> Temporary<WebGLShaderPrecisionFormat> { + precision: i32) -> Root<WebGLShaderPrecisionFormat> { reflect_dom_object( box WebGLShaderPrecisionFormat::new_inherited(range_min, range_max, precision), global, @@ -38,7 +38,7 @@ impl WebGLShaderPrecisionFormat { } } -impl<'a> WebGLShaderPrecisionFormatMethods for JSRef<'a, WebGLShaderPrecisionFormat> { +impl<'a> WebGLShaderPrecisionFormatMethods for &'a WebGLShaderPrecisionFormat { fn RangeMin(self) -> i32 { self.range_min } diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 882f56ff52f..d871bc598da 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLTextureBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::webglobject::WebGLObject; @@ -23,17 +23,17 @@ impl WebGLTexture { } } - pub fn new(global: GlobalRef, id: u32) -> Temporary<WebGLTexture> { + pub fn new(global: GlobalRef, id: u32) -> Root<WebGLTexture> { reflect_dom_object(box WebGLTexture::new_inherited(id), global, WebGLTextureBinding::Wrap) } } pub trait WebGLTextureHelpers { - fn get_id(&self) -> u32; + fn get_id(self) -> u32; } -impl<'a> WebGLTextureHelpers for JSRef<'a, WebGLTexture> { - fn get_id(&self) -> u32 { +impl<'a> WebGLTextureHelpers for &'a WebGLTexture { + fn get_id(self) -> u32 { self.id } } diff --git a/components/script/dom/webgluniformlocation.rs b/components/script/dom/webgluniformlocation.rs index 3f97000eedd..675ddf42ca0 100644 --- a/components/script/dom/webgluniformlocation.rs +++ b/components/script/dom/webgluniformlocation.rs @@ -5,7 +5,7 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use dom::bindings::codegen::Bindings::WebGLUniformLocationBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Temporary, JSRef}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector,reflect_dom_object}; #[dom_struct] @@ -22,17 +22,17 @@ impl WebGLUniformLocation { } } - pub fn new(global: GlobalRef, id: i32) -> Temporary<WebGLUniformLocation> { + pub fn new(global: GlobalRef, id: i32) -> Root<WebGLUniformLocation> { reflect_dom_object(box WebGLUniformLocation::new_inherited(id), global, WebGLUniformLocationBinding::Wrap) } } pub trait WebGLUniformLocationHelpers { - fn get_id(&self) -> i32; + fn get_id(self) -> i32; } -impl<'a> WebGLUniformLocationHelpers for JSRef<'a, WebGLUniformLocation> { - fn get_id(&self) -> i32 { +impl<'a> WebGLUniformLocationHelpers for &'a WebGLUniformLocation { + fn get_id(self) -> i32 { self.id } } diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 9272346d416..c8f8e5da056 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -11,7 +11,7 @@ use dom::bindings::codegen::InheritTypes::EventCast; use dom::bindings::error::{Error, Fallible}; use dom::bindings::error::Error::{InvalidAccess, Syntax}; use dom::bindings::global::{GlobalField, GlobalRef}; -use dom::bindings::js::{Temporary, JSRef, Rootable}; +use dom::bindings::js::Root; use dom::bindings::refcounted::Trusted; use dom::bindings::str::USVString; use dom::bindings::trace::JSTraceable; @@ -121,58 +121,55 @@ impl WebSocket { } - pub fn new(global: GlobalRef, url: DOMString) -> Fallible<Temporary<WebSocket>> { + pub fn new(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> { /*TODO: This constructor is only a prototype, it does not accomplish the specs defined here: http://html.spec.whatwg.org Item 1 is already satisfied. The remaining 8 items must be satisfied. TODO: This constructor should be responsible for spawning a thread for the - receive loop after ws_root.r().Open() - See comment + receive loop after ws.r().Open() - See comment */ - let ws_root = reflect_dom_object(box WebSocket::new_inherited(global, url), - global, - WebSocketBinding::Wrap).root(); - let ws_root = ws_root.r(); + let ws = reflect_dom_object(box WebSocket::new_inherited(global, url), + global, + WebSocketBinding::Wrap); // FIXME extract the right variables once Client::connect implementation is // fixed to follow the RFC 6455 properly - let (parsed_url, _, _, _, _) = try!(parse_web_socket_url(&ws_root.url)); + let (parsed_url, _, _, _, _) = try!(parse_web_socket_url(&ws.r().url)); // TODO Client::connect does not conform to RFC 6455 // see https://github.com/cyderize/rust-websocket/issues/38 let request = match Client::connect(parsed_url) { Ok(request) => request, Err(_) => { - let global_root = ws_root.global.root(); - let address = Trusted::new(global_root.r().get_cx(), ws_root, global_root.r().script_chan().clone()); + let global_root = ws.r().global.root(); + let address = Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone()); let task = box WebSocketTaskHandler::new(address, WebSocketTask::Close); global_root.r().script_chan().send(ScriptMsg::RunnableMsg(task)).unwrap(); - return Ok(Temporary::from_rooted(ws_root)); + return Ok(ws); } }; let response = request.send().unwrap(); response.validate().unwrap(); - ws_root.ready_state.set(WebSocketRequestState::Open); + ws.r().ready_state.set(WebSocketRequestState::Open); //Check to see if ready_state is Closing or Closed and failed = true - means we failed the websocket //if so return without setting any states - let ready_state = ws_root.ready_state.get(); - let failed = ws_root.failed.get(); + let ready_state = ws.r().ready_state.get(); + let failed = ws.r().failed.get(); if failed && (ready_state == WebSocketRequestState::Closed || ready_state == WebSocketRequestState::Closing) { //Do nothing else. Let the close finish. - return Ok(Temporary::from_rooted(ws_root)); + return Ok(ws); } let (temp_sender, temp_receiver) = response.begin().split(); - let mut other_sender = ws_root.sender.borrow_mut(); - let mut other_receiver = ws_root.receiver.borrow_mut(); - *other_sender = Some(temp_sender); - *other_receiver = Some(temp_receiver); + *ws.r().sender.borrow_mut() = Some(temp_sender); + *ws.r().receiver.borrow_mut() = Some(temp_receiver); //Create everything necessary for starting the open asynchronous task, then begin the task. - let global_root = ws_root.global.root(); + let global_root = ws.r().global.root(); let addr: Trusted<WebSocket> = - Trusted::new(global_root.r().get_cx(), ws_root, global_root.r().script_chan().clone()); + Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone()); let open_task = box WebSocketTaskHandler::new(addr.clone(), WebSocketTask::Open); global_root.r().script_chan().send(ScriptMsg::RunnableMsg(open_task)).unwrap(); //TODO: Spawn thread here for receive loop @@ -188,15 +185,15 @@ impl WebSocket { it confirms the websocket is now closed. This requires the close event to be fired (dispatch_close fires the close event - see implementation below) */ - Ok(Temporary::from_rooted(ws_root)) + Ok(ws) } - pub fn Constructor(global: GlobalRef, url: DOMString) -> Fallible<Temporary<WebSocket>> { + pub fn Constructor(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> { WebSocket::new(global, url) } } -impl<'a> WebSocketMethods for JSRef<'a, WebSocket> { +impl<'a> WebSocketMethods for &'a WebSocket { event_handler!(open, GetOnopen, SetOnopen); event_handler!(close, GetOnclose, SetOnclose); event_handler!(error, GetOnerror, SetOnerror); @@ -301,19 +298,19 @@ impl WebSocketTaskHandler { /*TODO: Items 1, 3, 4, & 5 under "WebSocket connection is established" as specified here: https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol */ - let ws = self.addr.to_temporary().root(); //Get root + let ws = self.addr.root(); //Get root let ws = ws.r(); //Get websocket reference let global = ws.global.root(); let event = Event::new(global.r(), "open".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(ws); + EventCancelable::NotCancelable); + let target = EventTargetCast::from_ref(ws); event.r().fire(target); } fn dispatch_close(&self) { - let ws = self.addr.to_temporary().root(); + let ws = self.addr.root(); let ws = ws.r(); let global = ws.global.root(); ws.ready_state.set(WebSocketRequestState::Closed); @@ -326,8 +323,8 @@ impl WebSocketTaskHandler { let event = Event::new(global.r(), "error".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::Cancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(ws); + EventCancelable::Cancelable); + let target = EventTargetCast::from_ref(ws); event.r().fire(target); } let rsn = ws.reason.borrow(); @@ -341,9 +338,9 @@ impl WebSocketTaskHandler { EventCancelable::NotCancelable, ws.clean_close.get(), ws.code.get(), - rsn_clone).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(ws); - let event: JSRef<Event> = EventCast::from_ref(close_event.r()); + rsn_clone); + let target = EventTargetCast::from_ref(ws); + let event = EventCast::from_ref(close_event.r()); event.fire(target); } } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 5f1849c436c..da23196b434 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -13,8 +13,8 @@ use dom::bindings::global::global_object_for_js_object; use dom::bindings::error::{report_pending_exception, Fallible}; use dom::bindings::error::Error::InvalidCharacter; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, OptionalRootable}; -use dom::bindings::js::{Rootable, RootedReference, Temporary}; +use dom::bindings::js::{JS, Root, MutNullableHeap}; +use dom::bindings::js::RootedReference; use dom::bindings::num::Finite; use dom::bindings::utils::{GlobalStaticData, Reflectable, WindowProxyHandler}; use dom::browsercontext::BrowserContext; @@ -24,7 +24,7 @@ use dom::element::Element; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; use dom::location::Location; use dom::navigator::Navigator; -use dom::node::{window_from_node, Node, TrustedNodeAddress, NodeHelpers}; +use dom::node::{window_from_node, TrustedNodeAddress, NodeHelpers}; use dom::performance::Performance; use dom::screen::Screen; use dom::storage::Storage; @@ -49,11 +49,11 @@ use util::opts; use util::str::{DOMString,HTML_SPACE_CHARACTERS}; use euclid::{Point2D, Rect, Size2D}; -use js::jsapi::JS_EvaluateUCScript; -use js::jsapi::JSContext; -use js::jsapi::{JS_GC, JS_GetRuntime}; -use js::jsval::{JSVal, UndefinedValue}; -use js::rust::{Runtime, with_compartment}; +use js::jsapi::{Evaluate2, MutableHandleValue}; +use js::jsapi::{JSContext, HandleValue}; +use js::jsapi::{JS_GC, JS_GetRuntime, JSAutoCompartment, JSAutoRequest}; +use js::rust::Runtime; +use js::rust::CompileOptionsWrapper; use url::{Url, UrlParser}; use libc; @@ -324,7 +324,7 @@ pub fn base64_atob(input: DOMString) -> Fallible<DOMString> { } } -impl<'a> WindowMethods for JSRef<'a, Window> { +impl<'a> WindowMethods for &'a Window { // https://html.spec.whatwg.org/#dom-alert fn Alert(self, s: DOMString) { // Right now, just print to the console @@ -335,45 +335,45 @@ impl<'a> WindowMethods for JSRef<'a, Window> { self.script_chan.send(ScriptMsg::ExitWindow(self.id.clone())).unwrap(); } - fn Document(self) -> Temporary<Document> { + fn Document(self) -> Root<Document> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let context = self.browser_context(); context.as_ref().unwrap().active_document() } // https://html.spec.whatwg.org/#dom-location - fn Location(self) -> Temporary<Location> { - self.Document().root().r().Location() + fn Location(self) -> Root<Location> { + self.Document().r().Location() } // https://html.spec.whatwg.org/#dom-sessionstorage - fn SessionStorage(self) -> Temporary<Storage> { + fn SessionStorage(self) -> Root<Storage> { self.session_storage.or_init(|| Storage::new(&GlobalRef::Window(self), StorageType::Session)) } // https://html.spec.whatwg.org/#dom-localstorage - fn LocalStorage(self) -> Temporary<Storage> { + fn LocalStorage(self) -> Root<Storage> { self.local_storage.or_init(|| Storage::new(&GlobalRef::Window(self), StorageType::Local)) } - fn Console(self) -> Temporary<Console> { + fn Console(self) -> Root<Console> { self.console.or_init(|| Console::new(GlobalRef::Window(self))) } // https://html.spec.whatwg.org/#dom-frameelement - fn GetFrameElement(self) -> Option<Temporary<Element>> { + fn GetFrameElement(self) -> Option<Root<Element>> { // FIXME(https://github.com/rust-lang/rust/issues/23338) let context = self.browser_context(); context.as_ref().unwrap().frame_element() } // https://html.spec.whatwg.org/#dom-navigator - fn Navigator(self) -> Temporary<Navigator> { + fn Navigator(self) -> Root<Navigator> { self.navigator.or_init(|| Navigator::new(self)) } // https://html.spec.whatwg.org/#dom-windowtimers-settimeout - fn SetTimeout(self, _cx: *mut JSContext, callback: Function, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetTimeout(self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::FunctionTimerCallback(callback), args, timeout, @@ -383,7 +383,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { } // https://html.spec.whatwg.org/#dom-windowtimers-settimeout - fn SetTimeout_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetTimeout_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::StringTimerCallback(callback), args, timeout, @@ -398,7 +398,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { } // https://html.spec.whatwg.org/#dom-windowtimers-setinterval - fn SetInterval(self, _cx: *mut JSContext, callback: Function, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetInterval(self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::FunctionTimerCallback(callback), args, timeout, @@ -408,7 +408,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { } // https://html.spec.whatwg.org/#dom-windowtimers-setinterval - fn SetInterval_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetInterval_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::StringTimerCallback(callback), args, timeout, @@ -422,25 +422,25 @@ impl<'a> WindowMethods for JSRef<'a, Window> { self.ClearTimeout(handle); } - fn Window(self) -> Temporary<Window> { - Temporary::from_rooted(self) + fn Window(self) -> Root<Window> { + Root::from_ref(self) } - fn Self_(self) -> Temporary<Window> { + fn Self_(self) -> Root<Window> { self.Window() } // https://www.whatwg.org/html/#dom-frames - fn Frames(self) -> Temporary<Window> { + fn Frames(self) -> Root<Window> { self.Window() } // https://html.spec.whatwg.org/multipage/#dom-parent - fn Parent(self) -> Temporary<Window> { + fn Parent(self) -> Root<Window> { self.parent().unwrap_or(self.Window()) } - fn Performance(self) -> Temporary<Performance> { + fn Performance(self) -> Root<Performance> { self.performance.or_init(|| { Performance::new(self, self.navigation_start, self.navigation_start_precise) @@ -451,7 +451,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { event_handler!(unload, GetOnunload, SetOnunload); error_event_handler!(error, GetOnerror, SetOnerror); - fn Screen(self) -> Temporary<Screen> { + fn Screen(self) -> Root<Screen> { self.screen.or_init(|| Screen::new(self)) } @@ -475,8 +475,8 @@ impl<'a> WindowMethods for JSRef<'a, Window> { } /// http://w3c.github.io/animation-timing/#dom-windowanimationtiming-requestanimationframe - fn RequestAnimationFrame(self, callback: FrameRequestCallback) -> i32 { - let doc = self.Document().root(); + fn RequestAnimationFrame(self, callback: Rc<FrameRequestCallback>) -> i32 { + let doc = self.Document(); let callback = move |now: f64| { // TODO: @jdm The spec says that any exceptions should be suppressed; @@ -488,11 +488,11 @@ impl<'a> WindowMethods for JSRef<'a, Window> { /// http://w3c.github.io/animation-timing/#dom-windowanimationtiming-cancelanimationframe fn CancelAnimationFrame(self, ident: i32) { - let doc = self.Document().root(); + let doc = self.Document(); doc.r().cancel_animation_frame(ident); } - fn WebdriverCallback(self, cx: *mut JSContext, val: JSVal) { + fn WebdriverCallback(self, cx: *mut JSContext, val: HandleValue) { let rv = jsval_to_webdriver(cx, val); let opt_chan = self.webdriver_script_chan.borrow_mut().take(); if let Some(chan) = opt_chan { @@ -510,7 +510,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { pub trait WindowHelpers { fn clear_js_runtime(self); - fn init_browser_context(self, doc: JSRef<Document>, frame_element: Option<JSRef<Element>>); + fn init_browser_context(self, doc: &Document, frame_element: Option<&Element>); fn load_url(self, href: DOMString); fn handle_fire_timer(self, timer_id: TimerId); fn force_reflow(self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason); @@ -539,7 +539,7 @@ pub trait WindowHelpers { fn steal_resize_event(self) -> Option<WindowSizeData>; fn set_page_clip_rect_with_new_viewport(self, viewport: Rect<f32>) -> bool; fn set_devtools_wants_updates(self, value: bool); - fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>>; + fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Root<Window>>; fn thaw(self); fn freeze(self); fn need_emit_timeline_marker(self, timeline_type: TimelineMarkerType) -> bool; @@ -548,45 +548,49 @@ pub trait WindowHelpers { fn drop_devtools_timeline_markers(self); fn set_webdriver_script_chan(self, chan: Option<Sender<WebDriverJSResult>>); fn is_alive(self) -> bool; - fn parent(self) -> Option<Temporary<Window>>; + fn parent(self) -> Option<Root<Window>>; } pub trait ScriptHelpers { - fn evaluate_js_on_global_with_result(self, code: &str) -> JSVal; - fn evaluate_script_on_global_with_result(self, code: &str, filename: &str) -> JSVal; + fn evaluate_js_on_global_with_result(self, code: &str, + rval: MutableHandleValue); + fn evaluate_script_on_global_with_result(self, code: &str, filename: &str, + rval: MutableHandleValue); } -impl<'a, T: Reflectable> ScriptHelpers for JSRef<'a, T> { - fn evaluate_js_on_global_with_result(self, code: &str) -> JSVal { - self.evaluate_script_on_global_with_result(code, "") +impl<'a, T: Reflectable> ScriptHelpers for &'a T { + fn evaluate_js_on_global_with_result(self, code: &str, + rval: MutableHandleValue) { + self.evaluate_script_on_global_with_result(code, "", rval) } #[allow(unsafe_code)] - fn evaluate_script_on_global_with_result(self, code: &str, filename: &str) -> JSVal { + fn evaluate_script_on_global_with_result(self, code: &str, filename: &str, + rval: MutableHandleValue) { let this = self.reflector().get_jsobject(); - let cx = global_object_for_js_object(this).root().r().get_cx(); - let global = global_object_for_js_object(this).root().r().reflector().get_jsobject(); + let global = global_object_for_js_object(this.get()); + let cx = global.r().get_cx(); + let _ar = JSAutoRequest::new(cx); + let globalhandle = global.r().reflector().get_jsobject(); let code: Vec<u16> = code.utf16_units().collect(); - let mut rval = UndefinedValue(); let filename = CString::new(filename).unwrap(); - with_compartment(cx, global, || { - unsafe { - if JS_EvaluateUCScript(cx, global, code.as_ptr(), - code.len() as libc::c_uint, - filename.as_ptr(), 1, &mut rval) == 0 { - debug!("error evaluating JS string"); - report_pending_exception(cx, global); - } - rval + let _ac = JSAutoCompartment::new(cx, globalhandle.get()); + let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 0); + unsafe { + if Evaluate2(cx, options.ptr, code.as_ptr() as *const i16, + code.len() as libc::size_t, + rval) == 0 { + debug!("error evaluating JS string"); + report_pending_exception(cx, globalhandle.get()); } - }) + } } } -impl<'a> WindowHelpers for JSRef<'a, Window> { +impl<'a> WindowHelpers for &'a Window { fn clear_js_runtime(self) { - let document = self.Document().root(); + let document = self.Document(); NodeCast::from_ref(document.r()).teardown(); // The above code may not catch all DOM objects @@ -611,13 +615,13 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { /// /// TODO(pcwalton): Only wait for style recalc, since we have off-main-thread layout. fn force_reflow(self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason) { - let document = self.Document().root(); - let root = document.r().GetDocumentElement().root(); + let document = self.Document(); + let root = document.r().GetDocumentElement(); let root = match root.r() { Some(root) => root, None => return, }; - let root: JSRef<Node> = NodeCast::from_ref(root); + let root = NodeCast::from_ref(root); let window_size = match self.window_size.get() { Some(window_size) => window_size, @@ -682,14 +686,14 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { /// /// TODO(pcwalton): Only wait for style recalc, since we have off-main-thread layout. fn reflow(self, goal: ReflowGoal, query_type: ReflowQueryType, reason: ReflowReason) { - let document = self.Document().root(); - let root = document.r().GetDocumentElement().root(); + let document = self.Document(); + let root = document.r().GetDocumentElement(); let root = match root.r() { Some(root) => root, None => return, }; - let root: JSRef<Node> = NodeCast::from_ref(root); + let root = NodeCast::from_ref(root); if query_type == ReflowQueryType::NoQuery && !root.get_has_dirty_descendants() { debug!("root has no dirty descendants; avoiding reflow (reason {:?})", reason); return @@ -755,8 +759,10 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { self.window_size.set(Some(new_size)); } - fn init_browser_context(self, doc: JSRef<Document>, frame_element: Option<JSRef<Element>>) { - *self.browser_context.borrow_mut() = Some(BrowserContext::new(doc, frame_element)); + fn init_browser_context(self, doc: &Document, frame_element: Option<&Element>) { + let mut browser_context = self.browser_context.borrow_mut(); + *browser_context = Some(BrowserContext::new(doc, frame_element)); + (*browser_context).as_mut().unwrap().create_window_proxy(); } /// Commence a new URL load which will either replace this window or scroll to a fragment. @@ -800,7 +806,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { } fn get_url(self) -> Url { - let doc = self.Document().root(); + let doc = self.Document(); doc.r().url() } @@ -885,7 +891,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { } // https://html.spec.whatwg.org/multipage/#accessing-other-browsing-contexts - fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>> { + fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Root<Window>> { None } @@ -894,7 +900,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { // Push the document title to the compositor since we are // activating this document due to a navigation. - let document = self.Document().root(); + let document = self.Document(); document.r().title_changed(); } @@ -931,13 +937,12 @@ impl<'a> WindowHelpers for JSRef<'a, Window> { self.current_state.get() == WindowState::Alive } - fn parent(self) -> Option<Temporary<Window>> { + fn parent(self) -> Option<Root<Window>> { let browser_context = self.browser_context(); let browser_context = browser_context.as_ref().unwrap(); - browser_context.frame_element().map(|fe| { - let frame_element = fe.root(); - let window = window_from_node(frame_element.r()).root(); + browser_context.frame_element().map(|frame_element| { + let window = window_from_node(frame_element.r()); // FIXME(https://github.com/rust-lang/rust/issues/23338) let r = window.r(); let context = r.browser_context(); @@ -962,7 +967,7 @@ impl Window { id: PipelineId, parent_info: Option<(PipelineId, SubpageId)>, window_size: Option<WindowSizeData>) - -> Temporary<Window> { + -> Root<Window> { let layout_rpc: Box<LayoutRPC> = { let (rpc_send, rpc_recv) = channel(); let LayoutChan(ref lchan) = layout_chan; diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 774cf67e913..34e07a6ee91 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -9,11 +9,11 @@ use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast}; use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::error::Error::Syntax; use dom::bindings::global::{GlobalRef, GlobalField}; -use dom::bindings::js::{JSRef, Rootable, Temporary}; use dom::bindings::refcounted::Trusted; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflectable, reflect_dom_object}; +use dom::bindings::js::Root; use dom::window::WindowHelpers; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::errorevent::ErrorEvent; @@ -26,8 +26,9 @@ use devtools_traits::{DevtoolsControlMsg, DevtoolsPageInfo}; use util::str::DOMString; -use js::jsapi::JSContext; -use js::jsval::{JSVal, UndefinedValue}; +use js::jsapi::{JSContext, HandleValue, RootedValue}; +use js::jsapi::{JSAutoRequest, JSAutoCompartment}; +use js::jsval::UndefinedValue; use url::UrlParser; use std::borrow::ToOwned; @@ -54,14 +55,14 @@ impl Worker { } } - pub fn new(global: GlobalRef, sender: Sender<(TrustedWorkerAddress, ScriptMsg)>) -> Temporary<Worker> { + pub fn new(global: GlobalRef, sender: Sender<(TrustedWorkerAddress, ScriptMsg)>) -> Root<Worker> { reflect_dom_object(box Worker::new_inherited(global, sender), global, WorkerBinding::Wrap) } // https://www.whatwg.org/html/#dom-worker - pub fn Constructor(global: GlobalRef, script_url: DOMString) -> Fallible<Temporary<Worker>> { + pub fn Constructor(global: GlobalRef, script_url: DOMString) -> Fallible<Root<Worker>> { // Step 2-4. let worker_url = match UrlParser::new().base_url(&global.get_url()).parse(&script_url) { Ok(url) => url, @@ -71,7 +72,7 @@ impl Worker { let resource_task = global.resource_task(); let (sender, receiver) = channel(); - let worker = Worker::new(global, sender.clone()).root(); + let worker = Worker::new(global, sender.clone()); let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.script_chan()); if let Some(ref chan) = global.devtools_chan() { @@ -92,48 +93,50 @@ impl Worker { worker_url, global.pipeline(), global.devtools_chan(), worker_ref, resource_task, global.script_chan(), sender, receiver); - Ok(Temporary::from_rooted(worker.r())) + Ok(worker) } pub fn handle_message(address: TrustedWorkerAddress, data: StructuredCloneData) { - let worker = address.to_temporary().root(); + let worker = address.root(); let global = worker.r().global.root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(worker.r()); - - let message = data.read(global.r()); - MessageEvent::dispatch_jsval(target, global.r(), message); + let target = EventTargetCast::from_ref(worker.r()); + let _ar = JSAutoRequest::new(global.r().get_cx()); + let _ac = JSAutoCompartment::new(global.r().get_cx(), target.reflector().get_jsobject().get()); + let mut message = RootedValue::new(global.r().get_cx(), UndefinedValue()); + data.read(global.r(), message.handle_mut()); + MessageEvent::dispatch_jsval(target, global.r(), message.handle()); } pub fn dispatch_simple_error(address: TrustedWorkerAddress) { - let worker = address.to_temporary().root(); + let worker = address.root(); let global = worker.r().global.root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(worker.r()); + let target = EventTargetCast::from_ref(worker.r()); let event = Event::new(global.r(), "error".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable).root(); + EventCancelable::NotCancelable); event.r().fire(target); } pub fn handle_error_message(address: TrustedWorkerAddress, message: DOMString, filename: DOMString, lineno: u32, colno: u32) { - let worker = address.to_temporary().root(); + let worker = address.root(); let global = worker.r().global.root(); - let error = UndefinedValue(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(worker.r()); + let error = RootedValue::new(global.r().get_cx(), UndefinedValue()); + let target = EventTargetCast::from_ref(worker.r()); let errorevent = ErrorEvent::new(global.r(), "error".to_owned(), EventBubbles::Bubbles, EventCancelable::Cancelable, - message, filename, lineno, colno, error).root(); - let event: JSRef<Event> = EventCast::from_ref(errorevent.r()); + message, filename, lineno, colno, error.handle()); + let event = EventCast::from_ref(errorevent.r()); event.fire(target); } } -impl<'a> WorkerMethods for JSRef<'a, Worker> { - fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult { +impl<'a> WorkerMethods for &'a Worker { + fn PostMessage(self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { let data = try!(StructuredCloneData::write(cx, message)); let address = Trusted::new(cx, self, self.global.root().r().script_chan().clone()); self.sender.send((address, ScriptMsg::DOMMessage(data))).unwrap(); diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 0ae6e569875..363f2639960 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -8,10 +8,10 @@ use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeCast; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{Syntax, Network, JSFailed}; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, Temporary}; +use dom::bindings::js::{JS, Root, MutNullableHeap}; use dom::bindings::utils::Reflectable; use dom::console::Console; -use dom::dedicatedworkerglobalscope::{DedicatedWorkerGlobalScope, DedicatedWorkerGlobalScopeHelpers}; +use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScopeHelpers; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::workerlocation::WorkerLocation; use dom::workernavigator::WorkerNavigator; @@ -25,8 +25,7 @@ use msg::constellation_msg::{PipelineId, WorkerId}; use net_traits::{load_whole_resource, ResourceTask}; use util::str::DOMString; -use js::jsapi::JSContext; -use js::jsval::JSVal; +use js::jsapi::{JSContext, HandleValue}; use js::rust::Runtime; use url::{Url, UrlParser}; @@ -104,14 +103,14 @@ impl WorkerGlobalScope { } } -impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { +impl<'a> WorkerGlobalScopeMethods for &'a WorkerGlobalScope { // https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self - fn Self_(self) -> Temporary<WorkerGlobalScope> { - Temporary::from_rooted(self) + fn Self_(self) -> Root<WorkerGlobalScope> { + Root::from_ref(self) } // https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-location - fn Location(self) -> Temporary<WorkerLocation> { + fn Location(self) -> Root<WorkerLocation> { self.location.or_init(|| { WorkerLocation::new(self, self.worker_url.clone()) }) @@ -151,11 +150,11 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { } // https://html.spec.whatwg.org/multipage/#dom-worker-navigator - fn Navigator(self) -> Temporary<WorkerNavigator> { + fn Navigator(self) -> Root<WorkerNavigator> { self.navigator.or_init(|| WorkerNavigator::new(self)) } - fn Console(self) -> Temporary<Console> { + fn Console(self) -> Root<Console> { self.console.or_init(|| Console::new(GlobalRef::Worker(self))) } @@ -167,7 +166,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { base64_atob(atob) } - fn SetTimeout(self, _cx: *mut JSContext, callback: Function, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetTimeout(self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::FunctionTimerCallback(callback), args, timeout, @@ -176,7 +175,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { self.script_chan()) } - fn SetTimeout_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetTimeout_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::StringTimerCallback(callback), args, timeout, @@ -189,7 +188,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { self.timers.clear_timeout_or_interval(handle); } - fn SetInterval(self, _cx: *mut JSContext, callback: Function, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetInterval(self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::FunctionTimerCallback(callback), args, timeout, @@ -198,7 +197,7 @@ impl<'a> WorkerGlobalScopeMethods for JSRef<'a, WorkerGlobalScope> { self.script_chan()) } - fn SetInterval_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<JSVal>) -> i32 { + fn SetInterval_(self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { self.timers.set_timeout_or_interval(TimerCallback::StringTimerCallback(callback), args, timeout, @@ -221,9 +220,9 @@ pub trait WorkerGlobalScopeHelpers { fn get_cx(self) -> *mut JSContext; } -impl<'a> WorkerGlobalScopeHelpers for JSRef<'a, WorkerGlobalScope> { +impl<'a> WorkerGlobalScopeHelpers for &'a WorkerGlobalScope { fn script_chan(self) -> Box<ScriptChan+Send> { - let dedicated: Option<JSRef<DedicatedWorkerGlobalScope>> = + let dedicated = DedicatedWorkerGlobalScopeCast::to_ref(self); match dedicated { Some(dedicated) => dedicated.script_chan(), @@ -232,7 +231,7 @@ impl<'a> WorkerGlobalScopeHelpers for JSRef<'a, WorkerGlobalScope> { } fn pipeline(self) -> PipelineId { - let dedicated: Option<JSRef<DedicatedWorkerGlobalScope>> = + let dedicated = DedicatedWorkerGlobalScopeCast::to_ref(self); match dedicated { Some(dedicated) => dedicated.pipeline(), @@ -241,7 +240,7 @@ impl<'a> WorkerGlobalScopeHelpers for JSRef<'a, WorkerGlobalScope> { } fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>) { - let dedicated: Option<JSRef<DedicatedWorkerGlobalScope>> = + let dedicated = DedicatedWorkerGlobalScopeCast::to_ref(self); match dedicated { Some(dedicated) => dedicated.new_script_pair(), @@ -250,7 +249,7 @@ impl<'a> WorkerGlobalScopeHelpers for JSRef<'a, WorkerGlobalScope> { } fn process_event(self, msg: ScriptMsg) { - let dedicated: Option<JSRef<DedicatedWorkerGlobalScope>> = + let dedicated = DedicatedWorkerGlobalScopeCast::to_ref(self); match dedicated { Some(dedicated) => dedicated.process_event(msg), diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs index c8aa09cd750..ec56ad79015 100644 --- a/components/script/dom/workerlocation.rs +++ b/components/script/dom/workerlocation.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::WorkerLocationBinding; use dom::bindings::codegen::Bindings::WorkerLocationBinding::WorkerLocationMethods; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::global::GlobalRef; use dom::bindings::str::USVString; use dom::bindings::utils::{Reflector, reflect_dom_object}; @@ -28,14 +28,14 @@ impl WorkerLocation { } } - pub fn new(global: JSRef<WorkerGlobalScope>, url: Url) -> Temporary<WorkerLocation> { + pub fn new(global: &WorkerGlobalScope, url: Url) -> Root<WorkerLocation> { reflect_dom_object(box WorkerLocation::new_inherited(url), GlobalRef::Worker(global), WorkerLocationBinding::Wrap) } } -impl<'a> WorkerLocationMethods for JSRef<'a, WorkerLocation> { +impl<'a> WorkerLocationMethods for &'a WorkerLocation { fn Href(self) -> USVString { UrlHelper::Href(&self.url) } diff --git a/components/script/dom/workernavigator.rs b/components/script/dom/workernavigator.rs index 6a6a325ae39..0decb060cb3 100644 --- a/components/script/dom/workernavigator.rs +++ b/components/script/dom/workernavigator.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::WorkerNavigatorBinding; use dom::bindings::codegen::Bindings::WorkerNavigatorBinding::WorkerNavigatorMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::js::Root; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::navigatorinfo; use dom::workerglobalscope::WorkerGlobalScope; @@ -24,14 +24,14 @@ impl WorkerNavigator { } } - pub fn new(global: JSRef<WorkerGlobalScope>) -> Temporary<WorkerNavigator> { + pub fn new(global: &WorkerGlobalScope) -> Root<WorkerNavigator> { reflect_dom_object(box WorkerNavigator::new_inherited(), GlobalRef::Worker(global), WorkerNavigatorBinding::Wrap) } } -impl<'a> WorkerNavigatorMethods for JSRef<'a, WorkerNavigator> { +impl<'a> WorkerNavigatorMethods for &'a WorkerNavigator { fn Product(self) -> DOMString { navigatorinfo::Product() } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 5a4992a0061..95a70b0cc6c 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -14,8 +14,8 @@ use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::error::Error::{InvalidState, InvalidAccess}; use dom::bindings::error::Error::{Network, Syntax, Security, Abort, Timeout}; use dom::bindings::global::{GlobalField, GlobalRef, GlobalRoot}; -use dom::bindings::js::{JS, JSRef, MutNullableHeap, OptionalRootable}; -use dom::bindings::js::{Rootable, Temporary}; +use dom::bindings::js::{JS, MutNullableHeap}; +use dom::bindings::js::Root; use dom::bindings::refcounted::Trusted; use dom::bindings::str::ByteString; use dom::bindings::utils::{Reflectable, reflect_dom_object}; @@ -40,7 +40,7 @@ use hyper::http::RawStatus; use hyper::mime::{self, Mime}; use hyper::method::Method; -use js::jsapi::{JS_ParseJSON, JSContext}; +use js::jsapi::{JS_ParseJSON, JSContext, RootedValue}; use js::jsapi::JS_ClearPendingException; use js::jsval::{JSVal, NullValue, UndefinedValue}; @@ -154,7 +154,7 @@ impl XMLHttpRequest { ready_state: Cell::new(XMLHttpRequestState::Unsent), timeout: Cell::new(0u32), with_credentials: Cell::new(false), - upload: JS::from_rooted(XMLHttpRequestUpload::new(global)), + upload: JS::from_rooted(&XMLHttpRequestUpload::new(global)), response_url: "".to_owned(), status: Cell::new(0), status_text: DOMRefCell::new(ByteString::new(vec!())), @@ -181,14 +181,14 @@ impl XMLHttpRequest { response_status: Cell::new(Ok(())), } } - pub fn new(global: GlobalRef) -> Temporary<XMLHttpRequest> { + pub fn new(global: GlobalRef) -> Root<XMLHttpRequest> { reflect_dom_object(box XMLHttpRequest::new_inherited(global), global, XMLHttpRequestBinding::Wrap) } // https://xhr.spec.whatwg.org/#constructors - pub fn Constructor(global: GlobalRef) -> Fallible<Temporary<XMLHttpRequest>> { + pub fn Constructor(global: GlobalRef) -> Fallible<Root<XMLHttpRequest>> { Ok(XMLHttpRequest::new(global)) } @@ -209,7 +209,7 @@ impl XMLHttpRequest { fn response_available(&self, response: CORSResponse) { if response.network_error { let mut context = self.xhr.lock().unwrap(); - let xhr = context.xhr.to_temporary().root(); + let xhr = context.xhr.root(); xhr.r().process_partial_response(XHRProgress::Errored(context.gen_id, Network)); *context.sync_status.borrow_mut() = Some(Err(Network)); return; @@ -243,7 +243,7 @@ impl XMLHttpRequest { load_data: LoadData) { impl AsyncResponseListener for XHRContext { fn headers_available(&self, metadata: Metadata) { - let xhr = self.xhr.to_temporary().root(); + let xhr = self.xhr.root(); let rv = xhr.r().process_headers_available(self.cors_request.clone(), self.gen_id, metadata); @@ -254,12 +254,12 @@ impl XMLHttpRequest { fn data_available(&self, payload: Vec<u8>) { self.buf.borrow_mut().push_all(&payload); - let xhr = self.xhr.to_temporary().root(); + let xhr = self.xhr.root(); xhr.r().process_data_available(self.gen_id, self.buf.borrow().clone()); } fn response_complete(&self, status: Result<(), String>) { - let xhr = self.xhr.to_temporary().root(); + let xhr = self.xhr.root(); let rv = xhr.r().process_response_complete(self.gen_id, status); *self.sync_status.borrow_mut() = Some(rv); } @@ -267,7 +267,7 @@ impl XMLHttpRequest { impl PreInvoke for XHRContext { fn should_invoke(&self) -> bool { - let xhr = self.xhr.to_temporary().root(); + let xhr = self.xhr.root(); xhr.r().generation_id.get() == self.gen_id } } @@ -280,7 +280,7 @@ impl XMLHttpRequest { } } -impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { +impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest { event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange); // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate @@ -462,8 +462,8 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { } // https://xhr.spec.whatwg.org/#the-upload-attribute - fn Upload(self) -> Temporary<XMLHttpRequestUpload> { - Temporary::from_rooted(self.upload) + fn Upload(self) -> Root<XMLHttpRequestUpload> { + self.upload.root() } // https://xhr.spec.whatwg.org/#the-send()-method @@ -491,7 +491,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { if !self.sync.get() { // Step 8 let upload_target = self.upload.root(); - let event_target: JSRef<EventTarget> = EventTargetCast::from_ref(upload_target.r()); + let event_target = EventTargetCast::from_ref(upload_target.r()); if event_target.has_handlers() { self.upload_events.set(true); } @@ -669,33 +669,38 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { // https://xhr.spec.whatwg.org/#the-response-attribute #[allow(unsafe_code)] fn Response(self, cx: *mut JSContext) -> JSVal { + let mut rval = RootedValue::new(cx, UndefinedValue()); match self.response_type.get() { _empty | Text => { let ready_state = self.ready_state.get(); if ready_state == XMLHttpRequestState::Done || ready_state == XMLHttpRequestState::Loading { - self.text_response().to_jsval(cx) + self.text_response().to_jsval(cx, rval.handle_mut()); } else { - "".to_jsval(cx) + "".to_jsval(cx, rval.handle_mut()); } }, - _ if self.ready_state.get() != XMLHttpRequestState::Done => NullValue(), + _ if self.ready_state.get() != XMLHttpRequestState::Done => { + return NullValue() + }, Json => { let decoded = UTF_8.decode(&self.response.borrow(), DecoderTrap::Replace).unwrap().to_owned(); let decoded: Vec<u16> = decoded.utf16_units().collect(); - let mut vp = UndefinedValue(); unsafe { - if JS_ParseJSON(cx, decoded.as_ptr(), decoded.len() as u32, &mut vp) == 0 { + if JS_ParseJSON(cx, + decoded.as_ptr() as *const i16, + decoded.len() as u32, + rval.handle_mut()) == 0 { JS_ClearPendingException(cx); return NullValue(); } } - vp } _ => { // XXXManishearth handle other response types - self.response.borrow().to_jsval(cx) + self.response.borrow().to_jsval(cx, rval.handle_mut()); } } + rval.ptr } // https://xhr.spec.whatwg.org/#the-responsetext-attribute @@ -712,8 +717,8 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { } // https://xhr.spec.whatwg.org/#the-responsexml-attribute - fn GetResponseXML(self) -> Option<Temporary<Document>> { - self.response_xml.get().map(Temporary::from_rooted) + fn GetResponseXML(self) -> Option<Root<Document>> { + self.response_xml.get().map(Root::from_rooted) } } @@ -731,7 +736,7 @@ pub type TrustedXHRAddress = Trusted<XMLHttpRequest>; trait PrivateXMLHttpRequestHelpers { fn change_ready_state(self, XMLHttpRequestState); - fn process_headers_available(&self, cors_request: Option<CORSRequest>, + fn process_headers_available(self, cors_request: Option<CORSRequest>, gen_id: GenerationId, metadata: Metadata) -> Result<(), Error>; fn process_data_available(self, gen_id: GenerationId, payload: Vec<u8>); fn process_response_complete(self, gen_id: GenerationId, status: Result<(), String>) -> ErrorResult; @@ -750,7 +755,7 @@ trait PrivateXMLHttpRequestHelpers { global: GlobalRef) -> ErrorResult; } -impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { +impl<'a> PrivateXMLHttpRequestHelpers for &'a XMLHttpRequest { fn change_ready_state(self, rs: XMLHttpRequestState) { assert!(self.ready_state.get() != rs); self.ready_state.set(rs); @@ -758,12 +763,12 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { let event = Event::new(global.r(), "readystatechange".to_owned(), EventBubbles::DoesNotBubble, - EventCancelable::Cancelable).root(); - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + EventCancelable::Cancelable); + let target = EventTargetCast::from_ref(self); event.r().fire(target); } - fn process_headers_available(&self, cors_request: Option<CORSRequest>, + fn process_headers_available(self, cors_request: Option<CORSRequest>, gen_id: GenerationId, metadata: Metadata) -> Result<(), Error> { match cors_request { Some(ref req) => { @@ -943,13 +948,13 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { let progressevent = ProgressEvent::new(global.r(), type_, false, false, total.is_some(), loaded, - total.unwrap_or(0)).root(); - let target: JSRef<EventTarget> = if upload { + total.unwrap_or(0)); + let target = if upload { EventTargetCast::from_ref(upload_target.r()) } else { EventTargetCast::from_ref(self) }; - let event: JSRef<Event> = EventCast::from_ref(progressevent.r()); + let event = EventCast::from_ref(progressevent.r()); event.fire(target); } @@ -974,7 +979,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> { impl Runnable for XHRTimeout { fn handler(self: Box<XHRTimeout>) { let this = *self; - let xhr = this.xhr.to_temporary().root(); + let xhr = this.xhr.root(); if xhr.r().ready_state.get() != XMLHttpRequestState::Done { xhr.r().process_partial_response(XHRProgress::Errored(this.gen_id, Timeout)); } @@ -1137,7 +1142,7 @@ impl Extractable for SendParam { }, eURLSearchParams(ref usp) => { // Default encoding is UTF-8. - usp.root().r().serialize(None).as_bytes().to_owned() + usp.r().serialize(None).as_bytes().to_owned() }, } } diff --git a/components/script/dom/xmlhttprequesteventtarget.rs b/components/script/dom/xmlhttprequesteventtarget.rs index 2457f192883..e2ce511450c 100644 --- a/components/script/dom/xmlhttprequesteventtarget.rs +++ b/components/script/dom/xmlhttprequesteventtarget.rs @@ -6,7 +6,6 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::XMLHttpRequestEventTargetBinding::XMLHttpRequestEventTargetMethods; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::codegen::InheritTypes::XMLHttpRequestEventTargetDerived; -use dom::bindings::js::JSRef; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; #[derive(Copy, Clone, PartialEq)] @@ -43,7 +42,7 @@ impl XMLHttpRequestEventTargetDerived for EventTarget { } -impl<'a> XMLHttpRequestEventTargetMethods for JSRef<'a, XMLHttpRequestEventTarget> { +impl<'a> XMLHttpRequestEventTargetMethods for &'a XMLHttpRequestEventTarget { event_handler!(loadstart,GetOnloadstart, SetOnloadstart); event_handler!(progress, GetOnprogress, SetOnprogress); event_handler!(abort, GetOnabort, SetOnabort); diff --git a/components/script/dom/xmlhttprequestupload.rs b/components/script/dom/xmlhttprequestupload.rs index 61004299b84..0c864fdd3c9 100644 --- a/components/script/dom/xmlhttprequestupload.rs +++ b/components/script/dom/xmlhttprequestupload.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::InheritTypes::XMLHttpRequestUploadDerived; use dom::bindings::codegen::Bindings::XMLHttpRequestUploadBinding; use dom::bindings::global::GlobalRef; -use dom::bindings::js::Temporary; +use dom::bindings::js::Root; use dom::bindings::utils::reflect_dom_object; use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget; @@ -23,7 +23,7 @@ impl XMLHttpRequestUpload { XMLHttpRequestEventTargetTypeId::XMLHttpRequestUpload) } } - pub fn new(global: GlobalRef) -> Temporary<XMLHttpRequestUpload> { + pub fn new(global: GlobalRef) -> Root<XMLHttpRequestUpload> { reflect_dom_object(box XMLHttpRequestUpload::new_inherited(), global, XMLHttpRequestUploadBinding::Wrap) diff --git a/components/script/lib.rs b/components/script/lib.rs index 6836895d5e7..8f693f7782d 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -72,3 +72,10 @@ pub mod clipboard_provider; mod devtools; mod horribly_inefficient_timers; mod webdriver_handlers; + +#[allow(unsafe_code)] +pub fn init() { + unsafe { + js::jsapi::JS_Init(); + } +} diff --git a/components/script/page.rs b/components/script/page.rs index 404cf20de6b..9ef95429ec9 100644 --- a/components/script/page.rs +++ b/components/script/page.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::cell::DOMRefCell; -use dom::bindings::js::{JS, Temporary, Unrooted}; +use dom::bindings::js::{JS, Root}; use dom::document::{Document, DocumentHelpers}; use dom::node::NodeHelpers; use dom::window::Window; @@ -75,16 +75,12 @@ impl Page { self.id } - pub fn window(&self) -> Temporary<Window> { - Temporary::from_rooted(self.frame.borrow().as_ref().unwrap().window.clone()) + pub fn window(&self) -> Root<Window> { + self.frame.borrow().as_ref().unwrap().window.root() } - pub fn window_for_script_deallocation(&self) -> Unrooted<Window> { - Unrooted::from_js(self.frame.borrow().as_ref().unwrap().window) - } - - pub fn document(&self) -> Temporary<Document> { - Temporary::from_rooted(self.frame.borrow().as_ref().unwrap().document.clone()) + pub fn document(&self) -> Root<Document> { + self.frame.borrow().as_ref().unwrap().document.root() } // must handle root case separately diff --git a/components/script/parse/html.rs b/components/script/parse/html.rs index a9e125f7da9..d7fd0946995 100644 --- a/components/script/parse/html.rs +++ b/components/script/parse/html.rs @@ -12,8 +12,8 @@ use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentTypeCast}; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLScriptElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, NodeCast}; use dom::bindings::codegen::InheritTypes::ProcessingInstructionCast; -use dom::bindings::js::{JS, JSRef, OptionalRootable, Root, Rootable}; -use dom::bindings::js::{RootedReference, Temporary}; +use dom::bindings::js::{JS, Root}; +use dom::bindings::js::{RootedReference}; use dom::bindings::trace::RootedVec; use dom::characterdata::{CharacterDataHelpers, CharacterDataTypeId}; use dom::comment::Comment; @@ -25,7 +25,6 @@ use dom::htmlscriptelement::HTMLScriptElement; use dom::htmlscriptelement::HTMLScriptElementHelpers; use dom::node::{Node, NodeHelpers, NodeTypeId}; use dom::node::{document_from_node, window_from_node}; -use dom::processinginstruction::ProcessingInstruction; use dom::processinginstruction::ProcessingInstructionHelpers; use dom::servohtmlparser; use dom::servohtmlparser::{ServoHTMLParser, FragmentContext}; @@ -47,17 +46,17 @@ use html5ever::tree_builder::{TreeSink, QuirksMode, NodeOrText, AppendNode, Appe use string_cache::QualName; trait SinkHelpers { - fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Temporary<Node>; + fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Root<Node>; } impl SinkHelpers for servohtmlparser::Sink { - fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Temporary<Node> { + fn get_or_create(&self, child: NodeOrText<JS<Node>>) -> Root<Node> { match child { - AppendNode(n) => Temporary::from_rooted(n), + AppendNode(n) => n.root(), AppendText(t) => { let doc = self.document.root(); let text = Text::new(t, doc.r()); - NodeCast::from_temporary(text) + NodeCast::from_root(text) } } } @@ -67,8 +66,8 @@ impl<'a> TreeSink for servohtmlparser::Sink { type Handle = JS<Node>; fn get_document(&mut self) -> JS<Node> { let doc = self.document.root(); - let node: JSRef<Node> = NodeCast::from_ref(doc.r()); - JS::from_rooted(node) + let node = NodeCast::from_ref(doc.r()); + JS::from_ref(node) } fn same_node(&self, x: JS<Node>, y: JS<Node>) -> bool { @@ -77,7 +76,7 @@ impl<'a> TreeSink for servohtmlparser::Sink { fn elem_name(&self, target: JS<Node>) -> QualName { let node: Root<Node> = target.root(); - let elem: JSRef<Element> = ElementCast::to_ref(node.r()) + let elem = ElementCast::to_ref(node.r()) .expect("tried to get name of non-Element in HTML parsing"); QualName { ns: elem.namespace().clone(), @@ -89,21 +88,21 @@ impl<'a> TreeSink for servohtmlparser::Sink { -> JS<Node> { let doc = self.document.root(); let elem = Element::create(name, None, doc.r(), - ElementCreator::ParserCreated).root(); + ElementCreator::ParserCreated); for attr in attrs.into_iter() { elem.r().set_attribute_from_parser(attr.name, attr.value, None); } - let node: JSRef<Node> = NodeCast::from_ref(elem.r()); - JS::from_rooted(node) + let node = NodeCast::from_ref(elem.r()); + JS::from_ref(node) } fn create_comment(&mut self, text: String) -> JS<Node> { let doc = self.document.root(); let comment = Comment::new(text, doc.r()); - let node: Root<Node> = NodeCast::from_temporary(comment).root(); - JS::from_rooted(node.r()) + let node = NodeCast::from_root(comment); + JS::from_rooted(&node) } fn append_before_sibling(&mut self, @@ -112,11 +111,11 @@ impl<'a> TreeSink for servohtmlparser::Sink { // If there is no parent, return the node to the parser. let sibling: Root<Node> = sibling.root(); let parent = match sibling.r().GetParentNode() { - Some(p) => p.root(), + Some(p) => p, None => return Err(new_node), }; - let child = self.get_or_create(new_node).root(); + let child = self.get_or_create(new_node); assert!(parent.r().InsertBefore(child.r(), Some(sibling.r())).is_ok()); Ok(()) } @@ -132,7 +131,7 @@ impl<'a> TreeSink for servohtmlparser::Sink { fn append(&mut self, parent: JS<Node>, child: NodeOrText<JS<Node>>) { let parent: Root<Node> = parent.root(); - let child = self.get_or_create(child).root(); + let child = self.get_or_create(child); // FIXME(#3701): Use a simpler algorithm and merge adjacent text nodes assert!(parent.r().AppendChild(child.r()).is_ok()); @@ -140,16 +139,16 @@ impl<'a> TreeSink for servohtmlparser::Sink { fn append_doctype_to_document(&mut self, name: String, public_id: String, system_id: String) { let doc = self.document.root(); - let doc_node: JSRef<Node> = NodeCast::from_ref(doc.r()); + let doc_node = NodeCast::from_ref(doc.r()); let doctype = DocumentType::new(name, Some(public_id), Some(system_id), doc.r()); - let node: Root<Node> = NodeCast::from_temporary(doctype).root(); + let node: Root<Node> = NodeCast::from_root(doctype); assert!(doc_node.AppendChild(node.r()).is_ok()); } fn add_attrs_if_missing(&mut self, target: JS<Node>, attrs: Vec<Attribute>) { let node: Root<Node> = target.root(); - let elem: JSRef<Element> = ElementCast::to_ref(node.r()) + let elem = ElementCast::to_ref(node.r()) .expect("tried to set attrs on non-Element in HTML parsing"); for attr in attrs.into_iter() { elem.set_attribute_from_parser(attr.name, attr.value, None); @@ -158,20 +157,20 @@ impl<'a> TreeSink for servohtmlparser::Sink { fn remove_from_parent(&mut self, target: JS<Node>) { let node = target.root(); - if let Some(ref parent) = node.r().GetParentNode().root() { + if let Some(ref parent) = node.r().GetParentNode() { parent.r().RemoveChild(node.r()).unwrap(); } } fn mark_script_already_started(&mut self, node: JS<Node>) { let node: Root<Node> = node.root(); - let script: Option<JSRef<HTMLScriptElement>> = HTMLScriptElementCast::to_ref(node.r()); + let script: Option<&HTMLScriptElement> = HTMLScriptElementCast::to_ref(node.r()); script.map(|script| script.mark_already_started()); } fn complete_script(&mut self, node: JS<Node>) -> NextParserState { let node: Root<Node> = node.root(); - let script: Option<JSRef<HTMLScriptElement>> = HTMLScriptElementCast::to_ref(node.r()); + let script: Option<&HTMLScriptElement> = HTMLScriptElementCast::to_ref(node.r()); if let Some(script) = script { return script.prepare(); } @@ -183,20 +182,20 @@ impl<'a> TreeSink for servohtmlparser::Sink { let new_parent = new_parent.r(); let old_parent = node.root(); let old_parent = old_parent.r(); - while let Some(ref child) = old_parent.GetFirstChild().root() { + while let Some(ref child) = old_parent.GetFirstChild() { new_parent.AppendChild(child.r()).unwrap(); } } } -impl<'a> Serializable for JSRef<'a, Node> { +impl<'a> Serializable for &'a Node { fn serialize<'wr, Wr: Write>(&self, serializer: &mut Serializer<'wr, Wr>, traversal_scope: TraversalScope) -> io::Result<()> { let node = *self; match (traversal_scope, node.type_id()) { (_, NodeTypeId::Element(..)) => { - let elem: JSRef<Element> = ElementCast::to_ref(node).unwrap(); + let elem = ElementCast::to_ref(node).unwrap(); let name = QualName::new(elem.namespace().clone(), elem.local_name().clone()); if traversal_scope == IncludeNode { @@ -215,7 +214,6 @@ impl<'a> Serializable for JSRef<'a, Node> { } for handle in node.children() { - let handle = handle.root(); try!(handle.r().serialize(serializer, IncludeNode)); } @@ -227,7 +225,6 @@ impl<'a> Serializable for JSRef<'a, Node> { (ChildrenOnly, NodeTypeId::Document) => { for handle in node.children() { - let handle = handle.root(); try!(handle.r().serialize(serializer, IncludeNode)); } Ok(()) @@ -236,7 +233,7 @@ impl<'a> Serializable for JSRef<'a, Node> { (ChildrenOnly, _) => Ok(()), (IncludeNode, NodeTypeId::DocumentType) => { - let doctype: JSRef<DocumentType> = DocumentTypeCast::to_ref(node).unwrap(); + let doctype = DocumentTypeCast::to_ref(node).unwrap(); serializer.write_doctype(&doctype.name()) }, @@ -251,7 +248,7 @@ impl<'a> Serializable for JSRef<'a, Node> { }, (IncludeNode, NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction)) => { - let pi: JSRef<ProcessingInstruction> = ProcessingInstructionCast::to_ref(node).unwrap(); + let pi = ProcessingInstructionCast::to_ref(node).unwrap(); let data = CharacterDataCast::from_ref(pi).data(); serializer.write_processing_instruction(&pi.target(), &data) }, @@ -268,7 +265,7 @@ pub enum ParseContext<'a> { Owner(Option<PipelineId>), } -pub fn parse_html(document: JSRef<Document>, +pub fn parse_html(document: &Document, input: String, url: &Url, context: ParseContext) { @@ -277,16 +274,16 @@ pub fn parse_html(document: JSRef<Document>, ServoHTMLParser::new(Some(url.clone()), document, owner), ParseContext::Fragment(fc) => ServoHTMLParser::new_for_fragment(Some(url.clone()), document, fc), - }.root(); + }; parser.r().parse_chunk(input); } // https://html.spec.whatwg.org/multipage/#parsing-html-fragments -pub fn parse_html_fragment(context_node: JSRef<Node>, +pub fn parse_html_fragment(context_node: &Node, input: DOMString, output: &mut RootedVec<JS<Node>>) { - let window = window_from_node(context_node).root(); - let context_document = document_from_node(context_node).root(); + let window = window_from_node(context_node); + let context_document = document_from_node(context_node); let context_document = context_document.r(); let url = context_document.url(); @@ -296,14 +293,13 @@ pub fn parse_html_fragment(context_node: JSRef<Node>, IsHTMLDocument::HTMLDocument, None, None, DocumentSource::FromParser, - loader).root(); + loader); // Step 2. document.r().set_quirks_mode(context_document.quirks_mode()); // Step 11. let form = context_node.inclusive_ancestors() - .map(|element| element.root()) .find(|element| element.r().is_htmlformelement()); let fragment_context = FragmentContext { context_elem: context_node, @@ -312,9 +308,9 @@ pub fn parse_html_fragment(context_node: JSRef<Node>, parse_html(document.r(), input, &url, ParseContext::Fragment(fragment_context)); // Step 14. - let root_element = document.r().GetDocumentElement().expect("no document element").root(); - let root_node: JSRef<Node> = NodeCast::from_ref(root_element.r()); + let root_element = document.r().GetDocumentElement().expect("no document element"); + let root_node = NodeCast::from_ref(root_element.r()); for child in root_node.children() { - output.push(JS::from_rooted(child)); + output.push(JS::from_rooted(&child)); } } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index df424807c56..5e482bf4056 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -25,20 +25,18 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLIFrameElementCast, NodeCast, EventCast}; use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::conversions::StringificationBehavior; -use dom::bindings::js::{JS, JSRef, OptionalRootable, RootCollection}; -use dom::bindings::js::{RootCollectionPtr, Rootable, RootedReference}; -use dom::bindings::js::Temporary; -use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference}; +use dom::bindings::js::{JS, RootCollection, trace_roots}; +use dom::bindings::js::{RootCollectionPtr, Root, RootedReference}; +use dom::bindings::refcounted::{LiveDOMReferences, Trusted, TrustedReference, trace_refcounted_objects}; use dom::bindings::structuredclone::StructuredCloneData; -use dom::bindings::trace::{JSTraceable, trace_collections, RootedVec}; -use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; +use dom::bindings::trace::{JSTraceable, trace_traceables, RootedVec}; +use dom::bindings::utils::{WRAP_CALLBACKS, DOM_CALLBACKS}; use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentProgressHandler, DocumentProgressTask, DocumentSource, MouseEventType}; use dom::element::{Element, AttributeHandlers}; -use dom::event::{Event, EventHelpers, EventBubbles, EventCancelable}; +use dom::event::{EventHelpers, EventBubbles, EventCancelable}; use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementHelpers}; use dom::uievent::UIEvent; -use dom::eventtarget::EventTarget; use dom::node::{Node, NodeHelpers, NodeDamage, window_from_node}; use dom::servohtmlparser::{ServoHTMLParser, ParserContext}; use dom::window::{Window, WindowHelpers, ScriptHelpers, ReflowReason}; @@ -80,9 +78,11 @@ use util::task_state; use euclid::Rect; use euclid::point::Point2D; use hyper::header::{LastModified, Headers}; -use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetExtraGCRootsTracer}; -use js::jsapi::{JSContext, JSRuntime, JSObject, JSTracer}; -use js::jsapi::{JS_SetGCCallback, JSGCStatus, JSGC_BEGIN, JSGC_END}; +use js::jsapi::{JS_SetWrapObjectCallbacks, JS_AddExtraGCRootsTracer, DisableIncrementalGC}; +use js::jsapi::{JSContext, JSRuntime, JSTracer}; +use js::jsapi::{JS_SetGCCallback, JSGCStatus, JSAutoRequest, SetDOMCallbacks}; +use js::jsapi::{SetDOMProxyInformation, DOMProxyShadowsResult, HandleObject, HandleId, RootedValue}; +use js::jsval::UndefinedValue; use js::rust::Runtime; use url::Url; @@ -113,7 +113,8 @@ unsafe extern fn trace_rust_roots(tr: *mut JSTracer, _data: *mut libc::c_void) { } }); - trace_collections(tr); + trace_traceables(tr); + trace_roots(tr); } /// A document load that is in the process of fetching the requested resource. Contains @@ -353,8 +354,8 @@ impl<'a> Drop for ScriptMemoryFailsafe<'a> { unsafe { let page = owner.page.borrow_for_script_deallocation(); for page in page.iter() { - let window = page.window_for_script_deallocation(); - (*window.unsafe_get()).clear_js_runtime_for_script_deallocation(); + let window = page.window(); + window.r().clear_js_runtime_for_script_deallocation(); } } } @@ -393,6 +394,8 @@ impl ScriptTaskFactory for ScriptTask { let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); spawn_named_with_send_on_failure(format!("ScriptTask {:?}", id), task_state::SCRIPT, move || { + let roots = RootCollection::new(); + let _stack_roots_tls = StackRootTLS::new(&roots); let script_task = ScriptTask::new(box compositor as Box<ScriptListener>, script_port, NonWorkerScriptChan(script_chan), @@ -407,6 +410,7 @@ impl ScriptTaskFactory for ScriptTask { SCRIPT_TASK_ROOT.with(|root| { *root.borrow_mut() = Some(&script_task as *const _); }); + let mut failsafe = ScriptMemoryFailsafe::new(&script_task); let new_load = InProgressLoad::new(id, parent_info, layout_chan, window_size, @@ -421,17 +425,22 @@ impl ScriptTaskFactory for ScriptTask { } } -unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus) { +unsafe extern "C" fn debug_gc_callback(_rt: *mut JSRuntime, status: JSGCStatus, _data: *mut libc::c_void) { match status { - JSGC_BEGIN => task_state::enter(task_state::IN_GC), - JSGC_END => task_state::exit(task_state::IN_GC), - _ => (), + JSGCStatus::JSGC_BEGIN => task_state::enter(task_state::IN_GC), + JSGCStatus::JSGC_END => task_state::exit(task_state::IN_GC), } } +unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext, + _object: HandleObject, _id: HandleId) -> DOMProxyShadowsResult { + // XXX implement me + return DOMProxyShadowsResult::ShadowCheckFailed; +} + impl ScriptTask { pub fn page_fetch_complete(id: PipelineId, subpage: Option<SubpageId>, metadata: Metadata) - -> Option<Temporary<ServoHTMLParser>> { + -> Option<Root<ServoHTMLParser>> { SCRIPT_TASK_ROOT.with(|root| { let script_task = unsafe { &*root.borrow().unwrap() }; script_task.handle_page_fetch_complete(id, subpage, metadata) @@ -467,25 +476,10 @@ impl ScriptTask { devtools_chan: Option<DevtoolsControlChan>) -> ScriptTask { let runtime = ScriptTask::new_rt_and_cx(); - let wrap_for_same_compartment = wrap_for_same_compartment as - unsafe extern "C" fn(*mut JSContext, *mut JSObject) -> *mut JSObject; - let pre_wrap = pre_wrap as - unsafe extern fn(*mut JSContext, *mut JSObject, *mut JSObject, - libc::c_uint) -> *mut JSObject; unsafe { - // JS_SetWrapObjectCallbacks clobbers the existing wrap callback, - // and JSCompartment::wrap crashes if that happens. The only way - // to retrieve the default callback is as the result of - // JS_SetWrapObjectCallbacks, which is why we call it twice. - let callback = JS_SetWrapObjectCallbacks(runtime.rt(), - None, - Some(wrap_for_same_compartment), - None); JS_SetWrapObjectCallbacks(runtime.rt(), - callback, - Some(wrap_for_same_compartment), - Some(pre_wrap)); + &WRAP_CALLBACKS); } let (devtools_sender, devtools_receiver) = channel(); @@ -525,17 +519,24 @@ impl ScriptTask { let runtime = Runtime::new(); unsafe { - JS_SetExtraGCRootsTracer(runtime.rt(), Some(trace_rust_roots), ptr::null_mut()); + JS_AddExtraGCRootsTracer(runtime.rt(), Some(trace_rust_roots), ptr::null_mut()); + JS_AddExtraGCRootsTracer(runtime.rt(), Some(trace_refcounted_objects), ptr::null_mut()); } // Needed for debug assertions about whether GC is running. if cfg!(debug_assertions) { unsafe { - JS_SetGCCallback(runtime.rt(), - Some(debug_gc_callback as unsafe extern "C" fn(*mut JSRuntime, JSGCStatus))); + JS_SetGCCallback(runtime.rt(), Some(debug_gc_callback), ptr::null_mut()); } } + unsafe { + SetDOMProxyInformation(ptr::null(), 0, Some(shadow_check_callback)); + SetDOMCallbacks(runtime.rt(), &DOM_CALLBACKS); + // Pre barriers aren't working correctly at the moment + DisableIncrementalGC(runtime.rt()); + } + runtime } @@ -558,9 +559,6 @@ impl ScriptTask { /// Handle incoming control messages. fn handle_msgs(&self) -> bool { - let roots = RootCollection::new(); - let _stack_roots_tls = StackRootTLS::new(&roots); - // Handle pending resize events. // Gather them first to avoid a double mut borrow on self. let mut resizes = vec!(); @@ -570,7 +568,7 @@ impl ScriptTask { if let Some(page) = page.as_ref() { for page in page.iter() { // Only process a resize if layout is idle. - let window = page.window().root(); + let window = page.window(); if window.r().layout_is_idle() { let resize_event = window.r().steal_resize_event(); match resize_event { @@ -699,7 +697,7 @@ impl ScriptTask { let page = self.page.borrow(); if let Some(page) = page.as_ref() { for page in page.iter() { - let window = page.window().root(); + let window = page.window(); let pending_reflows = window.r().get_pending_reflow_count(); if pending_reflows > 0 { window.r().reflow(ReflowGoal::ForDisplay, @@ -848,7 +846,7 @@ impl ScriptTask { let page = self.page.borrow(); if let Some(ref page) = page.as_ref() { if let Some(ref page) = page.find(id) { - let window = page.window().root(); + let window = page.window(); window.r().set_resize_event(size); return; } @@ -865,7 +863,7 @@ impl ScriptTask { let page = self.page.borrow(); if let Some(page) = page.as_ref() { if let Some(ref inner_page) = page.find(id) { - let window = inner_page.window().root(); + let window = inner_page.window(); if window.r().set_page_clip_rect_with_new_viewport(rect) { let page = get_page(page, id); self.rebuild_and_force_reflow(&*page, ReflowReason::Viewport); @@ -884,7 +882,7 @@ impl ScriptTask { /// Handle a request to load a page in a new child frame of an existing page. fn handle_resource_loaded(&self, pipeline: PipelineId, load: LoadType) { let page = get_page(&self.root_page(), pipeline); - let doc = page.document().root(); + let doc = page.document(); doc.r().finish_load(load); } @@ -899,7 +897,7 @@ impl ScriptTask { // If not in pending loads, the page should exist by now. let page = self.root_page(); let page = page.find(pipeline_id).expect("GetCurrentState sent to nonexistent pipeline"); - let doc = page.document().root(); + let doc = page.document(); // Check if document load event has fired. If the document load // event has fired, this also guarantees that the first reflow @@ -913,7 +911,7 @@ impl ScriptTask { // Checks if the html element has reftest-wait attribute present. // See http://testthewebforward.org/docs/reftests.html - let html_element = doc.r().GetDocumentElement().root(); + let html_element = doc.r().GetDocumentElement(); let reftest_wait = html_element.r().map_or(false, |elem| elem.has_class(&Atom::from_slice("reftest-wait"))); if reftest_wait { return ScriptState::DocumentLoading; @@ -936,7 +934,7 @@ impl ScriptTask { whose parent has a PipelineId which does not correspond to a pipeline in the script task's page tree. This is a bug."); - let parent_window = parent_page.window().root(); + let parent_window = parent_page.window(); let chan = layout_chan.downcast_ref::<Sender<layout_interface::Msg>>().unwrap(); let layout_chan = LayoutChan(chan.clone()); // Kick off the fetch for the new resource. @@ -948,7 +946,7 @@ impl ScriptTask { fn handle_loads_complete(&self, pipeline: PipelineId) { let page = get_page(&self.root_page(), pipeline); - let doc = page.document().root(); + let doc = page.document(); let doc = doc.r(); if doc.loader().is_blocked() { return; @@ -970,7 +968,7 @@ impl ScriptTask { let page = self.root_page(); let page = page.find(id).expect("ScriptTask: received fire timer msg for a pipeline ID not associated with this script task. This is a bug."); - let window = page.window().root(); + let window = page.window(); window.r().handle_fire_timer(timer_id); } @@ -979,7 +977,7 @@ impl ScriptTask { let page = self.root_page(); let page = page.find(id).expect("ScriptTask: received freeze msg for a pipeline ID not associated with this script task. This is a bug."); - let window = page.window().root(); + let window = page.window(); window.r().freeze(); } @@ -994,7 +992,7 @@ impl ScriptTask { self.rebuild_and_force_reflow(&*page, ReflowReason::CachedPageNeededReflow); } - let window = page.window().root(); + let window = page.window(); window.r().thaw(); } @@ -1004,11 +1002,11 @@ impl ScriptTask { let borrowed_page = self.root_page(); let page = borrowed_page.find(parent_pipeline_id).unwrap(); - let doc = page.document().root(); - let frame_element = self.find_iframe(doc.r(), subpage_id).root(); + let doc = page.document(); + let frame_element = self.find_iframe(doc.r(), subpage_id); if let Some(ref frame_element) = frame_element { - let element: JSRef<Element> = ElementCast::from_ref(frame_element.r()); + let element = ElementCast::from_ref(frame_element.r()); doc.r().begin_focus_transaction(); doc.r().request_focus(element); doc.r().commit_focus_transaction(FocusType::Parent); @@ -1024,9 +1022,9 @@ impl ScriptTask { let borrowed_page = self.root_page(); let frame_element = borrowed_page.find(parent_pipeline_id).and_then(|page| { - let doc = page.document().root(); + let doc = page.document(); self.find_iframe(doc.r(), subpage_id) - }).root(); + }); if let Some(ref frame_element) = frame_element { frame_element.r().dispatch_mozbrowser_event(event); @@ -1040,9 +1038,9 @@ impl ScriptTask { let borrowed_page = self.root_page(); let frame_element = borrowed_page.find(containing_pipeline_id).and_then(|page| { - let doc = page.document().root(); + let doc = page.document(); self.find_iframe(doc.r(), old_subpage_id) - }).root(); + }); frame_element.r().unwrap().update_subpage_id(new_subpage_id); } @@ -1053,7 +1051,7 @@ impl ScriptTask { let page = self.root_page(); match page.find(pipeline_id) { Some(page) => { - let window = page.window().root(); + let window = page.window(); window.r().handle_reflow_complete_msg(reflow_id); } None => { @@ -1067,7 +1065,7 @@ impl ScriptTask { let page = self.root_page(); let page = page.find(id).expect("Received resize message for PipelineId not associated with a page in the page tree. This is a bug."); - let window = page.window().root(); + let window = page.window(); window.r().set_window_size(new_size); page.set_reflow_status(true); } @@ -1089,7 +1087,7 @@ impl ScriptTask { /// We have received notification that the response associated with a load has completed. /// Kick off the document and frame tree creation process using the result. fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option<SubpageId>, - metadata: Metadata) -> Option<Temporary<ServoHTMLParser>> { + metadata: Metadata) -> Option<Root<ServoHTMLParser>> { let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage }); @@ -1110,7 +1108,7 @@ impl ScriptTask { /// Handles a request for the window title. fn handle_get_title_msg(&self, pipeline_id: PipelineId) { let page = get_page(&self.root_page(), pipeline_id); - let document = page.document().root(); + let document = page.document(); document.r().send_title_to_compositor(); } @@ -1146,7 +1144,7 @@ impl ScriptTask { // If root is being exited, shut down all pages let page = self.root_page(); - let window = page.window().root(); + let window = page.window(); if window.r().pipeline() == id { debug!("shutting down layout for root page {:?}", id); shut_down_layout(&page, exit_type); @@ -1163,13 +1161,13 @@ impl ScriptTask { /// Handles when layout task finishes all animation in one tick fn handle_tick_all_animations(&self, id: PipelineId) { let page = get_page(&self.root_page(), id); - let document = page.document().root(); + let document = page.document(); document.r().invoke_animation_callbacks(); } /// The entry point to document loading. Defines bindings, sets up the window and document /// objects, parses HTML and CSS, and kicks off initial layout. - fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Temporary<ServoHTMLParser> { + fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoHTMLParser> { let final_url = metadata.final_url.clone(); debug!("ScriptTask: loading {} on page {:?}", incomplete.url.serialize(), incomplete.pipeline_id); @@ -1191,11 +1189,11 @@ impl ScriptTask { // https://github.com/servo/servo/issues/3939#issuecomment-62287025). borrowed_page.as_ref().and_then(|borrowed_page| { borrowed_page.find(parent_id).and_then(|page| { - let doc = page.document().root(); + let doc = page.document(); self.find_iframe(doc.r(), subpage_id) }) }) - }).root(); + }); // Create a new frame tree entry. let page = Rc::new(Page::new(incomplete.pipeline_id, final_url.clone())); @@ -1268,7 +1266,7 @@ impl ScriptTask { incomplete.layout_chan, incomplete.pipeline_id, incomplete.parent_info, - incomplete.window_size).root(); + incomplete.window_size); let last_modified: Option<DOMString> = metadata.headers.as_ref().and_then(|headers| { headers.get().map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm)) @@ -1292,22 +1290,24 @@ impl ScriptTask { content_type, last_modified, DocumentSource::FromParser, - loader).root(); + loader); let frame_element = frame_element.r().map(|elem| ElementCast::from_ref(elem)); window.r().init_browser_context(document.r(), frame_element); // Create the root frame page.set_frame(Some(Frame { - document: JS::from_rooted(document.r()), - window: JS::from_rooted(window.r()), + document: JS::from_rooted(&document), + window: JS::from_rooted(&window), })); let is_javascript = incomplete.url.scheme == "javascript"; let parse_input = if is_javascript { + let _ar = JSAutoRequest::new(self.get_cx()); let evalstr = incomplete.url.non_relative_scheme_data().unwrap(); - let jsval = window.r().evaluate_js_on_global_with_result(evalstr); - let strval = FromJSValConvertible::from_jsval(self.get_cx(), jsval, + let mut jsval = RootedValue::new(self.get_cx(), UndefinedValue()); + window.r().evaluate_js_on_global_with_result(evalstr, jsval.handle_mut()); + let strval = FromJSValConvertible::from_jsval(self.get_cx(), jsval.handle(), StringificationBehavior::Empty); strval.unwrap_or("".to_owned()) } else { @@ -1337,8 +1337,8 @@ impl ScriptTask { } } - fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: JSRef<Element>) { - let node: JSRef<Node> = NodeCast::from_ref(node); + fn scroll_fragment_point(&self, pipeline_id: PipelineId, node: &Element) { + let node = NodeCast::from_ref(node); let rect = node.get_bounding_content_box(); let point = Point2D::new(rect.origin.x.to_f32_px(), rect.origin.y.to_f32_px()); // FIXME(#2003, pcwalton): This is pretty bogus when multiple layers are involved. @@ -1350,20 +1350,20 @@ impl ScriptTask { /// Reflows non-incrementally, rebuilding the entire layout tree in the process. fn rebuild_and_force_reflow(&self, page: &Page, reason: ReflowReason) { - let document = page.document().root(); + let document = page.document(); document.r().dirty_all_nodes(); - let window = window_from_node(document.r()).root(); + let window = window_from_node(document.r()); window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, reason); } /// Find an iframe element in a provided document. - fn find_iframe(&self, doc: JSRef<Document>, subpage_id: SubpageId) - -> Option<Temporary<HTMLIFrameElement>> { - let doc: JSRef<Node> = NodeCast::from_ref(doc); + fn find_iframe(&self, doc: &Document, subpage_id: SubpageId) + -> Option<Root<HTMLIFrameElement>> { + let doc = NodeCast::from_ref(doc); doc.traverse_preorder() - .filter_map(HTMLIFrameElementCast::to_temporary) - .find(|node| node.root().r().subpage_id() == Some(subpage_id)) + .filter_map(HTMLIFrameElementCast::to_root) + .find(|node| node.r().subpage_id() == Some(subpage_id)) } /// This is the main entry point for receiving and dispatching DOM events. @@ -1399,7 +1399,7 @@ impl ScriptTask { _marker = AutoDOMEventMarker::new(self); } let page = get_page(&self.root_page(), pipeline_id); - let document = page.document().root(); + let document = page.document(); // We temporarily steal the list of targets over which the mouse is to pass it to // handle_mouse_move_event() in a safe RootedVec container. let mut mouse_over_targets = RootedVec::new(); @@ -1414,7 +1414,7 @@ impl ScriptTask { _marker = AutoDOMEventMarker::new(self); } let page = get_page(&self.root_page(), pipeline_id); - let document = page.document().root(); + let document = page.document(); document.r().dispatch_key_event( key, state, modifiers, &mut *self.compositor.borrow_mut()); } @@ -1431,7 +1431,7 @@ impl ScriptTask { _marker = AutoDOMEventMarker::new(self); } let page = get_page(&self.root_page(), pipeline_id); - let document = page.document().root(); + let document = page.document(); document.r().handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type); } @@ -1443,9 +1443,9 @@ impl ScriptTask { Some(subpage_id) => { let borrowed_page = self.root_page(); let iframe = borrowed_page.find(pipeline_id).and_then(|page| { - let doc = page.document().root(); + let doc = page.document(); self.find_iframe(doc.r(), subpage_id) - }).root(); + }); if let Some(iframe) = iframe.r() { iframe.navigate_child_browsing_context(load_data.url); } @@ -1461,8 +1461,8 @@ impl ScriptTask { /// for the given pipeline. fn trigger_fragment(&self, pipeline_id: PipelineId, fragment: String) { let page = get_page(&self.root_page(), pipeline_id); - let document = page.document().root(); - match document.r().find_fragment_node(fragment).root() { + let document = page.document(); + match document.r().find_fragment_node(fragment) { Some(ref node) => { self.scroll_fragment_point(pipeline_id, node.r()); } @@ -1473,16 +1473,15 @@ impl ScriptTask { fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData) { let page = get_page(&self.root_page(), pipeline_id); - let window = page.window().root(); + let window = page.window(); window.r().set_window_size(new_size); window.r().force_reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::WindowResize); - let document = page.document().root(); + let document = page.document(); let fragment_node = window.r().steal_fragment_name() - .and_then(|name| document.r().find_fragment_node(name)) - .root(); + .and_then(|name| document.r().find_fragment_node(name)); match fragment_node { Some(ref node) => self.scroll_fragment_point(pipeline_id, node.r()), None => {} @@ -1493,10 +1492,10 @@ impl ScriptTask { let uievent = UIEvent::new(window.r(), "resize".to_owned(), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, Some(window.r()), - 0i32).root(); - let event: JSRef<Event> = EventCast::from_ref(uievent.r()); + 0i32); + let event = EventCast::from_ref(uievent.r()); - let wintarget: JSRef<EventTarget> = EventTargetCast::from_ref(window.r()); + let wintarget = EventTargetCast::from_ref(window.r()); event.fire(wintarget); } @@ -1560,7 +1559,7 @@ impl ScriptTask { None => return, }; - let document = page.document().root(); + let document = page.document(); let final_url = document.r().url(); document.r().set_ready_state(DocumentReadyState::Interactive); @@ -1570,7 +1569,7 @@ impl ScriptTask { document.r().disarm_reflow_timeout(); document.r().content_changed(NodeCast::from_ref(document.r()), NodeDamage::OtherNodeDamage); - let window = window_from_node(document.r()).root(); + let window = window_from_node(document.r()); window.r().reflow(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery, ReflowReason::FirstLoad); // No more reflow required @@ -1625,7 +1624,7 @@ fn shut_down_layout(page_tree: &Rc<Page>, exit_type: PipelineExitType) { // Tell the layout task to begin shutting down, and wait until it // processed this message. let (response_chan, response_port) = channel(); - let window = page.window().root(); + let window = page.window(); let LayoutChan(chan) = window.r().layout_chan(); if chan.send(layout_interface::Msg::PrepareToExit(response_chan)).is_ok() { channels.push(chan); @@ -1635,7 +1634,7 @@ fn shut_down_layout(page_tree: &Rc<Page>, exit_type: PipelineExitType) { // Drop our references to the JSContext and DOM objects. for page in page_tree.iter() { - let window = page.window().root(); + let window = page.window(); window.r().clear_js_runtime(); // Sever the connection between the global and the DOM tree page.set_frame(None); diff --git a/components/script/textinput.rs b/components/script/textinput.rs index 8d5668e1d04..6c485ae2b96 100644 --- a/components/script/textinput.rs +++ b/components/script/textinput.rs @@ -5,7 +5,6 @@ //! Common handling of keyboard input and state management for text input controls use clipboard_provider::ClipboardProvider; -use dom::bindings::js::JSRef; use dom::keyboardevent::{KeyboardEvent, KeyboardEventHelpers, key_value}; use msg::constellation_msg::{SHIFT, CONTROL, ALT, SUPER}; use msg::constellation_msg::{Key, KeyModifiers}; @@ -296,7 +295,7 @@ impl<T: ClipboardProvider> TextInput<T> { } /// Process a given `KeyboardEvent` and return an action for the caller to execute. - pub fn handle_keydown(&mut self, event: JSRef<KeyboardEvent>) -> KeyReaction { + pub fn handle_keydown(&mut self, event: &KeyboardEvent) -> KeyReaction { if let Some(key) = event.get_key() { self.handle_keydown_aux(key, event.get_key_modifiers()) } else { diff --git a/components/script/timers.rs b/components/script/timers.rs index 806bc57b85a..fbdad279204 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -5,7 +5,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::callback::ExceptionHandling::Report; use dom::bindings::codegen::Bindings::FunctionBinding::Function; -use dom::bindings::js::JSRef; +use dom::bindings::global::global_object_for_js_object; use dom::bindings::utils::Reflectable; use dom::window::ScriptHelpers; @@ -16,7 +16,8 @@ use horribly_inefficient_timers; use util::task::spawn_named; use util::str::DOMString; -use js::jsval::JSVal; +use js::jsapi::{RootedValue, HandleValue, Heap}; +use js::jsval::{JSVal, UndefinedValue}; use std::borrow::ToOwned; use std::cell::Cell; @@ -25,6 +26,8 @@ use std::collections::HashMap; use std::sync::mpsc::{channel, Sender}; use std::sync::mpsc::Select; use std::hash::{Hash, Hasher}; +use std::rc::Rc; +use std::default::Default; #[derive(PartialEq, Eq)] #[jstraceable] @@ -43,7 +46,7 @@ struct TimerHandle { #[derive(Clone)] pub enum TimerCallback { StringTimerCallback(DOMString), - FunctionTimerCallback(Function) + FunctionTimerCallback(Rc<Function>) } impl Hash for TimerId { @@ -104,11 +107,10 @@ pub enum TimerControlMsg { // TODO: Handle rooting during fire_timer when movable GC is turned on #[jstraceable] #[privatize] -#[derive(Clone)] struct TimerData { is_interval: IsInterval, callback: TimerCallback, - args: Vec<JSVal> + args: Vec<Heap<JSVal>> } impl TimerManager { @@ -133,7 +135,7 @@ impl TimerManager { #[allow(unsafe_code)] pub fn set_timeout_or_interval(&self, callback: TimerCallback, - arguments: Vec<JSVal>, + arguments: Vec<HandleValue>, timeout: i32, is_interval: IsInterval, source: TimerSource, @@ -205,10 +207,21 @@ impl TimerManager { data: TimerData { is_interval: is_interval, callback: callback, - args: arguments + args: Vec::with_capacity(arguments.len()) } }; self.active_timers.borrow_mut().insert(timer_id, timer); + + // This is a bit complicated, but this ensures that the vector's + // buffer isn't reallocated (and moved) after setting the Heap values + let mut timers = self.active_timers.borrow_mut(); + let mut timer = timers.get_mut(&timer_id).unwrap(); + for _ in 0..arguments.len() { + timer.data.args.push(Heap::default()); + } + for i in 0..arguments.len() { + timer.data.args.get_mut(i).unwrap().set(arguments[i].get()); + } handle } @@ -220,24 +233,31 @@ impl TimerManager { } } - pub fn fire_timer<T: Reflectable>(&self, timer_id: TimerId, this: JSRef<T>) { + pub fn fire_timer<T: Reflectable>(&self, timer_id: TimerId, this: &T) { - let data = match self.active_timers.borrow().get(&timer_id) { - None => return, - Some(timer_handle) => timer_handle.data.clone(), - }; + let (is_interval, callback, args): (IsInterval, TimerCallback, Vec<JSVal>) = + match self.active_timers.borrow().get(&timer_id) { + Some(timer_handle) => + (timer_handle.data.is_interval, + timer_handle.data.callback.clone(), + timer_handle.data.args.iter().map(|arg| arg.get()).collect()), + None => return, + }; - // TODO: Must handle rooting of funval and args when movable GC is turned on - match data.callback { + match callback { TimerCallback::FunctionTimerCallback(function) => { - let _ = function.Call_(this, data.args, Report); + let arg_handles = args.iter().by_ref().map(|arg| HandleValue { ptr: arg }).collect(); + let _ = function.Call_(this, arg_handles, Report); } TimerCallback::StringTimerCallback(code_str) => { - this.evaluate_js_on_global_with_result(&code_str); + let proxy = this.reflector().get_jsobject(); + let cx = global_object_for_js_object(proxy.get()).r().get_cx(); + let mut rval = RootedValue::new(cx, UndefinedValue()); + this.evaluate_js_on_global_with_result(&code_str, rval.handle_mut()); } - }; + } - if data.is_interval == IsInterval::NonInterval { + if is_interval == IsInterval::NonInterval { self.active_timers.borrow_mut().remove(&timer_id); } } diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 5ba227df192..c724b1b7348 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -10,27 +10,28 @@ use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; -use dom::bindings::js::{OptionalRootable, Rootable, Temporary}; +use dom::bindings::js::Root; use dom::node::{Node, NodeHelpers}; use dom::window::{ScriptHelpers, WindowHelpers}; use dom::document::DocumentHelpers; use js::jsapi::JSContext; -use js::jsval::JSVal; use page::Page; use msg::constellation_msg::{PipelineId, SubpageId}; use msg::webdriver_msg::{WebDriverJSValue, WebDriverJSError, WebDriverJSResult, WebDriverFrameId}; use script_task::get_page; +use js::jsapi::{RootedValue, HandleValue}; +use js::jsval::UndefinedValue; use std::rc::Rc; use std::sync::mpsc::Sender; -fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Option<Temporary<Node>> { +fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String) -> Option<Root<Node>> { let page = get_page(&*page, pipeline); - let document = page.document().root(); + let document = page.document(); let node = NodeCast::from_ref(document.r()); for candidate in node.traverse_preorder() { - if candidate.root().r().get_unique_id() == node_id { + if candidate.r().get_unique_id() == node_id { return Some(candidate); } } @@ -38,19 +39,19 @@ fn find_node_by_unique_id(page: &Rc<Page>, pipeline: PipelineId, node_id: String None } -pub fn jsval_to_webdriver(cx: *mut JSContext, val: JSVal) -> WebDriverJSResult { - if val.is_undefined() { +pub fn jsval_to_webdriver(cx: *mut JSContext, val: HandleValue) -> WebDriverJSResult { + if val.get().is_undefined() { Ok(WebDriverJSValue::Undefined) - } else if val.is_boolean() { - Ok(WebDriverJSValue::Boolean(val.to_boolean())) - } else if val.is_double() { + } else if val.get().is_boolean() { + Ok(WebDriverJSValue::Boolean(val.get().to_boolean())) + } else if val.get().is_double() { Ok(WebDriverJSValue::Number(FromJSValConvertible::from_jsval(cx, val, ()).unwrap())) - } else if val.is_string() { + } else if val.get().is_string() { //FIXME: use jsstring_to_str when jsval grows to_jsstring Ok( WebDriverJSValue::String( FromJSValConvertible::from_jsval(cx, val, StringificationBehavior::Default).unwrap())) - } else if val.is_null() { + } else if val.get().is_null() { Ok(WebDriverJSValue::Null) } else { Err(WebDriverJSError::UnknownType) @@ -59,19 +60,22 @@ pub fn jsval_to_webdriver(cx: *mut JSContext, val: JSVal) -> WebDriverJSResult { pub fn handle_execute_script(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<WebDriverJSResult>) { let page = get_page(&*page, pipeline); - let window = page.window().root(); + let window = page.window(); let cx = window.r().get_cx(); - let rval = window.r().evaluate_js_on_global_with_result(&eval); + let mut rval = RootedValue::new(cx, UndefinedValue()); + window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut()); - reply.send(jsval_to_webdriver(cx, rval)).unwrap(); + reply.send(jsval_to_webdriver(cx, rval.handle())).unwrap(); } pub fn handle_execute_async_script(page: &Rc<Page>, pipeline: PipelineId, eval: String, reply: Sender<WebDriverJSResult>) { let page = get_page(&*page, pipeline); - let window = page.window().root(); + let window = page.window(); + let cx = window.r().get_cx(); window.r().set_webdriver_script_chan(Some(reply)); - window.r().evaluate_js_on_global_with_result(&eval); + let mut rval = RootedValue::new(cx, UndefinedValue()); + window.r().evaluate_js_on_global_with_result(&eval, rval.handle_mut()); } pub fn handle_get_frame_id(page: &Rc<Page>, @@ -86,7 +90,7 @@ pub fn handle_get_frame_id(page: &Rc<Page>, WebDriverFrameId::Element(x) => { match find_node_by_unique_id(page, pipeline, x) { Some(ref node) => { - match HTMLIFrameElementCast::to_ref(node.root().r()) { + match HTMLIFrameElementCast::to_ref(node.r()) { Some(ref elem) => Ok(elem.GetContentWindow()), None => Err(()) } @@ -96,19 +100,19 @@ pub fn handle_get_frame_id(page: &Rc<Page>, }, WebDriverFrameId::Parent => { let window = page.window(); - Ok(window.root().r().parent()) + Ok(window.r().parent()) } }; - let frame_id = window.map(|x| x.and_then(|x| x.root().r().parent_info())); + let frame_id = window.map(|x| x.and_then(|x| x.r().parent_info())); reply.send(frame_id).unwrap() } pub fn handle_find_element_css(page: &Rc<Page>, _pipeline: PipelineId, selector: String, reply: Sender<Result<Option<String>, ()>>) { - reply.send(match page.document().root().r().QuerySelector(selector.clone()) { + reply.send(match page.document().r().QuerySelector(selector.clone()) { Ok(node) => { - let result = node.map(|x| NodeCast::from_ref(x.root().r()).get_unique_id()); + let result = node.map(|x| NodeCast::from_ref(x.r()).get_unique_id()); Ok(result) } Err(_) => Err(()) @@ -117,13 +121,12 @@ pub fn handle_find_element_css(page: &Rc<Page>, _pipeline: PipelineId, selector: pub fn handle_find_elements_css(page: &Rc<Page>, _pipeline: PipelineId, selector: String, reply: Sender<Result<Vec<String>, ()>>) { - reply.send(match page.document().root().r().QuerySelectorAll(selector.clone()) { - Ok(ref node_list) => { - let nodes = node_list.root(); + reply.send(match page.document().r().QuerySelectorAll(selector.clone()) { + Ok(ref nodes) => { let mut result = Vec::with_capacity(nodes.r().Length() as usize); for i in 0..nodes.r().Length() { if let Some(ref node) = nodes.r().Item(i) { - result.push(node.root().r().get_unique_id()); + result.push(node.r().get_unique_id()); } } Ok(result) @@ -135,18 +138,18 @@ pub fn handle_find_elements_css(page: &Rc<Page>, _pipeline: PipelineId, selector } pub fn handle_get_active_element(page: &Rc<Page>, _pipeline: PipelineId, reply: Sender<Option<String>>) { - reply.send(page.document().root().r().GetActiveElement().map( - |elem| NodeCast::from_ref(elem.root().r()).get_unique_id())).unwrap(); + reply.send(page.document().r().GetActiveElement().map( + |elem| NodeCast::from_ref(elem.r()).get_unique_id())).unwrap(); } pub fn handle_get_title(page: &Rc<Page>, _pipeline: PipelineId, reply: Sender<String>) { - reply.send(page.document().root().r().Title()).unwrap(); + reply.send(page.document().r().Title()).unwrap(); } pub fn handle_get_text(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Result<String, ()>>) { reply.send(match find_node_by_unique_id(&*page, pipeline, node_id) { Some(ref node) => { - Ok(node.root().r().GetTextContent().unwrap_or("".to_owned())) + Ok(node.r().GetTextContent().unwrap_or("".to_owned())) }, None => Err(()) }).unwrap(); @@ -154,8 +157,7 @@ pub fn handle_get_text(page: &Rc<Page>, pipeline: PipelineId, node_id: String, r pub fn handle_get_name(page: &Rc<Page>, pipeline: PipelineId, node_id: String, reply: Sender<Result<String, ()>>) { reply.send(match find_node_by_unique_id(&*page, pipeline, node_id) { - Some(tmp_node) => { - let node = tmp_node.root(); + Some(node) => { let element = ElementCast::to_ref(node.r()).unwrap(); Ok(element.TagName()) }, diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index b181a407ea5..136ddccb090 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -600,7 +600,7 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#d7d45d07e0e91b13a01f32704fb93631fbf9611c" +source = "git+https://github.com/servo/rust-mozjs#d0c4bd28930e809bf0af38cc8c034cbc61afa545" dependencies = [ "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -755,7 +755,7 @@ dependencies = [ [[package]] name = "mozjs_sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#2d5bc1838f8cc2f37177c705fb9bc583c742bc33" +source = "git+https://github.com/servo/mozjs#2c918d1fb803673f5e5aca230034f77e85455448" [[package]] name = "msg" diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 0ac0519a81c..5842a0b2280 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -81,6 +81,7 @@ impl Browser { // Global configuration options, parsed from the command line. let opts = opts::get(); + script::init(); // Create the global vtables used by the (generated) DOM // bindings to implement JS proxies. RegisterBindings::RegisterProxyHandlers(); diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 04187e52cc8..981d17cec79 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -592,7 +592,7 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#d7d45d07e0e91b13a01f32704fb93631fbf9611c" +source = "git+https://github.com/servo/rust-mozjs#d0c4bd28930e809bf0af38cc8c034cbc61afa545" dependencies = [ "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -747,7 +747,7 @@ dependencies = [ [[package]] name = "mozjs_sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#2d5bc1838f8cc2f37177c705fb9bc583c742bc33" +source = "git+https://github.com/servo/mozjs#2c918d1fb803673f5e5aca230034f77e85455448" [[package]] name = "msg" diff --git a/ports/cef/lib.rs b/ports/cef/lib.rs index 4cb5abfa4ff..e926f8ebc14 100644 --- a/ports/cef/lib.rs +++ b/ports/cef/lib.rs @@ -46,6 +46,10 @@ extern crate libc; extern crate url as std_url; #[cfg(target_os="macos")] +#[link_args="-Xlinker -undefined -Xlinker dynamic_lookup"] +extern { } + +#[cfg(target_os="macos")] extern crate cgl; #[cfg(target_os="macos")] extern crate cocoa; diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock index 14720669bbe..41f34c75f52 100644 --- a/ports/gonk/Cargo.lock +++ b/ports/gonk/Cargo.lock @@ -526,7 +526,7 @@ dependencies = [ [[package]] name = "js" version = "0.1.0" -source = "git+https://github.com/servo/rust-mozjs#d7d45d07e0e91b13a01f32704fb93631fbf9611c" +source = "git+https://github.com/servo/rust-mozjs#d0c4bd28930e809bf0af38cc8c034cbc61afa545" dependencies = [ "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "mozjs_sys" version = "0.0.0" -source = "git+https://github.com/servo/mozjs#2d5bc1838f8cc2f37177c705fb9bc583c742bc33" +source = "git+https://github.com/servo/mozjs#2c918d1fb803673f5e5aca230034f77e85455448" [[package]] name = "msg" diff --git a/ports/gonk/fake-ld.sh b/ports/gonk/fake-ld.sh index a03caea6322..53c55259be0 100755 --- a/ports/gonk/fake-ld.sh +++ b/ports/gonk/fake-ld.sh @@ -1,2 +1,2 @@ #!/bin/bash -arm-linux-androideabi-g++ $@ $LDFLAGS -pie -lGLESv2 -lsupc++ -L$GONKDIR/prebuilts/ndk/9/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/ -L$GONKDIR/backup-flame/system/lib/ +arm-linux-androideabi-g++ $@ $LDFLAGS -pie -lGLESv2 -L$GONKDIR/backup-flame/system/lib/ diff --git a/ports/gonk/src/main.rs b/ports/gonk/src/main.rs index 19c1a0fb256..9e3cf9636f7 100644 --- a/ports/gonk/src/main.rs +++ b/ports/gonk/src/main.rs @@ -41,6 +41,9 @@ extern crate url; extern crate net; extern crate env_logger; +#[link(name = "stlport")] +extern {} + use util::opts; use net::resource_task; use servo::Browser; diff --git a/python/servo/command_base.py b/python/servo/command_base.py index c6d46fc3de8..7c41fa42196 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -238,10 +238,10 @@ class CommandBase(object): if self.config["gonk"]["product"]: env["GONK_PRODUCT"] = self.config["gonk"]["product"] - env["CC"] = "arm-linux-androideabi-gcc" env["ARCH_DIR"] = "arch-arm" env["CPPFLAGS"] = ( "-DANDROID -DTARGET_OS_GONK " + "-DANDROID_VERSION=19 " "-DGR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE=1 " "-isystem %(gonkdir)s/bionic/libc/%(archdir)s/include " "-isystem %(gonkdir)s/bionic/libc/include/ " @@ -250,24 +250,29 @@ class CommandBase(object): "-isystem %(gonkdir)s/bionic/libm/include " "-I%(gonkdir)s/system " "-I%(gonkdir)s/system/core/include " - "-isystem %(gonkdir)s/bionic " "-I%(gonkdir)s/frameworks/native/opengl/include " "-I%(gonkdir)s/external/zlib " - "-I%(gonkdir)s/hardware/libhardware/include/hardware/ " ) % {"gonkdir": env["GONKDIR"], "archdir": env["ARCH_DIR"]} env["CXXFLAGS"] = ( - "-O2 -mandroid -fPIC %(cppflags)s " - "-I%(gonkdir)s/ndk/sources/cxx-stl/stlport/stlport " - "-I%(gonkdir)s/ndk/sources/cxx-stl/system/include " + "-O2 -mandroid -fPIC " + "-isystem %(gonkdir)s/api/cpp/include " + "-isystem %(gonkdir)s/external/stlport/stlport " + "-isystem %(gonkdir)s/bionic " + "-isystem %(gonkdir)s/bionic/libstdc++/include " + "%(cppflags)s" ) % {"gonkdir": env["GONKDIR"], "cppflags": env["CPPFLAGS"]} env["CFLAGS"] = ( - "-O2 -mandroid -fPIC %(cppflags)s " - "-I%(gonkdir)s/ndk/sources/cxx-stl/stlport/stlport " - "-I%(gonkdir)s/ndk/sources/cxx-stl/system/include " - ) % {"gonkdir": env["GONKDIR"], "cppflags": env["CPPFLAGS"]} + "%(cxxflags)s" + ) % {"cxxflags": env["CXXFLAGS"]} another_extra_path = path.join( env["GONKDIR"], "prebuilts", "gcc", "linux-x86", "arm", "arm-linux-androideabi-4.7", "bin") + + env["gonkdir"] = env["GONKDIR"] + env["gonk_toolchain_prefix"] = ( + "%(toolchain)s/arm-linux-androideabi-" + ) % {"toolchain": another_extra_path} + env["PATH"] = "%s%s%s" % (another_extra_path, os.pathsep, env["PATH"]) env["LDFLAGS"] = ( "-mandroid -L%(gonkdir)s/out/target/product/%(gonkproduct)s/obj/lib " diff --git a/tests/wpt/metadata/FileAPI/idlharness.html.ini b/tests/wpt/metadata/FileAPI/idlharness.html.ini index f96868b5859..9ded67b6acb 100644 --- a/tests/wpt/metadata/FileAPI/idlharness.html.ini +++ b/tests/wpt/metadata/FileAPI/idlharness.html.ini @@ -9,9 +9,6 @@ [URL interface: operation revokeObjectURL(DOMString)] expected: FAIL - [Blob interface object length] - expected: FAIL - [Blob interface: attribute isClosed] expected: FAIL diff --git a/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini b/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini index 0a370990bef..af28495ed67 100644 --- a/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini +++ b/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini @@ -6,21 +6,12 @@ [XMLHttpRequest interface: calling overrideMimeType(DOMString) on new XMLHttpRequest() with too few arguments must throw TypeError] expected: FAIL - [FormData interface object length] - expected: FAIL - [FormData interface: new FormData() must inherit property "getAll" with the proper type (4)] expected: FAIL [FormData interface: new FormData(form) must inherit property "getAll" with the proper type (4)] expected: FAIL - [XMLHttpRequestUpload interface object length] - expected: FAIL - - [XMLHttpRequest interface object length] - expected: FAIL - [XMLHttpRequest interface: new XMLHttpRequest() must inherit property "overrideMimeType" with the proper type (20)] expected: FAIL @@ -33,18 +24,12 @@ [FormData interface: calling getAll(USVString) on new FormData(form) with too few arguments must throw TypeError] expected: FAIL - [ProgressEvent interface object length] - expected: FAIL - [ProgressEvent interface: existence and properties of interface object] expected: FAIL [XMLHttpRequestEventTarget interface: existence and properties of interface object] expected: FAIL - [XMLHttpRequestEventTarget interface object length] - expected: FAIL - [XMLHttpRequestUpload interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-name.htm.ini b/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-name.htm.ini deleted file mode 100644 index 167afefcb18..00000000000 --- a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-name.htm.ini +++ /dev/null @@ -1,6 +0,0 @@ -[setrequestheader-bogus-name.htm] - type: testharness - expected: TIMEOUT - [setRequestHeader should throw with header name "テスト".] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini b/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini deleted file mode 100644 index c176859cd08..00000000000 --- a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini +++ /dev/null @@ -1,6 +0,0 @@ -[setrequestheader-bogus-value.htm] - type: testharness - expected: TIMEOUT - [XMLHttpRequest: setRequestHeader() value argument checks 2] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/dom/interfaces.html.ini b/tests/wpt/metadata/dom/interfaces.html.ini index fce2f3ccc3f..473276d0be3 100644 --- a/tests/wpt/metadata/dom/interfaces.html.ini +++ b/tests/wpt/metadata/dom/interfaces.html.ini @@ -1,8 +1,5 @@ [interfaces.html] type: testharness - [Event interface object length] - expected: FAIL - [Event interface: document.createEvent("Event") must have own property "isTrusted"] expected: FAIL @@ -12,21 +9,9 @@ [CustomEvent interface: existence and properties of interface object] expected: FAIL - [CustomEvent interface object length] - expected: FAIL - [Event interface: new CustomEvent("foo") must have own property "isTrusted"] expected: FAIL - [EventTarget interface object length] - expected: FAIL - - [NodeList interface object length] - expected: FAIL - - [HTMLCollection interface object length] - expected: FAIL - [MutationObserver interface: existence and properties of interface object] expected: FAIL @@ -90,15 +75,9 @@ [Node interface: existence and properties of interface object] expected: FAIL - [Node interface object length] - expected: FAIL - [Document interface: existence and properties of interface object] expected: FAIL - [Document interface object length] - expected: FAIL - [Document interface: attribute origin] expected: FAIL @@ -141,15 +120,9 @@ [Document interface: calling queryAll(DOMString) on xmlDoc with too few arguments must throw TypeError] expected: FAIL - [DOMImplementation interface object length] - expected: FAIL - [DocumentFragment interface: existence and properties of interface object] expected: FAIL - [DocumentFragment interface object length] - expected: FAIL - [DocumentFragment interface: operation getElementById(DOMString)] expected: FAIL @@ -180,15 +153,9 @@ [DocumentType interface: existence and properties of interface object] expected: FAIL - [DocumentType interface object length] - expected: FAIL - [Element interface: existence and properties of interface object] expected: FAIL - [Element interface object length] - expected: FAIL - [Element interface: operation hasAttributes()] expected: FAIL @@ -258,42 +225,24 @@ [Element interface: calling queryAll(DOMString) on element with too few arguments must throw TypeError] expected: FAIL - [NamedNodeMap interface object length] - expected: FAIL - [NamedNodeMap interface: operation setNamedItem(Attr)] expected: FAIL [NamedNodeMap interface: operation setNamedItemNS(Attr)] expected: FAIL - [Attr interface object length] - expected: FAIL - [CharacterData interface: existence and properties of interface object] expected: FAIL - [CharacterData interface object length] - expected: FAIL - [Text interface: existence and properties of interface object] expected: FAIL - [Text interface object length] - expected: FAIL - [ProcessingInstruction interface: existence and properties of interface object] expected: FAIL - [ProcessingInstruction interface object length] - expected: FAIL - [Comment interface: existence and properties of interface object] expected: FAIL - [Comment interface object length] - expected: FAIL - [Range interface: operation deleteContents()] expected: FAIL @@ -354,18 +303,9 @@ [Range interface: calling surroundContents(Node) on detachedRange with too few arguments must throw TypeError] expected: FAIL - [NodeIterator interface object length] - expected: FAIL - - [TreeWalker interface object length] - expected: FAIL - [NodeFilter interface: existence and properties of interface object] expected: FAIL - [DOMTokenList interface object length] - expected: FAIL - [DOMSettableTokenList interface: existence and properties of interface object] expected: FAIL @@ -381,9 +321,3 @@ [DOMSettableTokenList interface: attribute value] expected: FAIL - [Range interface object length] - expected: FAIL - - [NodeIterator interface object length] - expected: FAIL - diff --git a/tests/wpt/metadata/dom/ranges/Range-cloneContents.html.ini b/tests/wpt/metadata/dom/ranges/Range-cloneContents.html.ini index ada6527c5ea..9f96cdb458a 100644 --- a/tests/wpt/metadata/dom/ranges/Range-cloneContents.html.ini +++ b/tests/wpt/metadata/dom/ranges/Range-cloneContents.html.ini @@ -1,3 +1,530 @@ [Range-cloneContents.html] type: testharness - expected: CRASH + [Range.detach()] + expected: FAIL + + [Resulting DOM for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Returned fragment for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Returned fragment for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Returned fragment for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Returned fragment for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Returned fragment for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Returned fragment for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting DOM for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting cursor position for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Returned fragment for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting DOM for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Returned fragment for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting cursor position for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Returned fragment for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting DOM for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting cursor position for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Returned fragment for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting DOM for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting cursor position for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Returned fragment for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting DOM for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting cursor position for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Returned fragment for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting DOM for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting cursor position for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Returned fragment for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting DOM for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting cursor position for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting DOM for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting DOM for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting cursor position for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Returned fragment for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting DOM for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting cursor position for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Returned fragment for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting DOM for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting cursor position for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Returned fragment for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting DOM for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting cursor position for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Returned fragment for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting DOM for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting cursor position for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Returned fragment for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting DOM for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Returned fragment for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting DOM for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting cursor position for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Returned fragment for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting DOM for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting cursor position for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Returned fragment for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting DOM for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Returned fragment for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Returned fragment for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting DOM for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Returned fragment for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting cursor position for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Returned fragment for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting DOM for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting cursor position for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Returned fragment for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting DOM for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting cursor position for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Returned fragment for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting DOM for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Returned fragment for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting DOM for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Returned fragment for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Returned fragment for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting DOM for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting cursor position for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Returned fragment for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting DOM for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting cursor position for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Returned fragment for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting DOM for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Returned fragment for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Returned fragment for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Returned fragment for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Returned fragment for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting cursor position for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Returned fragment for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting DOM for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Returned fragment for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting DOM for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Returned fragment for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + + [Returned fragment for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + diff --git a/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini b/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini index fe3efdc8d7f..5728046b57a 100644 --- a/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini +++ b/tests/wpt/metadata/dom/ranges/Range-deleteContents.html.ini @@ -1,3 +1,359 @@ [Range-deleteContents.html] type: testharness - expected: CRASH + [Detached Range] + expected: FAIL + + [Resulting DOM for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting DOM for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting cursor position for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting DOM for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting cursor position for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting DOM for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting cursor position for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting DOM for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting cursor position for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting DOM for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting cursor position for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting DOM for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting cursor position for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting DOM for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting cursor position for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting DOM for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting DOM for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting cursor position for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting DOM for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting cursor position for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting DOM for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting cursor position for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting DOM for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting cursor position for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting DOM for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting cursor position for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting DOM for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting DOM for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting cursor position for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting DOM for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting cursor position for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting DOM for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting DOM for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting cursor position for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting DOM for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting cursor position for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting DOM for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting cursor position for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting DOM for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting DOM for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting DOM for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting cursor position for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting DOM for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting cursor position for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting DOM for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting cursor position for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting DOM for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting DOM for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + diff --git a/tests/wpt/metadata/dom/ranges/Range-extractContents.html.ini b/tests/wpt/metadata/dom/ranges/Range-extractContents.html.ini index 6facbe117de..254277cac2e 100644 --- a/tests/wpt/metadata/dom/ranges/Range-extractContents.html.ini +++ b/tests/wpt/metadata/dom/ranges/Range-extractContents.html.ini @@ -1,3 +1,530 @@ [Range-extractContents.html] type: testharness - expected: CRASH + [Detached Range] + expected: FAIL + + [Resulting DOM for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 0 [paras[0\].firstChild, 0, paras[0\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 1 [paras[0\].firstChild, 0, paras[0\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 2 [paras[0\].firstChild, 2, paras[0\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Returned fragment for range 3 [paras[0\].firstChild, 2, paras[0\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 4 [paras[1\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting cursor position for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Returned fragment for range 5 [paras[1\].firstChild, 2, paras[1\].firstChild, 9\]] + expected: FAIL + + [Resulting DOM for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 6 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 7 [detachedPara1.firstChild, 2, detachedPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 8 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 9 [foreignPara1.firstChild, 2, foreignPara1.firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Returned fragment for range 10 [document.documentElement, 0, document.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Returned fragment for range 11 [document.documentElement, 0, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting cursor position for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Returned fragment for range 12 [document.documentElement, 1, document.documentElement, 2\]] + expected: FAIL + + [Resulting DOM for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Returned fragment for range 13 [document.head, 1, document.head, 1\]] + expected: FAIL + + [Resulting DOM for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting cursor position for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Returned fragment for range 14 [document.body, 4, document.body, 5\]] + expected: FAIL + + [Resulting DOM for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting cursor position for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Returned fragment for range 15 [foreignDoc.documentElement, 0, foreignDoc.documentElement, 1\]] + expected: FAIL + + [Resulting DOM for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting cursor position for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Returned fragment for range 16 [paras[0\], 0, paras[0\], 1\]] + expected: FAIL + + [Resulting DOM for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting cursor position for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Returned fragment for range 17 [detachedPara1, 0, detachedPara1, 1\]] + expected: FAIL + + [Resulting DOM for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting cursor position for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Returned fragment for range 18 [paras[0\].firstChild, 0, paras[1\].firstChild, 0\]] + expected: FAIL + + [Resulting DOM for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 19 [paras[0\].firstChild, 0, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting cursor position for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Returned fragment for range 20 [paras[0\].firstChild, 3, paras[3\], 1\]] + expected: FAIL + + [Resulting DOM for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting cursor position for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Returned fragment for range 21 [paras[0\], 0, paras[0\].firstChild, 7\]] + expected: FAIL + + [Resulting DOM for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting cursor position for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Returned fragment for range 22 [testDiv, 2, paras[4\], 1\]] + expected: FAIL + + [Resulting DOM for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting cursor position for range 23 [document, 0, document, 1\]] + expected: FAIL + + [Resulting DOM for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 24 [document, 0, document, 2\]] + expected: FAIL + + [Resulting DOM for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting cursor position for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Returned fragment for range 25 [comment, 2, comment, 3\]] + expected: FAIL + + [Resulting DOM for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting cursor position for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Returned fragment for range 26 [testDiv, 0, comment, 5\]] + expected: FAIL + + [Resulting DOM for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting cursor position for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Returned fragment for range 27 [foreignDoc, 1, foreignComment, 2\]] + expected: FAIL + + [Resulting DOM for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting cursor position for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Returned fragment for range 28 [foreignDoc.body, 0, foreignTextNode, 36\]] + expected: FAIL + + [Resulting DOM for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting cursor position for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Returned fragment for range 29 [xmlDoc, 1, xmlComment, 0\]] + expected: FAIL + + [Resulting DOM for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 30 [detachedTextNode, 0, detachedTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 31 [detachedForeignTextNode, 0, detachedForeignTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting cursor position for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Returned fragment for range 32 [detachedXmlTextNode, 0, detachedXmlTextNode, 8\]] + expected: FAIL + + [Resulting DOM for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Returned fragment for range 33 [detachedComment, 3, detachedComment, 4\]] + expected: FAIL + + [Resulting DOM for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting cursor position for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Returned fragment for range 34 [detachedForeignComment, 0, detachedForeignComment, 1\]] + expected: FAIL + + [Resulting DOM for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting cursor position for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Returned fragment for range 35 [detachedXmlComment, 2, detachedXmlComment, 6\]] + expected: FAIL + + [Resulting DOM for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Returned fragment for range 36 [docfrag, 0, docfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 37 [paras[1\].firstChild, 0, paras[1\].firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting cursor position for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Returned fragment for range 38 [paras[1\].firstChild, 2, paras[1\].firstChild, 8\]] + expected: FAIL + + [Resulting DOM for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 39 [detachedPara1.firstChild, 0, detachedPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting cursor position for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Returned fragment for range 40 [foreignPara1.firstChild, 0, foreignPara1.firstChild, 1\]] + expected: FAIL + + [Resulting DOM for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting cursor position for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Returned fragment for range 41 [foreignDoc.head, 1, foreignDoc.head, 1\]] + expected: FAIL + + [Resulting DOM for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Returned fragment for range 42 [foreignDoc.body, 0, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting cursor position for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Returned fragment for range 43 [paras[0\], 0, paras[0\], 0\]] + expected: FAIL + + [Resulting DOM for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting cursor position for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Returned fragment for range 44 [detachedPara1, 0, detachedPara1, 0\]] + expected: FAIL + + [Resulting DOM for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting cursor position for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Returned fragment for range 45 [testDiv, 1, paras[2\].firstChild, 5\]] + expected: FAIL + + [Resulting DOM for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Returned fragment for range 46 [document.documentElement, 1, document.body, 0\]] + expected: FAIL + + [Resulting DOM for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting cursor position for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Returned fragment for range 47 [foreignDoc.documentElement, 1, foreignDoc.body, 0\]] + expected: FAIL + + [Resulting DOM for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting cursor position for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Returned fragment for range 48 [document, 1, document, 2\]] + expected: FAIL + + [Resulting DOM for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting cursor position for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Returned fragment for range 49 [paras[2\].firstChild, 4, comment, 2\]] + expected: FAIL + + [Resulting DOM for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting cursor position for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Returned fragment for range 50 [paras[3\], 1, comment, 8\]] + expected: FAIL + + [Resulting DOM for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Returned fragment for range 51 [foreignDoc, 0, foreignDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting cursor position for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Returned fragment for range 52 [xmlDoc, 0, xmlDoc, 0\]] + expected: FAIL + + [Resulting DOM for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Returned fragment for range 53 [detachedForeignTextNode, 7, detachedForeignTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting cursor position for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Returned fragment for range 54 [detachedXmlTextNode, 7, detachedXmlTextNode, 7\]] + expected: FAIL + + [Resulting DOM for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting cursor position for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Returned fragment for range 55 [detachedComment, 5, detachedComment, 5\]] + expected: FAIL + + [Resulting DOM for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting cursor position for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Returned fragment for range 56 [detachedForeignComment, 4, detachedForeignComment, 4\]] + expected: FAIL + + [Resulting DOM for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Returned fragment for range 57 [foreignDocfrag, 0, foreignDocfrag, 0\]] + expected: FAIL + + [Resulting DOM for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + + [Resulting cursor position for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + + [Returned fragment for range 58 [xmlDocfrag, 0, xmlDocfrag, 0\]] + expected: FAIL + diff --git a/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini b/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini deleted file mode 100644 index cefc0c5be28..00000000000 --- a/tests/wpt/metadata/dom/traversal/NodeIterator.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[NodeIterator.html] - type: testharness - [Propagate exception from filter function] - expected: FAIL - diff --git a/tests/wpt/metadata/dom/traversal/TreeWalker-acceptNode-filter.html.ini b/tests/wpt/metadata/dom/traversal/TreeWalker-acceptNode-filter.html.ini deleted file mode 100644 index e67e45df785..00000000000 --- a/tests/wpt/metadata/dom/traversal/TreeWalker-acceptNode-filter.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[TreeWalker-acceptNode-filter.html] - type: testharness - [Testing with filter function that throws] - expected: FAIL - - [Testing with filter object that throws] - expected: FAIL - diff --git a/tests/wpt/metadata/encoding/idlharness.html.ini b/tests/wpt/metadata/encoding/idlharness.html.ini index 62e16e8c2e5..b7f3a8981a9 100644 --- a/tests/wpt/metadata/encoding/idlharness.html.ini +++ b/tests/wpt/metadata/encoding/idlharness.html.ini @@ -1,14 +1,8 @@ [idlharness.html] type: testharness - [TextDecoder interface object length] - expected: FAIL - [TextDecoder interface: attribute ignoreBOM] expected: FAIL [TextDecoder interface: new TextDecoder() must inherit property "ignoreBOM" with the proper type (2)] expected: FAIL - [TextEncoder interface object length] - expected: FAIL - diff --git a/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini b/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini index 5491e6cad84..94b88d455d7 100644 --- a/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini +++ b/tests/wpt/metadata/encoding/textdecoder-fatal-streaming.html.ini @@ -1,8 +1,5 @@ [textdecoder-fatal-streaming.html] type: testharness - [Fatal flag, non-streaming cases] - expected: FAIL - [Fatal flag, streaming cases] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/the-window-object/window-indexed-properties-strict.html.ini b/tests/wpt/metadata/html/browsers/the-window-object/window-indexed-properties-strict.html.ini index 000076d4c1b..8aaedb40b64 100644 --- a/tests/wpt/metadata/html/browsers/the-window-object/window-indexed-properties-strict.html.ini +++ b/tests/wpt/metadata/html/browsers/the-window-object/window-indexed-properties-strict.html.ini @@ -3,6 +3,3 @@ [Indexed properties of the window object (strict mode) 1] expected: FAIL - [Indexed properties of the window object (strict mode) 2] - expected: FAIL - diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 7b64b3539a2..b1228b4171f 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -1608,9 +1608,6 @@ [PropertyNodeList interface: operation getValues()] expected: FAIL - [DOMStringMap interface object length] - expected: FAIL - [DOMElementMap interface: existence and properties of interface object] expected: FAIL @@ -1632,9 +1629,6 @@ [HTMLElement interface: existence and properties of interface object] expected: FAIL - [HTMLElement interface object length] - expected: FAIL - [HTMLElement interface: attribute translate] expected: FAIL @@ -2181,9 +2175,6 @@ [HTMLUnknownElement interface: existence and properties of interface object] expected: FAIL - [HTMLUnknownElement interface object length] - expected: FAIL - [HTMLUnknownElement must be primary interface of document.createElement("bgsound")] expected: FAIL @@ -2205,9 +2196,6 @@ [HTMLHtmlElement interface: existence and properties of interface object] expected: FAIL - [HTMLHtmlElement interface object length] - expected: FAIL - [HTMLHtmlElement interface: attribute version] expected: FAIL @@ -2217,21 +2205,12 @@ [HTMLHeadElement interface: existence and properties of interface object] expected: FAIL - [HTMLHeadElement interface object length] - expected: FAIL - [HTMLTitleElement interface: existence and properties of interface object] expected: FAIL - [HTMLTitleElement interface object length] - expected: FAIL - [HTMLBaseElement interface: existence and properties of interface object] expected: FAIL - [HTMLBaseElement interface object length] - expected: FAIL - [HTMLBaseElement interface: attribute href] expected: FAIL @@ -2247,9 +2226,6 @@ [HTMLLinkElement interface: existence and properties of interface object] expected: FAIL - [HTMLLinkElement interface object length] - expected: FAIL - [HTMLLinkElement interface: attribute crossOrigin] expected: FAIL @@ -2286,9 +2262,6 @@ [HTMLMetaElement interface: existence and properties of interface object] expected: FAIL - [HTMLMetaElement interface object length] - expected: FAIL - [HTMLMetaElement interface: attribute httpEquiv] expected: FAIL @@ -2304,9 +2277,6 @@ [HTMLStyleElement interface: existence and properties of interface object] expected: FAIL - [HTMLStyleElement interface object length] - expected: FAIL - [HTMLStyleElement interface: attribute media] expected: FAIL @@ -2331,9 +2301,6 @@ [HTMLBodyElement interface: existence and properties of interface object] expected: FAIL - [HTMLBodyElement interface object length] - expected: FAIL - [HTMLBodyElement interface: attribute text] expected: FAIL @@ -2439,9 +2406,6 @@ [HTMLHeadingElement interface: existence and properties of interface object] expected: FAIL - [HTMLHeadingElement interface object length] - expected: FAIL - [HTMLHeadingElement interface: attribute align] expected: FAIL @@ -2466,9 +2430,6 @@ [HTMLParagraphElement interface: existence and properties of interface object] expected: FAIL - [HTMLParagraphElement interface object length] - expected: FAIL - [HTMLParagraphElement interface: attribute align] expected: FAIL @@ -2478,9 +2439,6 @@ [HTMLHRElement interface: existence and properties of interface object] expected: FAIL - [HTMLHRElement interface object length] - expected: FAIL - [HTMLHRElement interface: attribute align] expected: FAIL @@ -2514,9 +2472,6 @@ [HTMLPreElement interface: existence and properties of interface object] expected: FAIL - [HTMLPreElement interface object length] - expected: FAIL - [HTMLPreElement interface: attribute width] expected: FAIL @@ -2553,9 +2508,6 @@ [HTMLQuoteElement interface: existence and properties of interface object] expected: FAIL - [HTMLQuoteElement interface object length] - expected: FAIL - [HTMLQuoteElement interface: attribute cite] expected: FAIL @@ -2574,9 +2526,6 @@ [HTMLOListElement interface: existence and properties of interface object] expected: FAIL - [HTMLOListElement interface object length] - expected: FAIL - [HTMLOListElement interface: attribute reversed] expected: FAIL @@ -2592,9 +2541,6 @@ [HTMLUListElement interface: existence and properties of interface object] expected: FAIL - [HTMLUListElement interface object length] - expected: FAIL - [HTMLUListElement interface: attribute compact] expected: FAIL @@ -2604,9 +2550,6 @@ [HTMLLIElement interface: existence and properties of interface object] expected: FAIL - [HTMLLIElement interface object length] - expected: FAIL - [HTMLLIElement interface: attribute value] expected: FAIL @@ -2622,18 +2565,12 @@ [HTMLDListElement interface: existence and properties of interface object] expected: FAIL - [HTMLDListElement interface object length] - expected: FAIL - [HTMLDListElement interface: attribute compact] expected: FAIL [HTMLDivElement interface: existence and properties of interface object] expected: FAIL - [HTMLDivElement interface object length] - expected: FAIL - [HTMLDivElement interface: attribute align] expected: FAIL @@ -2643,9 +2580,6 @@ [HTMLAnchorElement interface: existence and properties of interface object] expected: FAIL - [HTMLAnchorElement interface object length] - expected: FAIL - [HTMLAnchorElement interface: attribute target] expected: FAIL @@ -2715,9 +2649,6 @@ [HTMLDataElement interface: existence and properties of interface object] expected: FAIL - [HTMLDataElement interface object length] - expected: FAIL - [HTMLDataElement interface: attribute value] expected: FAIL @@ -2727,9 +2658,6 @@ [HTMLTimeElement interface: existence and properties of interface object] expected: FAIL - [HTMLTimeElement interface object length] - expected: FAIL - [HTMLTimeElement interface: attribute dateTime] expected: FAIL @@ -2739,15 +2667,9 @@ [HTMLSpanElement interface: existence and properties of interface object] expected: FAIL - [HTMLSpanElement interface object length] - expected: FAIL - [HTMLBRElement interface: existence and properties of interface object] expected: FAIL - [HTMLBRElement interface object length] - expected: FAIL - [HTMLBRElement interface: attribute clear] expected: FAIL @@ -2757,9 +2679,6 @@ [HTMLModElement interface: existence and properties of interface object] expected: FAIL - [HTMLModElement interface object length] - expected: FAIL - [HTMLModElement interface: attribute cite] expected: FAIL @@ -2799,9 +2718,6 @@ [HTMLImageElement interface: existence and properties of interface object] expected: FAIL - [HTMLImageElement interface object length] - expected: FAIL - [HTMLImageElement interface: attribute srcset] expected: FAIL @@ -2901,9 +2817,6 @@ [HTMLIFrameElement interface: existence and properties of interface object] expected: FAIL - [HTMLIFrameElement interface object length] - expected: FAIL - [HTMLIFrameElement interface: attribute srcdoc] expected: FAIL @@ -2937,9 +2850,6 @@ [HTMLEmbedElement interface: existence and properties of interface object] expected: FAIL - [HTMLEmbedElement interface object length] - expected: FAIL - [HTMLEmbedElement interface: attribute src] expected: FAIL @@ -2991,9 +2901,6 @@ [HTMLObjectElement interface: existence and properties of interface object] expected: FAIL - [HTMLObjectElement interface object length] - expected: FAIL - [HTMLObjectElement interface: attribute data] expected: FAIL @@ -3156,9 +3063,6 @@ [HTMLParamElement interface: existence and properties of interface object] expected: FAIL - [HTMLParamElement interface object length] - expected: FAIL - [HTMLParamElement interface: attribute name] expected: FAIL @@ -3186,9 +3090,6 @@ [HTMLVideoElement interface: existence and properties of interface object] expected: FAIL - [HTMLVideoElement interface object length] - expected: FAIL - [HTMLVideoElement interface: attribute width] expected: FAIL @@ -3363,9 +3264,6 @@ [HTMLAudioElement interface: existence and properties of interface object] expected: FAIL - [HTMLAudioElement interface object length] - expected: FAIL - [HTMLMediaElement interface: document.createElement("audio") must inherit property "error" with the proper type (0)] expected: FAIL @@ -3657,9 +3555,6 @@ [HTMLSourceElement interface: existence and properties of interface object] expected: FAIL - [HTMLSourceElement interface object length] - expected: FAIL - [HTMLSourceElement interface: attribute src] expected: FAIL @@ -3693,9 +3588,6 @@ [HTMLTrackElement interface: existence and properties of interface object] expected: FAIL - [HTMLTrackElement interface object length] - expected: FAIL - [HTMLTrackElement interface: attribute kind] expected: FAIL @@ -3777,9 +3669,6 @@ [HTMLMediaElement interface: existence and properties of interface object] expected: FAIL - [HTMLMediaElement interface object length] - expected: FAIL - [HTMLMediaElement interface: attribute error] expected: FAIL @@ -4686,9 +4575,6 @@ [HTMLMapElement interface: existence and properties of interface object] expected: FAIL - [HTMLMapElement interface object length] - expected: FAIL - [HTMLMapElement interface: attribute name] expected: FAIL @@ -4710,9 +4596,6 @@ [HTMLAreaElement interface: existence and properties of interface object] expected: FAIL - [HTMLAreaElement interface object length] - expected: FAIL - [HTMLAreaElement interface: attribute alt] expected: FAIL @@ -4776,9 +4659,6 @@ [HTMLTableElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableElement interface object length] - expected: FAIL - [HTMLTableElement interface: operation createCaption()] expected: FAIL @@ -4932,9 +4812,6 @@ [HTMLTableCaptionElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableCaptionElement interface object length] - expected: FAIL - [HTMLTableCaptionElement interface: attribute align] expected: FAIL @@ -4944,9 +4821,6 @@ [HTMLTableColElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableColElement interface object length] - expected: FAIL - [HTMLTableColElement interface: attribute span] expected: FAIL @@ -5004,9 +4878,6 @@ [HTMLTableSectionElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableSectionElement interface object length] - expected: FAIL - [HTMLTableSectionElement interface: attribute rows] expected: FAIL @@ -5124,9 +4995,6 @@ [HTMLTableRowElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableRowElement interface object length] - expected: FAIL - [HTMLTableRowElement interface: attribute rowIndex] expected: FAIL @@ -5196,9 +5064,6 @@ [HTMLTableDataCellElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableDataCellElement interface object length] - expected: FAIL - [HTMLTableDataCellElement interface: attribute abbr] expected: FAIL @@ -5244,9 +5109,6 @@ [HTMLTableHeaderCellElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableHeaderCellElement interface object length] - expected: FAIL - [HTMLTableHeaderCellElement interface: attribute scope] expected: FAIL @@ -5310,9 +5172,6 @@ [HTMLTableCellElement interface: existence and properties of interface object] expected: FAIL - [HTMLTableCellElement interface object length] - expected: FAIL - [HTMLTableCellElement interface: attribute rowSpan] expected: FAIL @@ -5352,9 +5211,6 @@ [HTMLFormElement interface: existence and properties of interface object] expected: FAIL - [HTMLFormElement interface object length] - expected: FAIL - [HTMLFormElement interface: attribute elements] expected: FAIL @@ -5388,9 +5244,6 @@ [HTMLLabelElement interface: existence and properties of interface object] expected: FAIL - [HTMLLabelElement interface object length] - expected: FAIL - [HTMLLabelElement interface: attribute form] expected: FAIL @@ -5412,9 +5265,6 @@ [HTMLInputElement interface: existence and properties of interface object] expected: FAIL - [HTMLInputElement interface object length] - expected: FAIL - [HTMLInputElement interface: attribute accept] expected: FAIL @@ -5694,9 +5544,6 @@ [HTMLButtonElement interface: existence and properties of interface object] expected: FAIL - [HTMLButtonElement interface object length] - expected: FAIL - [HTMLButtonElement interface: attribute autofocus] expected: FAIL @@ -5763,9 +5610,6 @@ [HTMLSelectElement interface: existence and properties of interface object] expected: FAIL - [HTMLSelectElement interface object length] - expected: FAIL - [HTMLSelectElement interface: attribute autocomplete] expected: FAIL @@ -5886,15 +5730,9 @@ [HTMLDataListElement interface: existence and properties of interface object] expected: FAIL - [HTMLDataListElement interface object length] - expected: FAIL - [HTMLOptGroupElement interface: existence and properties of interface object] expected: FAIL - [HTMLOptGroupElement interface object length] - expected: FAIL - [HTMLOptGroupElement interface: attribute label] expected: FAIL @@ -5904,9 +5742,6 @@ [HTMLOptionElement interface: existence and properties of interface object] expected: FAIL - [HTMLOptionElement interface object length] - expected: FAIL - [HTMLOptionElement interface: attribute form] expected: FAIL @@ -5934,9 +5769,6 @@ [HTMLTextAreaElement interface: existence and properties of interface object] expected: FAIL - [HTMLTextAreaElement interface object length] - expected: FAIL - [HTMLTextAreaElement interface: attribute autocomplete] expected: FAIL @@ -6189,9 +6021,6 @@ [HTMLOutputElement interface: existence and properties of interface object] expected: FAIL - [HTMLOutputElement interface object length] - expected: FAIL - [HTMLOutputElement interface: attribute htmlFor] expected: FAIL @@ -6270,9 +6099,6 @@ [HTMLProgressElement interface: existence and properties of interface object] expected: FAIL - [HTMLProgressElement interface object length] - expected: FAIL - [HTMLProgressElement interface: attribute value] expected: FAIL @@ -6300,9 +6126,6 @@ [HTMLMeterElement interface: existence and properties of interface object] expected: FAIL - [HTMLMeterElement interface object length] - expected: FAIL - [HTMLMeterElement interface: attribute value] expected: FAIL @@ -6348,9 +6171,6 @@ [HTMLFieldSetElement interface: existence and properties of interface object] expected: FAIL - [HTMLFieldSetElement interface object length] - expected: FAIL - [HTMLFieldSetElement interface: attribute form] expected: FAIL @@ -6378,9 +6198,6 @@ [HTMLLegendElement interface: existence and properties of interface object] expected: FAIL - [HTMLLegendElement interface object length] - expected: FAIL - [HTMLLegendElement interface: attribute form] expected: FAIL @@ -6408,9 +6225,6 @@ [AutocompleteErrorEvent interface: attribute reason] expected: FAIL - [ValidityState interface object length] - expected: FAIL - [ValidityState interface: attribute valueMissing] expected: FAIL @@ -6597,9 +6411,6 @@ [HTMLDialogElement interface: existence and properties of interface object] expected: FAIL - [HTMLDialogElement interface object length] - expected: FAIL - [HTMLDialogElement interface: operation show([object Object\],[object Object\])] expected: FAIL @@ -6612,9 +6423,6 @@ [HTMLScriptElement interface: existence and properties of interface object] expected: FAIL - [HTMLScriptElement interface object length] - expected: FAIL - [HTMLScriptElement interface: attribute type] expected: FAIL @@ -6660,18 +6468,12 @@ [HTMLTemplateElement interface: existence and properties of interface object] expected: FAIL - [HTMLTemplateElement interface object length] - expected: FAIL - [HTMLTemplateElement interface: attribute content] expected: FAIL [HTMLCanvasElement interface: existence and properties of interface object] expected: FAIL - [HTMLCanvasElement interface object length] - expected: FAIL - [HTMLCanvasElement interface: operation probablySupportsContext(DOMString,any)] expected: FAIL @@ -6954,12 +6756,6 @@ [CanvasRenderingContext2D interface: calling ellipse(unrestricted double,unrestricted double,unrestricted double,unrestricted double,unrestricted double,unrestricted double,unrestricted double,boolean) on document.createElement("canvas").getContext("2d") with too few arguments must throw TypeError] expected: FAIL - [CanvasGradient interface object length] - expected: FAIL - - [CanvasPattern interface object length] - expected: FAIL - [CanvasPattern interface: operation setTransform(SVGMatrix)] expected: FAIL @@ -7227,9 +7023,6 @@ [Window interface: existence and properties of interface object] expected: FAIL - [Window interface object length] - expected: FAIL - [Window interface: existence and properties of interface prototype object] expected: FAIL @@ -7998,9 +7791,6 @@ [History interface: calling replaceState(any,DOMString,DOMString) on window.history with too few arguments must throw TypeError] expected: FAIL - [Location interface object length] - expected: FAIL - [Location interface: calling replace(DOMString) on window.location with too few arguments must throw TypeError] expected: FAIL @@ -8295,12 +8085,6 @@ [ErrorEvent interface: existence and properties of interface object] expected: FAIL - [ErrorEvent interface object length] - expected: FAIL - - [Navigator interface object length] - expected: FAIL - [Navigator interface: attribute language] expected: FAIL @@ -8559,9 +8343,6 @@ [MessageEvent interface: existence and properties of interface object] expected: FAIL - [MessageEvent interface object length] - expected: FAIL - [MessageEvent interface: attribute source] expected: FAIL @@ -8625,9 +8406,6 @@ [WebSocket interface: existence and properties of interface object] expected: FAIL - [WebSocket interface object length] - expected: FAIL - [WebSocket interface: attribute bufferedAmount] expected: FAIL @@ -8646,9 +8424,6 @@ [CloseEvent interface: existence and properties of interface object] expected: FAIL - [CloseEvent interface object length] - expected: FAIL - [MessageChannel interface: existence and properties of interface object] expected: FAIL @@ -8742,9 +8517,6 @@ [WorkerGlobalScope interface: existence and properties of interface object] expected: FAIL - [WorkerGlobalScope interface object length] - expected: FAIL - [WorkerGlobalScope interface: operation close()] expected: FAIL @@ -8766,9 +8538,6 @@ [DedicatedWorkerGlobalScope interface: existence and properties of interface object] expected: FAIL - [DedicatedWorkerGlobalScope interface object length] - expected: FAIL - [DedicatedWorkerGlobalScope interface: operation postMessage(any,[object Object\])] expected: FAIL @@ -8799,9 +8568,6 @@ [Worker interface: existence and properties of interface object] expected: FAIL - [Worker interface object length] - expected: FAIL - [Worker interface: operation terminate()] expected: FAIL @@ -8826,9 +8592,6 @@ [SharedWorker interface: attribute onerror] expected: FAIL - [WorkerNavigator interface object length] - expected: FAIL - [WorkerNavigator interface: attribute language] expected: FAIL @@ -8838,24 +8601,12 @@ [WorkerNavigator interface: attribute onLine] expected: FAIL - [WorkerLocation interface object length] - expected: FAIL - - [Storage interface object length] - expected: FAIL - [StorageEvent interface: existence and properties of interface object] expected: FAIL - [StorageEvent interface object length] - expected: FAIL - [HTMLAppletElement interface: existence and properties of interface object] expected: FAIL - [HTMLAppletElement interface object length] - expected: FAIL - [HTMLAppletElement interface: attribute align] expected: FAIL @@ -9033,9 +8784,6 @@ [HTMLFrameSetElement interface: existence and properties of interface object] expected: FAIL - [HTMLFrameSetElement interface object length] - expected: FAIL - [HTMLFrameSetElement interface: attribute cols] expected: FAIL @@ -9129,9 +8877,6 @@ [HTMLFrameElement interface: existence and properties of interface object] expected: FAIL - [HTMLFrameElement interface object length] - expected: FAIL - [HTMLFrameElement interface: attribute name] expected: FAIL @@ -9195,9 +8940,6 @@ [HTMLDirectoryElement interface: existence and properties of interface object] expected: FAIL - [HTMLDirectoryElement interface object length] - expected: FAIL - [HTMLDirectoryElement interface: attribute compact] expected: FAIL @@ -9207,9 +8949,6 @@ [HTMLFontElement interface: existence and properties of interface object] expected: FAIL - [HTMLFontElement interface object length] - expected: FAIL - [HTMLFontElement interface: attribute face] expected: FAIL diff --git a/tests/wpt/metadata/url/interfaces.html.ini b/tests/wpt/metadata/url/interfaces.html.ini index dd6b13a2cf0..b5376e22c9e 100644 --- a/tests/wpt/metadata/url/interfaces.html.ini +++ b/tests/wpt/metadata/url/interfaces.html.ini @@ -111,9 +111,6 @@ [URLSearchParams interface: existence and properties of interface object] expected: FAIL - [URLSearchParams interface object length] - expected: FAIL - [URLSearchParams interface: operation getAll(ScalarValueString)] expected: FAIL diff --git a/tests/wpt/metadata/webstorage/idlharness.html.ini b/tests/wpt/metadata/webstorage/idlharness.html.ini index f8e2048bd32..3df3eb9d734 100644 --- a/tests/wpt/metadata/webstorage/idlharness.html.ini +++ b/tests/wpt/metadata/webstorage/idlharness.html.ini @@ -3,15 +3,9 @@ [Window interface: attribute localStorage] expected: FAIL - [Storage interface object length] - expected: FAIL - [StorageEvent interface: existence and properties of interface object] expected: FAIL - [StorageEvent interface object length] - expected: FAIL - [Window interface: attribute sessionStorage] expected: FAIL diff --git a/tests/wpt/metadata/workers/interfaces.worker.js.ini b/tests/wpt/metadata/workers/interfaces.worker.js.ini index 900a7c63d4b..09a609f8a01 100644 --- a/tests/wpt/metadata/workers/interfaces.worker.js.ini +++ b/tests/wpt/metadata/workers/interfaces.worker.js.ini @@ -1,14 +1,8 @@ [interfaces.worker] type: testharness - [EventTarget interface object length] - expected: FAIL - [WorkerGlobalScope interface: existence and properties of interface object] expected: FAIL - [WorkerGlobalScope interface object length] - expected: FAIL - [WorkerGlobalScope interface: operation close()] expected: FAIL @@ -27,9 +21,6 @@ [DedicatedWorkerGlobalScope interface: existence and properties of interface object] expected: FAIL - [DedicatedWorkerGlobalScope interface object length] - expected: FAIL - [DedicatedWorkerGlobalScope interface: operation postMessage(any,[object Object\])] expected: FAIL @@ -51,9 +42,6 @@ [WorkerGlobalScope interface: self must inherit property "ononline" with the proper type (6)] expected: FAIL - [WorkerNavigator interface object length] - expected: FAIL - [WorkerNavigator interface: attribute language] expected: FAIL @@ -63,9 +51,6 @@ [WorkerNavigator interface: attribute onLine] expected: FAIL - [WorkerLocation interface object length] - expected: FAIL - [WorkerLocation interface: attribute origin] expected: FAIL diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.html b/tests/wpt/mozilla/tests/mozilla/interfaces.html index e93ee2fe46a..ea5c1ec8a03 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.html @@ -13,6 +13,7 @@ var ecmaGlobals = [ "Array", "ArrayBuffer", + "Atomics", "Boolean", "DataView", "Date", @@ -26,6 +27,7 @@ var ecmaGlobals = [ "Int32Array", "Int8Array", "InternalError", + "Intl", "Iterator", "JSON", "Map", @@ -37,17 +39,32 @@ var ecmaGlobals = [ "RangeError", "ReferenceError", "RegExp", + "SIMD", "Set", + "SharedArrayBuffer", + "SharedFloat32Array", + "SharedFloat64Array", + "SharedInt16Array", + "SharedInt32Array", + "SharedInt8Array", + "SharedUint16Array", + "SharedUint32Array", + "SharedUint8Array", + "SharedUint8ClampedArray", "StopIteration", "String", + "Symbol", "SyntaxError", "TypeError", + "TypedObject", + "URIError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray", - "URIError", + "Uint8ClampedArray", "WeakMap", + "WeakSet", ]; // IMPORTANT: Do not change the list below without review from a DOM peer! |