mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Implement MutNullableJS for mutable, nullable member pointers to DOM objects.
This commit is contained in:
parent
f73e508821
commit
54fcab61d6
11 changed files with 171 additions and 109 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue