Implement MutNullableJS for mutable, nullable member pointers to DOM objects.

This commit is contained in:
Josh Matthews 2014-09-30 16:39:31 +02:00 committed by Ms2ger
parent f73e508821
commit 54fcab61d6
11 changed files with 171 additions and 109 deletions

View file

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