зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
5ac3634894
Коммит
179c7b7dcc
|
@ -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),
|
||||
|
|
Загрузка…
Ссылка в новой задаче