servo: Merge #3531 - Implement MutNullableJS for mutable, nullable member pointers to DOM objects (from Ms2ger:MutNullableJS); r=Ms2ger

Extracted from #3527.

Source-Repo: https://github.com/servo/servo
Source-Revision: bae5440689c67f425f94ec27bf0f61ff955dc290
This commit is contained in:
Josh Matthews 2014-10-01 09:09:28 -06:00
Родитель 5ac3634894
Коммит 179c7b7dcc
11 изменённых файлов: 171 добавлений и 109 удалений

Просмотреть файл

@ -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>;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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()
}

Просмотреть файл

@ -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,

Просмотреть файл

@ -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<'a> NodeHelpers<'a> for JSRef<'a, 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<'a> NodeHelpers<'a> for JSRef<'a, 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<'a> NodeHelpers<'a> for JSRef<'a, 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

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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),

Просмотреть файл

@ -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()
}
}

Просмотреть файл

@ -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),