mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Make Document a Node.
This commit is contained in:
parent
cc76a2188e
commit
99a36cbeb6
10 changed files with 96 additions and 120 deletions
|
@ -9,7 +9,7 @@ use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
|||
use dom::bindings::utils::{DOMString, null_str_as_empty};
|
||||
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
|
||||
use dom::characterdata::CharacterData;
|
||||
use dom::document::AbstractDocument;
|
||||
use dom::document::{AbstractDocument, DocumentTypeId};
|
||||
use dom::documenttype::DocumentType;
|
||||
use dom::element::{Element, ElementTypeId, HTMLImageElementTypeId, HTMLIframeElementTypeId};
|
||||
use dom::element::{HTMLStyleElementTypeId};
|
||||
|
@ -88,7 +88,7 @@ pub struct Node<View> {
|
|||
prev_sibling: Option<AbstractNode<View>>,
|
||||
|
||||
/// The document that this node belongs to.
|
||||
priv owner_doc: AbstractDocument,
|
||||
priv owner_doc: Option<AbstractDocument>,
|
||||
|
||||
/// The live list of children return by .childNodes.
|
||||
child_list: Option<@mut NodeList>,
|
||||
|
@ -103,6 +103,7 @@ pub enum NodeTypeId {
|
|||
DoctypeNodeTypeId,
|
||||
DocumentFragmentNodeTypeId,
|
||||
CommentNodeTypeId,
|
||||
DocumentNodeTypeId(DocumentTypeId),
|
||||
ElementNodeTypeId(ElementTypeId),
|
||||
TextNodeTypeId,
|
||||
}
|
||||
|
@ -204,6 +205,13 @@ impl<'self, View> AbstractNode<View> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Allow consumers to upcast from derived classes.
|
||||
pub fn from_document(doc: AbstractDocument) -> AbstractNode<View> {
|
||||
unsafe {
|
||||
cast::transmute(doc)
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience accessors
|
||||
|
||||
/// Returns the type ID of this node. Fails if this node is borrowed mutably.
|
||||
|
@ -331,6 +339,13 @@ impl<'self, View> AbstractNode<View> {
|
|||
self.transmute_mut(f)
|
||||
}
|
||||
|
||||
pub fn is_document(self) -> bool {
|
||||
match self.type_id() {
|
||||
DocumentNodeTypeId(*) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This should be doing dynamic borrow checking for safety.
|
||||
pub fn with_imm_element<R>(self, f: &fn(&Element) -> R) -> R {
|
||||
if !self.is_element() {
|
||||
|
@ -431,27 +446,7 @@ impl<'self, View> AbstractNode<View> {
|
|||
|
||||
// Issue #1030: should not walk the tree
|
||||
pub fn is_in_doc(&self) -> bool {
|
||||
let document = self.node().owner_doc();
|
||||
match document.document().GetDocumentElement() {
|
||||
None => false,
|
||||
Some(root) => {
|
||||
let mut node = *self;
|
||||
let mut in_doc;
|
||||
loop {
|
||||
match node.parent_node() {
|
||||
Some(parent) => {
|
||||
node = parent;
|
||||
},
|
||||
None => {
|
||||
// Issue #1029: this is horrible.
|
||||
in_doc = unsafe { node.raw_object() as uint == root.raw_object() as uint };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
in_doc
|
||||
}
|
||||
}
|
||||
self.ancestors().any(|node| node.is_document())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,11 +490,11 @@ impl<View> Iterator<AbstractNode<View>> for AbstractNodeChildrenIterator<View> {
|
|||
|
||||
impl<View> Node<View> {
|
||||
pub fn owner_doc(&self) -> AbstractDocument {
|
||||
self.owner_doc
|
||||
self.owner_doc.unwrap()
|
||||
}
|
||||
|
||||
pub fn set_owner_doc(&mut self, document: AbstractDocument) {
|
||||
self.owner_doc = document;
|
||||
self.owner_doc = Some(document);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,6 +523,14 @@ impl Node<ScriptView> {
|
|||
}
|
||||
|
||||
pub fn new(type_id: NodeTypeId, doc: AbstractDocument) -> Node<ScriptView> {
|
||||
Node::new_(type_id, Some(doc))
|
||||
}
|
||||
|
||||
pub fn new_without_doc(type_id: NodeTypeId) -> Node<ScriptView> {
|
||||
Node::new_(type_id, None)
|
||||
}
|
||||
|
||||
fn new_(type_id: NodeTypeId, doc: Option<AbstractDocument>) -> Node<ScriptView> {
|
||||
Node {
|
||||
reflector_: Reflector::new(),
|
||||
type_id: type_id,
|
||||
|
@ -546,32 +549,16 @@ impl Node<ScriptView> {
|
|||
layout_data: LayoutData::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getNextSibling(&mut self) -> Option<&mut AbstractNode<ScriptView>> {
|
||||
match self.next_sibling {
|
||||
// transmute because the compiler can't deduce that the reference
|
||||
// is safe outside of with_mut_base blocks.
|
||||
Some(ref mut n) => Some(unsafe { cast::transmute(n) }),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getFirstChild(&mut self) -> Option<&mut AbstractNode<ScriptView>> {
|
||||
match self.first_child {
|
||||
// transmute because the compiler can't deduce that the reference
|
||||
// is safe outside of with_mut_base blocks.
|
||||
Some(ref mut n) => Some(unsafe { cast::transmute(n) }),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node<ScriptView> {
|
||||
// http://dom.spec.whatwg.org/#dom-node-nodetype
|
||||
pub fn NodeType(&self) -> u16 {
|
||||
match self.type_id {
|
||||
ElementNodeTypeId(_) => 1,
|
||||
TextNodeTypeId => 3,
|
||||
CommentNodeTypeId => 8,
|
||||
DocumentNodeTypeId(_)=> 9,
|
||||
DoctypeNodeTypeId => 10,
|
||||
DocumentFragmentNodeTypeId => 11,
|
||||
}
|
||||
|
@ -592,6 +579,7 @@ impl Node<ScriptView> {
|
|||
}
|
||||
},
|
||||
DocumentFragmentNodeTypeId => ~"#document-fragment",
|
||||
DocumentNodeTypeId(_) => ~"#document"
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -606,7 +594,7 @@ impl Node<ScriptView> {
|
|||
TextNodeTypeId |
|
||||
DoctypeNodeTypeId |
|
||||
DocumentFragmentNodeTypeId => Some(self.owner_doc()),
|
||||
// DocumentNodeTypeId => None
|
||||
DocumentNodeTypeId(_) => None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,7 +663,7 @@ impl Node<ScriptView> {
|
|||
characterdata.Data()
|
||||
}
|
||||
}
|
||||
DoctypeNodeTypeId => {
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -723,7 +711,7 @@ impl Node<ScriptView> {
|
|||
|
||||
// Step 1.
|
||||
match parent.type_id() {
|
||||
// DocumentNodeTypeId |
|
||||
DocumentNodeTypeId(*) |
|
||||
DocumentFragmentNodeTypeId |
|
||||
ElementNodeTypeId(*) => (),
|
||||
_ => {
|
||||
|
@ -754,21 +742,21 @@ impl Node<ScriptView> {
|
|||
TextNodeTypeId |
|
||||
// ProcessingInstructionNodeTypeId |
|
||||
CommentNodeTypeId => (),
|
||||
/*_ => { XXX #838
|
||||
return Err(HierarchyRequest);
|
||||
},*/
|
||||
DocumentNodeTypeId(*) => return Err(HierarchyRequest),
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
match node.type_id() {
|
||||
TextNodeTypeId => {
|
||||
if false { // XXX #838
|
||||
return Err(HierarchyRequest);
|
||||
match node.parent_node() {
|
||||
Some(parent) if parent.is_document() => return Err(HierarchyRequest),
|
||||
_ => ()
|
||||
}
|
||||
},
|
||||
DoctypeNodeTypeId => {
|
||||
if true { // XXX #838
|
||||
return Err(HierarchyRequest);
|
||||
match node.parent_node() {
|
||||
Some(parent) if !parent.is_document() => return Err(HierarchyRequest),
|
||||
_ => ()
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
|
@ -899,7 +887,7 @@ impl Node<ScriptView> {
|
|||
document.document().content_changed();
|
||||
}
|
||||
}
|
||||
DoctypeNodeTypeId => {}
|
||||
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue