diff options
Diffstat (limited to 'src/components/script/dom')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Document.webidl | 2 | ||||
-rw-r--r-- | src/components/script/dom/bindings/node.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/document.rs | 69 | ||||
-rw-r--r-- | src/components/script/dom/domparser.rs | 24 | ||||
-rw-r--r-- | src/components/script/dom/htmldocument.rs | 5 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 67 |
6 files changed, 83 insertions, 89 deletions
diff --git a/src/components/script/dom/bindings/codegen/Document.webidl b/src/components/script/dom/bindings/codegen/Document.webidl index e834b875184..ef479f01a97 100644 --- a/src/components/script/dom/bindings/codegen/Document.webidl +++ b/src/components/script/dom/bindings/codegen/Document.webidl @@ -24,7 +24,7 @@ enum VisibilityState { "hidden", "visible" }; /* http://dom.spec.whatwg.org/#interface-document */ [Constructor] -interface Document /*: Node*/ { //XXXjdm Requires servo/#623 +interface Document : Node { /*[Throws] readonly attribute DOMImplementation implementation;*/ // readonly attribute DOMString URL; diff --git a/src/components/script/dom/bindings/node.rs b/src/components/script/dom/bindings/node.rs index 5adf545f14c..e2d10ec6387 100644 --- a/src/components/script/dom/bindings/node.rs +++ b/src/components/script/dom/bindings/node.rs @@ -3,10 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::utils::{Reflectable, Reflector, Traceable}; +use dom::document::{PlainDocumentTypeId, HTMLDocumentTypeId}; use dom::element::*; use dom::types::*; use dom::node::{AbstractNode, ElementNodeTypeId, TextNodeTypeId, CommentNodeTypeId}; -use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, ScriptView}; +use dom::node::{DoctypeNodeTypeId, DocumentFragmentNodeTypeId, ScriptView, DocumentNodeTypeId}; use std::cast; use std::libc; @@ -95,6 +96,8 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject CommentNodeTypeId => generate_element!(Comment), DoctypeNodeTypeId => generate_element!(DocumentType), DocumentFragmentNodeTypeId => generate_element!(DocumentFragment), + DocumentNodeTypeId(PlainDocumentTypeId) => generate_element!(Document), + DocumentNodeTypeId(HTMLDocumentTypeId) => generate_element!(HTMLDocument), TextNodeTypeId => generate_element!(Text), } } diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index dc8cec50668..bbed257503a 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -13,14 +13,12 @@ use dom::element::{HTMLHtmlElementTypeId, HTMLHeadElementTypeId, HTMLTitleElemen use dom::htmlcollection::HTMLCollection; use dom::htmldocument::HTMLDocument; use dom::htmlelement::HTMLElement; -use dom::htmlhtmlelement::HTMLHtmlElement; -use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId}; +use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, DocumentNodeTypeId}; use dom::text::Text; use dom::window::Window; use dom::htmltitleelement::HTMLTitleElement; use html::hubbub_html_parser::build_element_from_tag; -use js::jsapi::{JSObject, JSContext, JSVal}; -use js::jsapi::{JSTRACE_OBJECT, JSTracer, JS_CallTracer}; +use js::jsapi::{JSObject, JSContext, JSVal, JSTracer}; use js::glue::RUST_OBJECT_TO_JSVAL; use servo_util::tree::{TreeNodeRef, ElementLike}; @@ -29,12 +27,18 @@ use std::hashmap::HashMap; use std::cast; use std::ptr; use std::str::eq_slice; -use std::libc; use std::ascii::StrAsciiExt; use std::unstable::raw::Box; +#[deriving(Eq)] +pub enum DocumentTypeId { + PlainDocumentTypeId, + HTMLDocumentTypeId +} + pub trait ReflectableDocument { fn init_reflector(@mut self, cx: *JSContext); + fn init_node(@mut self, doc: AbstractDocument); } #[deriving(Eq)] @@ -45,9 +49,11 @@ pub struct AbstractDocument { impl AbstractDocument { pub fn as_abstract<T: ReflectableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument { doc.init_reflector(cx); - AbstractDocument { + let abstract = AbstractDocument { document: unsafe { cast::transmute(doc) } - } + }; + doc.init_node(abstract); + abstract } pub fn document<'a>(&'a self) -> &'a Document { @@ -91,7 +97,7 @@ impl AbstractDocument { }); let document = self.mut_document(); - document.root = Some(root); + document.node.AppendChild(AbstractNode::from_document(*self), root); // Register elements having "id" attribute to the owner doc. document.register_nodes_with_id(&root); document.content_changed(); @@ -105,7 +111,7 @@ pub enum DocumentType { } pub struct Document { - priv root: Option<AbstractNode<ScriptView>>, + node: Node<ScriptView>, reflector_: Reflector, window: @mut Window, doctype: DocumentType, @@ -116,8 +122,12 @@ pub struct Document { impl Document { #[fixed_stack_segment] pub fn new(window: @mut Window, doctype: DocumentType) -> Document { + let node_type = match doctype { + HTML => HTMLDocumentTypeId, + SVG | XML => PlainDocumentTypeId + }; Document { - root: None, + node: Node::new_without_doc(DocumentNodeTypeId(node_type)), reflector_: Reflector::new(), window: window, doctype: doctype, @@ -128,16 +138,7 @@ impl Document { pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> { let cx = owner.get_cx(); - - let document = AbstractDocument::as_abstract(cx, @mut Document::new(owner, XML)); - - let root = @HTMLHtmlElement { - htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document) - }; - let root = unsafe { Node::as_abstract_node(cx, root) }; - document.set_root(root); - - Ok(document) + Ok(AbstractDocument::as_abstract(cx, @mut Document::new(owner, XML))) } } @@ -145,6 +146,11 @@ impl ReflectableDocument for Document { fn init_reflector(@mut self, cx: *JSContext) { self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice } + + fn init_node(@mut self, doc: AbstractDocument) { + self.node.set_owner_doc(doc); + self.node.add_to_doc(AbstractNode::from_document(doc), doc); + } } impl Reflectable for AbstractDocument { @@ -184,11 +190,11 @@ impl DerivedWrapper for AbstractDocument { impl Reflectable for Document { fn reflector<'a>(&'a self) -> &'a Reflector { - &self.reflector_ + self.node.reflector() } fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector { - &mut self.reflector_ + self.node.mut_reflector() } fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { @@ -202,7 +208,7 @@ impl Reflectable for Document { impl Document { pub fn GetDocumentElement(&self) -> Option<AbstractNode<ScriptView>> { - self.root + self.node.first_child } fn get_cx(&self) -> *JSContext { @@ -414,21 +420,6 @@ fn foreach_ided_elements(root: &AbstractNode<ScriptView>, impl Traceable for Document { #[fixed_stack_segment] fn trace(&self, tracer: *mut JSTracer) { - match self.root { - None => {}, - Some(root) => { - unsafe { - (*tracer).debugPrinter = ptr::null(); - (*tracer).debugPrintIndex = -1; - do "root".to_c_str().with_ref |name| { - (*tracer).debugPrintArg = name as *libc::c_void; - debug!("tracing root node"); - JS_CallTracer(tracer as *JSTracer, - root.reflector().get_jsobject(), - JSTRACE_OBJECT as u32); - } - } - } - } + self.node.trace(tracer); } } diff --git a/src/components/script/dom/domparser.rs b/src/components/script/dom/domparser.rs index cc3db3e07a7..a29cdfb32ff 100644 --- a/src/components/script/dom/domparser.rs +++ b/src/components/script/dom/domparser.rs @@ -4,13 +4,9 @@ use dom::bindings::codegen::DOMParserBinding; use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml}; -use dom::bindings::utils::{DOMString, Fallible, Reflector, Reflectable}; +use dom::bindings::utils::{DOMString, Fallible, Reflector, Reflectable, FailureUnknown}; use dom::document::{AbstractDocument, Document, XML}; -use dom::element::HTMLHtmlElementTypeId; use dom::htmldocument::HTMLDocument; -use dom::htmlelement::HTMLElement; -use dom::htmlhtmlelement::HTMLHtmlElement; -use dom::node::Node; use dom::window::Window; pub struct DOMParser { @@ -41,25 +37,17 @@ impl DOMParser { ty: DOMParserBinding::SupportedType) -> Fallible<AbstractDocument> { let cx = self.owner.get_cx(); - let document = match ty { + match ty { Text_html => { - HTMLDocument::new(self.owner) + Ok(HTMLDocument::new(self.owner)) } Text_xml => { - AbstractDocument::as_abstract(cx, @mut Document::new(self.owner, XML)) + Ok(AbstractDocument::as_abstract(cx, @mut Document::new(self.owner, XML))) } _ => { - fail!("unsupported document type") + Err(FailureUnknown) } - }; - - let root = @HTMLHtmlElement { - htmlelement: HTMLElement::new(HTMLHtmlElementTypeId, ~"html", document) - }; - let root = unsafe { Node::as_abstract_node(cx, root) }; - document.set_root(root); - - Ok(document) + } } } diff --git a/src/components/script/dom/htmldocument.rs b/src/components/script/dom/htmldocument.rs index cadba01ce97..d4ac4fa0e52 100644 --- a/src/components/script/dom/htmldocument.rs +++ b/src/components/script/dom/htmldocument.rs @@ -35,6 +35,11 @@ impl ReflectableDocument for HTMLDocument { fn init_reflector(@mut self, cx: *JSContext) { self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice } + + fn init_node(@mut self, doc: AbstractDocument) { + self.parent.node.set_owner_doc(doc); + self.parent.node.add_to_doc(AbstractNode::from_document(doc), doc); + } } impl HTMLDocument { diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 15d2b47c0a9..249cfdd1ac1 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -9,7 +9,7 @@ use dom::bindings::utils::{Reflectable, Reflector}; 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, } @@ -200,6 +201,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. @@ -327,6 +335,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() { @@ -463,11 +478,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); } } @@ -508,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, @@ -526,24 +549,6 @@ 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> { @@ -552,6 +557,7 @@ impl Node<ScriptView> { ElementNodeTypeId(_) => 1, TextNodeTypeId => 3, CommentNodeTypeId => 8, + DocumentNodeTypeId(_)=> 9, DoctypeNodeTypeId => 10, DocumentFragmentNodeTypeId => 11, } @@ -572,6 +578,7 @@ impl Node<ScriptView> { } }, DocumentFragmentNodeTypeId => ~"#document-fragment", + DocumentNodeTypeId(_) => ~"#document" }) } @@ -586,7 +593,7 @@ impl Node<ScriptView> { TextNodeTypeId | DoctypeNodeTypeId | DocumentFragmentNodeTypeId => Some(self.owner_doc()), - // DocumentNodeTypeId => None + DocumentNodeTypeId(_) => None } } @@ -655,7 +662,7 @@ impl Node<ScriptView> { characterdata.Data() } } - DoctypeNodeTypeId => { + DoctypeNodeTypeId | DocumentNodeTypeId(_) => { None } } @@ -722,7 +729,7 @@ impl Node<ScriptView> { document.document().content_changed(); } } - DoctypeNodeTypeId => {} + DoctypeNodeTypeId | DocumentNodeTypeId(_) => {} } Ok(()) } @@ -744,10 +751,9 @@ impl Node<ScriptView> { if new_child.is_doctype() { return true; } - if !this_node.is_element() { - // FIXME: This should also work for Document and DocumentFragments when they inherit from node. - // per jgraham - return true; + match this_node.type_id() { + DocumentNodeTypeId(*) | ElementNodeTypeId(*) => (), + _ => return true } if this_node == new_child { return true; @@ -798,7 +804,8 @@ impl Node<ScriptView> { // Unregister elements having "id' from the owner doc. // This need be called before target nodes are removed from tree. - self.owner_doc.mut_document().unregister_nodes_with_id(&abstract_self); + let owner_doc = self.owner_doc(); + owner_doc.mut_document().unregister_nodes_with_id(&abstract_self); abstract_self.remove_child(node); // Signal the document that it needs to update its display. |