diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-09-30 16:39:31 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-10-01 17:06:23 +0200 |
commit | 54fcab61d61533ce4de5436c8721aa7548f8509d (patch) | |
tree | 64572dff214e699be5550ab79e8a55c648ea0d35 /components/script | |
parent | f73e5088219cd6deeea0d4f0612cad750fc532a9 (diff) | |
download | servo-54fcab61d61533ce4de5436c8721aa7548f8509d.tar.gz servo-54fcab61d61533ce4de5436c8721aa7548f8509d.zip |
Implement MutNullableJS for mutable, nullable member pointers to DOM objects.
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/js.rs | 59 | ||||
-rw-r--r-- | components/script/dom/document.rs | 12 | ||||
-rw-r--r-- | components/script/dom/element.rs | 45 | ||||
-rw-r--r-- | components/script/dom/event.rs | 17 | ||||
-rw-r--r-- | components/script/dom/eventdispatcher.rs | 2 | ||||
-rw-r--r-- | components/script/dom/mouseevent.rs | 9 | ||||
-rw-r--r-- | components/script/dom/node.rs | 83 | ||||
-rw-r--r-- | components/script/dom/uievent.rs | 9 | ||||
-rw-r--r-- | components/script/dom/window.rs | 27 | ||||
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 9 | ||||
-rw-r--r-- | components/script/page.rs | 8 |
11 files changed, 171 insertions, 109 deletions
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index a0521b17535..14f717f7455 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -54,6 +54,7 @@ use layout_interface::TrustedNodeAddress; use script_task::StackRoots; use std::cell::{Cell, RefCell}; +use std::default::Default; use std::kinds::marker::ContravariantLifetime; use std::mem; @@ -192,6 +193,62 @@ impl<T: Reflectable> Reflectable for JS<T> { } } +/// A mutable `JS<T>` value, with nullability represented by an enclosing +/// Option wrapper. Must be used in place of traditional internal mutability +/// to ensure that the proper GC barriers are enforced. +#[must_root] +#[jstraceable] +pub struct MutNullableJS<T: Reflectable> { + ptr: Cell<Option<JS<T>>> +} + +impl<T: Assignable<U>, U: Reflectable> MutNullableJS<U> { + pub fn new(initial: Option<T>) -> MutNullableJS<U> { + MutNullableJS { + ptr: Cell::new(initial.map(|initial| { + unsafe { initial.get_js() } + })) + } + } +} + +impl<T: Reflectable> Default for MutNullableJS<T> { + fn default() -> MutNullableJS<T> { + MutNullableJS { + ptr: Cell::new(None) + } + } +} + +impl<T: Reflectable> MutNullableJS<T> { + /// Store an unrooted value in this field. This is safe under the + /// assumption that `MutNullableJS<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<U: Assignable<T>>(&self, val: Option<U>) { + self.ptr.set(val.map(|val| { + unsafe { val.get_js() } + })); + } + + /// Set the inner value to null, without making API users jump through + /// useless type-ascription hoops. + pub fn clear(&self) { + self.assign(None::<JS<T>>); + } + + /// Retrieve a copy of the current optional inner value. + pub fn get(&self) -> Option<Temporary<T>> { + self.ptr.get().map(Temporary::new) + } + + /// Retrieve a copy of the inner optional `JS<T>`. For use by layout, which + /// can't use safe types like Temporary. + pub unsafe fn get_inner(&self) -> Option<JS<T>> { + self.ptr.get() + } +} + impl<T: Reflectable> JS<T> { /// Returns an unsafe pointer to the interior of this JS object without touching the borrow /// flags. This is the only method that be safely accessed from layout. (The fact that this @@ -245,7 +302,7 @@ impl<'a, 'b, T: Reflectable> OptionalRootedReference<T> for Option<Option<Root<' /// 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. -/*definitely not public*/ trait Assignable<T> { +pub trait Assignable<T> { unsafe fn get_js(&self) -> JS<T>; } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index b3261f6df39..cccb2658d40 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -21,7 +21,7 @@ use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter use dom::bindings::error::{HierarchyRequest, NamespaceError}; use dom::bindings::global::GlobalRef; use dom::bindings::global; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable, TemporaryPushable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, OptionalSettable, TemporaryPushable}; use dom::bindings::js::OptionalRootable; use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; @@ -57,12 +57,14 @@ use hubbub::hubbub::{QuirksMode, NoQuirks, LimitedQuirks, FullQuirks}; use layout_interface::{DocumentDamageLevel, ContentChangedDocumentDamage}; use servo_util::namespace; use servo_util::str::{DOMString, split_html_space_chars}; + use string_cache::Atom; +use url::Url; use std::collections::hashmap::HashMap; use std::ascii::StrAsciiExt; use std::cell::{Cell, RefCell}; -use url::Url; +use std::default::Default; use time; #[deriving(PartialEq)] @@ -79,7 +81,7 @@ pub struct Document { reflector_: Reflector, pub window: JS<Window>, idmap: Traceable<RefCell<HashMap<Atom, Vec<JS<Element>>>>>, - implementation: Cell<Option<JS<DOMImplementation>>>, + implementation: MutNullableJS<DOMImplementation>, content_type: DOMString, last_modified: Traceable<RefCell<Option<DOMString>>>, pub encoding_name: Traceable<RefCell<DOMString>>, @@ -288,7 +290,7 @@ impl Document { reflector_: Reflector::new(), window: JS::from_rooted(window), idmap: Traceable::new(RefCell::new(HashMap::new())), - implementation: Cell::new(None), + implementation: Default::default(), content_type: match content_type { Some(string) => string.clone(), None => match is_html_document { @@ -382,7 +384,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { if self.implementation.get().is_none() { self.implementation.assign(Some(DOMImplementation::new(self))); } - Temporary::new(self.implementation.get().as_ref().unwrap().clone()) + self.implementation.get().unwrap() } // http://dom.spec.whatwg.org/#dom-document-url diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 2a3f53751f2..324cb02b2a7 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::ElementBinding; use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::NamedNodeMapBinding::NamedNodeMapMethods; use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast}; -use dom::bindings::js::{JS, JSRef, Temporary, TemporaryPushable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable}; use dom::bindings::js::{OptionalSettable, OptionalRootable, Root}; use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, Reflector}; @@ -38,7 +38,8 @@ use servo_util::namespace; use servo_util::str::DOMString; use std::ascii::StrAsciiExt; -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; +use std::default::Default; use std::mem; use string_cache::{Atom, Namespace}; @@ -51,8 +52,8 @@ pub struct Element { pub prefix: Option<DOMString>, pub attrs: RefCell<Vec<JS<Attr>>>, pub style_attribute: Traceable<RefCell<Option<style::PropertyDeclarationBlock>>>, - pub attr_list: Cell<Option<JS<NamedNodeMap>>>, - class_list: Cell<Option<JS<DOMTokenList>>>, + pub attr_list: MutNullableJS<NamedNodeMap>, + class_list: MutNullableJS<DOMTokenList>, } impl ElementDerived for EventTarget { @@ -156,8 +157,8 @@ impl Element { namespace: namespace, prefix: prefix, attrs: RefCell::new(vec!()), - attr_list: Cell::new(None), - class_list: Cell::new(None), + attr_list: Default::default(), + class_list: Default::default(), style_attribute: Traceable::new(RefCell::new(None)), } } @@ -557,31 +558,25 @@ impl<'a> ElementMethods for JSRef<'a, Element> { // http://dom.spec.whatwg.org/#dom-element-classlist fn ClassList(self) -> Temporary<DOMTokenList> { - match self.class_list.get() { - Some(class_list) => Temporary::new(class_list), - None => { - let class_list = DOMTokenList::new(self, "class").root(); - self.class_list.assign(Some(class_list.deref().clone())); - Temporary::from_rooted(*class_list) - } + if self.class_list.get().is_none() { + let class_list = DOMTokenList::new(self, "class"); + self.class_list.assign(Some(class_list)); } + self.class_list.get().unwrap() } // http://dom.spec.whatwg.org/#dom-element-attributes fn Attributes(self) -> Temporary<NamedNodeMap> { - match self.attr_list.get() { - None => (), - Some(ref list) => return Temporary::new(list.clone()), + if self.attr_list.get().is_none() { + let doc = { + let node: JSRef<Node> = NodeCast::from_ref(self); + node.owner_doc().root() + }; + let window = doc.deref().window.root(); + let list = NamedNodeMap::new(*window, self); + self.attr_list.assign(Some(list)); } - - let doc = { - let node: JSRef<Node> = NodeCast::from_ref(self); - node.owner_doc().root() - }; - let window = doc.deref().window.root(); - let list = NamedNodeMap::new(*window, self); - self.attr_list.assign(Some(list)); - Temporary::new(self.attr_list.get().as_ref().unwrap().clone()) + self.attr_list.get().unwrap() } // http://dom.spec.whatwg.org/#dom-element-getattribute diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index 69caf3f137c..858ac31becd 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -6,12 +6,13 @@ 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, Temporary}; +use dom::bindings::js::{MutNullableJS, JSRef, Temporary}; use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::eventtarget::EventTarget; use servo_util::str::DOMString; use std::cell::{Cell, RefCell}; +use std::default::Default; use time; @@ -40,8 +41,8 @@ pub enum EventTypeId { pub struct Event { pub type_id: EventTypeId, reflector_: Reflector, - pub current_target: Cell<Option<JS<EventTarget>>>, - pub target: Cell<Option<JS<EventTarget>>>, + pub current_target: MutNullableJS<EventTarget>, + pub target: MutNullableJS<EventTarget>, type_: Traceable<RefCell<DOMString>>, pub phase: Traceable<Cell<EventPhase>>, pub canceled: Traceable<Cell<bool>>, @@ -60,8 +61,8 @@ impl Event { Event { type_id: type_id, reflector_: Reflector::new(), - current_target: Cell::new(None), - target: Cell::new(None), + current_target: Default::default(), + target: Default::default(), phase: Traceable::new(Cell::new(PhaseNone)), type_: Traceable::new(RefCell::new("".to_string())), canceled: Traceable::new(Cell::new(false)), @@ -108,11 +109,11 @@ impl<'a> EventMethods for JSRef<'a, Event> { } fn GetTarget(self) -> Option<Temporary<EventTarget>> { - self.target.get().as_ref().map(|target| Temporary::new(target.clone())) + self.target.get() } fn GetCurrentTarget(self) -> Option<Temporary<EventTarget>> { - self.current_target.get().as_ref().map(|target| Temporary::new(target.clone())) + self.current_target.get() } fn DefaultPrevented(self) -> bool { @@ -158,7 +159,7 @@ impl<'a> EventMethods for JSRef<'a, Event> { self.stop_immediate.deref().set(false); self.canceled.deref().set(false); self.trusted.deref().set(false); - self.target.set(None); + self.target.clear(); *self.type_.deref().borrow_mut() = type_; self.bubbles.deref().set(bubbles); self.cancelable.deref().set(cancelable); diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index 0fa26d60715..4c3bcc16fcb 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -133,7 +133,7 @@ pub fn dispatch_event<'a, 'b>(target: JSRef<'a, EventTarget>, event.dispatching.deref().set(false); event.phase.deref().set(PhaseNone); - event.current_target.set(None); + event.current_target.clear(); !event.DefaultPrevented() } diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 9efc5a97d3e..2332417da18 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::InheritTypes::{UIEventCast, MouseEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::global; -use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable}; +use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary, OptionalSettable}; use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::event::{Event, MouseEventTypeId}; @@ -18,6 +18,7 @@ use dom::uievent::UIEvent; use dom::window::Window; use servo_util::str::DOMString; use std::cell::Cell; +use std::default::Default; #[jstraceable] #[must_root] @@ -32,7 +33,7 @@ pub struct MouseEvent { pub alt_key: Traceable<Cell<bool>>, pub meta_key: Traceable<Cell<bool>>, pub button: Traceable<Cell<i16>>, - pub related_target: Cell<Option<JS<EventTarget>>> + pub related_target: MutNullableJS<EventTarget> } impl MouseEventDerived for Event { @@ -54,7 +55,7 @@ impl MouseEvent { alt_key: Traceable::new(Cell::new(false)), meta_key: Traceable::new(Cell::new(false)), button: Traceable::new(Cell::new(0)), - related_target: Cell::new(None) + related_target: Default::default(), } } @@ -142,7 +143,7 @@ impl<'a> MouseEventMethods for JSRef<'a, MouseEvent> { } fn GetRelatedTarget(self) -> Option<Temporary<EventTarget>> { - self.related_target.get().clone().map(|target| Temporary::new(target)) + self.related_target.get() } fn InitMouseEvent(self, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 7e9ce5ec907..632335d14cc 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -22,9 +22,9 @@ use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived; use dom::bindings::error::{Fallible, NotFound, HierarchyRequest, Syntax}; use dom::bindings::global::GlobalRef; use dom::bindings::global; -use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root, OptionalUnrootable}; +use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root}; use dom::bindings::js::{OptionalSettable, TemporaryPushable, OptionalRootedRootable}; -use dom::bindings::js::{ResultRootable, OptionalRootable}; +use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS}; use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; @@ -57,7 +57,8 @@ use js::jsapi::{JSContext, JSObject, JSRuntime}; use js::jsfriendapi; use libc; use libc::uintptr_t; -use std::cell::{Cell, RefCell, Ref, RefMut}; +use std::cell::{RefCell, Ref, RefMut}; +use std::default::Default; use std::iter::{Map, Filter}; use std::mem; use style; @@ -80,25 +81,25 @@ pub struct Node { type_id: NodeTypeId, /// The parent of this node. - parent_node: Cell<Option<JS<Node>>>, + parent_node: MutNullableJS<Node>, /// The first child of this node. - first_child: Cell<Option<JS<Node>>>, + first_child: MutNullableJS<Node>, /// The last child of this node. - last_child: Cell<Option<JS<Node>>>, + last_child: MutNullableJS<Node>, /// The next sibling of this node. - next_sibling: Cell<Option<JS<Node>>>, + next_sibling: MutNullableJS<Node>, /// The previous sibling of this node. - prev_sibling: Cell<Option<JS<Node>>>, + prev_sibling: MutNullableJS<Node>, /// The document that this node belongs to. - owner_doc: Cell<Option<JS<Document>>>, + owner_doc: MutNullableJS<Document>, /// The live list of children return by .childNodes. - child_list: Cell<Option<JS<NodeList>>>, + child_list: MutNullableJS<NodeList>, /// A bitfield of flags for node items. flags: Traceable<RefCell<NodeFlags>>, @@ -358,9 +359,9 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { } } - child.prev_sibling.set(None); - child.next_sibling.set(None); - child.parent_node.set(None); + child.prev_sibling.clear(); + child.next_sibling.clear(); + child.parent_node.clear(); } } @@ -461,25 +462,25 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> { } fn parent_node(self) -> Option<Temporary<Node>> { - self.deref().parent_node.get().map(|node| Temporary::new(node)) + self.deref().parent_node.get() } fn first_child(self) -> Option<Temporary<Node>> { - self.deref().first_child.get().map(|node| Temporary::new(node)) + self.deref().first_child.get() } fn last_child(self) -> Option<Temporary<Node>> { - self.deref().last_child.get().map(|node| Temporary::new(node)) + self.deref().last_child.get() } /// Returns the previous sibling of this node. Fails if this node is borrowed mutably. fn prev_sibling(self) -> Option<Temporary<Node>> { - self.deref().prev_sibling.get().map(|node| Temporary::new(node)) + self.deref().prev_sibling.get() } /// Returns the next sibling of this node. Fails if this node is borrowed mutably. fn next_sibling(self) -> Option<Temporary<Node>> { - self.deref().next_sibling.get().map(|node| Temporary::new(node)) + self.deref().next_sibling.get() } #[inline] @@ -578,7 +579,7 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> { fn is_parent_of(self, child: JSRef<Node>) -> bool { match child.parent_node() { - Some(parent) if parent == Temporary::from_rooted(self) => true, + Some(ref parent) if parent == &Temporary::from_rooted(self) => true, _ => false } } @@ -651,7 +652,7 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> { } fn owner_doc(self) -> Temporary<Document> { - Temporary::new(self.owner_doc.get().as_ref().unwrap().clone()) + self.owner_doc.get().unwrap() } fn set_owner_doc(self, document: JSRef<Document>) { @@ -777,32 +778,32 @@ impl LayoutNodeHelpers for JS<Node> { #[inline] unsafe fn parent_node_ref(&self) -> Option<JS<Node>> { - (*self.unsafe_get()).parent_node.get() + (*self.unsafe_get()).parent_node.get_inner() } #[inline] unsafe fn first_child_ref(&self) -> Option<JS<Node>> { - (*self.unsafe_get()).first_child.get() + (*self.unsafe_get()).first_child.get_inner() } #[inline] unsafe fn last_child_ref(&self) -> Option<JS<Node>> { - (*self.unsafe_get()).last_child.get() + (*self.unsafe_get()).last_child.get_inner() } #[inline] unsafe fn prev_sibling_ref(&self) -> Option<JS<Node>> { - (*self.unsafe_get()).prev_sibling.get() + (*self.unsafe_get()).prev_sibling.get_inner() } #[inline] unsafe fn next_sibling_ref(&self) -> Option<JS<Node>> { - (*self.unsafe_get()).next_sibling.get() + (*self.unsafe_get()).next_sibling.get_inner() } #[inline] unsafe fn owner_doc_for_layout(&self) -> JS<Document> { - (*self.unsafe_get()).owner_doc.get().unwrap() + (*self.unsafe_get()).owner_doc.get_inner().unwrap() } } @@ -1025,13 +1026,13 @@ impl Node { eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)), type_id: type_id, - parent_node: Cell::new(None), - first_child: Cell::new(None), - last_child: Cell::new(None), - next_sibling: Cell::new(None), - prev_sibling: Cell::new(None), - owner_doc: Cell::new(doc.unrooted()), - child_list: Cell::new(None), + parent_node: Default::default(), + first_child: Default::default(), + last_child: Default::default(), + next_sibling: Default::default(), + prev_sibling: Default::default(), + owner_doc: MutNullableJS::new(doc), + child_list: Default::default(), flags: Traceable::new(RefCell::new(NodeFlags::new(type_id))), @@ -1304,7 +1305,7 @@ impl Node { fn pre_remove(child: JSRef<Node>, parent: JSRef<Node>) -> Fallible<Temporary<Node>> { // Step 1. match child.parent_node() { - Some(node) if node != Temporary::from_rooted(parent) => return Err(NotFound), + Some(ref node) if node != &Temporary::from_rooted(parent) => return Err(NotFound), _ => () } @@ -1535,7 +1536,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> { // http://dom.spec.whatwg.org/#dom-node-parentnode fn GetParentNode(self) -> Option<Temporary<Node>> { - self.parent_node.get().map(|node| Temporary::new(node)) + self.parent_node.get() } // http://dom.spec.whatwg.org/#dom-node-parentelement @@ -1558,34 +1559,34 @@ impl<'a> NodeMethods for JSRef<'a, Node> { fn ChildNodes(self) -> Temporary<NodeList> { match self.child_list.get() { None => (), - Some(ref list) => return Temporary::new(list.clone()), + Some(list) => return list, } let doc = self.owner_doc().root(); let window = doc.deref().window.root(); let child_list = NodeList::new_child_list(*window, self); self.child_list.assign(Some(child_list)); - Temporary::new(self.child_list.get().as_ref().unwrap().clone()) + self.child_list.get().unwrap() } // http://dom.spec.whatwg.org/#dom-node-firstchild fn GetFirstChild(self) -> Option<Temporary<Node>> { - self.first_child.get().map(|node| Temporary::new(node)) + self.first_child.get() } // http://dom.spec.whatwg.org/#dom-node-lastchild fn GetLastChild(self) -> Option<Temporary<Node>> { - self.last_child.get().map(|node| Temporary::new(node)) + self.last_child.get() } // http://dom.spec.whatwg.org/#dom-node-previoussibling fn GetPreviousSibling(self) -> Option<Temporary<Node>> { - self.prev_sibling.get().map(|node| Temporary::new(node)) + self.prev_sibling.get() } // http://dom.spec.whatwg.org/#dom-node-nextsibling fn GetNextSibling(self) -> Option<Temporary<Node>> { - self.next_sibling.get().map(|node| Temporary::new(node)) + self.next_sibling.get() } // http://dom.spec.whatwg.org/#dom-node-nodevalue diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index eac29a4ab24..86501d47324 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::InheritTypes::{EventCast, UIEventDerived}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::global; -use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, OptionalSettable}; +use dom::bindings::js::{MutNullableJS, JSRef, RootedReference, Temporary, OptionalSettable}; use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::event::{Event, EventTypeId, UIEventTypeId}; @@ -17,12 +17,13 @@ use dom::window::Window; use servo_util::str::DOMString; use std::cell::Cell; +use std::default::Default; #[jstraceable] #[must_root] pub struct UIEvent { pub event: Event, - view: Cell<Option<JS<Window>>>, + view: MutNullableJS<Window>, detail: Traceable<Cell<i32>> } @@ -36,7 +37,7 @@ impl UIEvent { pub fn new_inherited(type_id: EventTypeId) -> UIEvent { UIEvent { event: Event::new_inherited(type_id), - view: Cell::new(None), + view: Default::default(), detail: Traceable::new(Cell::new(0)), } } @@ -70,7 +71,7 @@ impl UIEvent { impl<'a> UIEventMethods for JSRef<'a, UIEvent> { fn GetView(self) -> Option<Temporary<Window>> { - self.view.get().map(|view| Temporary::new(view)) + self.view.get() } fn Detail(self) -> i32 { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index d0c33ebc1ca..f48fb5a2e43 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::error::{Fallible, InvalidCharacter}; use dom::bindings::global; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalSettable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, OptionalSettable}; use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::{Reflectable, Reflector}; use dom::browsercontext::BrowserContext; @@ -44,6 +44,7 @@ use std::cell::{Cell, RefCell}; use std::cmp; use std::comm::{channel, Sender}; use std::comm::Select; +use std::default::Default; use std::hash::{Hash, sip}; use std::io::timer::Timer; use std::ptr; @@ -81,16 +82,16 @@ pub struct Window { eventtarget: EventTarget, pub script_chan: ScriptChan, pub control_chan: ScriptControlChan, - console: Cell<Option<JS<Console>>>, - location: Cell<Option<JS<Location>>>, - navigator: Cell<Option<JS<Navigator>>>, + console: MutNullableJS<Console>, + location: MutNullableJS<Location>, + navigator: MutNullableJS<Navigator>, pub image_cache_task: ImageCacheTask, pub active_timers: Traceable<RefCell<HashMap<TimerId, TimerHandle>>>, next_timer_handle: Traceable<Cell<i32>>, pub compositor: Untraceable<Box<ScriptListener+'static>>, pub browser_context: Traceable<RefCell<Option<BrowserContext>>>, pub page: Rc<Page>, - performance: Cell<Option<JS<Performance>>>, + performance: MutNullableJS<Performance>, pub navigationStart: u64, pub navigationStartPrecise: f64, screen: Cell<Option<JS<Screen>>>, @@ -225,7 +226,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { let location = Location::new(self, page); self.location.assign(Some(location)); } - Temporary::new(self.location.get().as_ref().unwrap().clone()) + self.location.get().unwrap() } fn Console(self) -> Temporary<Console> { @@ -233,7 +234,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { let console = Console::new(&global::Window(self)); self.console.assign(Some(console)); } - Temporary::new(self.console.get().as_ref().unwrap().clone()) + self.console.get().unwrap() } fn Navigator(self) -> Temporary<Navigator> { @@ -241,7 +242,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { let navigator = Navigator::new(self); self.navigator.assign(Some(navigator)); } - Temporary::new(self.navigator.get().as_ref().unwrap().clone()) + self.navigator.get().unwrap() } fn SetTimeout(self, _cx: *mut JSContext, callback: JSVal, timeout: i32) -> i32 { @@ -289,7 +290,7 @@ impl<'a> WindowMethods for JSRef<'a, Window> { let performance = Performance::new(self); self.performance.assign(Some(performance)); } - Temporary::new(self.performance.get().as_ref().unwrap().clone()) + self.performance.get().unwrap() } fn GetOnclick(self) -> Option<EventHandlerNonNull> { @@ -529,16 +530,16 @@ impl Window { eventtarget: EventTarget::new_inherited(WindowTypeId), script_chan: script_chan, control_chan: control_chan, - console: Cell::new(None), + console: Default::default(), compositor: Untraceable::new(compositor), page: page, - location: Cell::new(None), - navigator: Cell::new(None), + location: Default::default(), + navigator: Default::default(), image_cache_task: image_cache_task, active_timers: Traceable::new(RefCell::new(HashMap::new())), next_timer_handle: Traceable::new(Cell::new(0)), browser_context: Traceable::new(RefCell::new(None)), - performance: Cell::new(None), + performance: Default::default(), navigationStart: time::get_time().sec as u64, navigationStartPrecise: time::precise_time_s(), screen: Cell::new(None), diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 7bb38cf49df..dd3ababc8cb 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -13,7 +13,7 @@ use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult, Fallible, InvalidState, InvalidAccess}; use dom::bindings::error::{Network, Syntax, Security, Abort, Timeout}; use dom::bindings::global::{GlobalField, GlobalRef, WorkerField}; -use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootedRootable}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, OptionalRootedRootable}; use dom::bindings::str::ByteString; use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; @@ -53,6 +53,7 @@ use servo_util::task::spawn_named; use std::ascii::StrAsciiExt; use std::cell::{Cell, RefCell}; use std::comm::{Sender, Receiver, channel}; +use std::default::Default; use std::io::{BufReader, MemWriter, Timer}; use std::from_str::FromStr; use std::path::BytesContainer; @@ -115,7 +116,7 @@ pub struct XMLHttpRequest { status_text: Traceable<RefCell<ByteString>>, response: Traceable<RefCell<ByteString>>, response_type: Traceable<Cell<XMLHttpRequestResponseType>>, - response_xml: Cell<Option<JS<Document>>>, + response_xml: MutNullableJS<Document>, response_headers: Untraceable<RefCell<ResponseHeaderCollection>>, // Associated concepts @@ -149,7 +150,7 @@ impl XMLHttpRequest { status_text: Traceable::new(RefCell::new(ByteString::new(vec!()))), response: Traceable::new(RefCell::new(ByteString::new(vec!()))), response_type: Traceable::new(Cell::new(_empty)), - response_xml: Cell::new(None), + response_xml: Default::default(), response_headers: Untraceable::new(RefCell::new(ResponseHeaderCollection::new())), request_method: Untraceable::new(RefCell::new(Get)), @@ -667,7 +668,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> { } } fn GetResponseXML(self) -> Option<Temporary<Document>> { - self.response_xml.get().map(|response| Temporary::new(response)) + self.response_xml.get() } } diff --git a/components/script/page.rs b/components/script/page.rs index 41083ca2250..b25be6122bb 100644 --- a/components/script/page.rs +++ b/components/script/page.rs @@ -5,7 +5,7 @@ use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast}; -use dom::bindings::js::{JS, JSRef, Temporary}; +use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary}; use dom::bindings::js::OptionalRootable; use dom::bindings::trace::{Traceable, Untraceable}; use dom::bindings::utils::GlobalStaticData; @@ -30,12 +30,14 @@ use servo_net::resource_task::ResourceTask; use servo_util::str::DOMString; use std::cell::{Cell, RefCell, Ref, RefMut}; use std::comm::{channel, Receiver, Empty, Disconnected}; +use std::default::Default; use std::mem::replace; use std::rc::Rc; use url::Url; /// Encapsulates a handle to a frame and its associated layout information. #[jstraceable] +#[allow(unrooted_must_root)] // FIXME(#3543) should be must_root. pub struct Page { /// Pipeline id associated with this page. pub id: PipelineId, @@ -78,7 +80,7 @@ pub struct Page { pub resize_event: Untraceable<Cell<Option<WindowSizeData>>>, /// Pending scroll to fragment event, if any - pub fragment_node: Cell<Option<JS<Element>>>, + pub fragment_node: MutNullableJS<Element>, /// Associated resource task for use by DOM objects like XMLHttpRequest pub resource_task: Untraceable<ResourceTask>, @@ -152,7 +154,7 @@ impl Page { url: Untraceable::new(RefCell::new(None)), next_subpage_id: Traceable::new(Cell::new(SubpageId(0))), resize_event: Untraceable::new(Cell::new(None)), - fragment_node: Cell::new(None), + fragment_node: Default::default(), last_reflow_id: Traceable::new(Cell::new(0)), resource_task: Untraceable::new(resource_task), constellation_chan: Untraceable::new(constellation_chan), |