Rewrite Document creation and reflection.

This commit is contained in:
Ms2ger 2013-11-02 23:36:49 +01:00
parent c2a99933c9
commit 8a7448bc67
3 changed files with 44 additions and 65 deletions

View file

@ -4,17 +4,16 @@
use dom::comment::Comment; use dom::comment::Comment;
use dom::bindings::codegen::DocumentBinding; use dom::bindings::codegen::DocumentBinding;
use dom::bindings::utils::{DOMString, ErrorResult, Fallible}; use dom::bindings::utils::{Reflectable, Reflector, DerivedWrapper, Traceable, reflect_dom_object};
use dom::bindings::utils::{Reflectable, Reflector, DerivedWrapper, NotSupported}; use dom::bindings::utils::{ErrorResult, Fallible, NotSupported, InvalidCharacter};
use dom::bindings::utils::{is_valid_element_name, InvalidCharacter, Traceable}; use dom::bindings::utils::{DOMString, null_str_as_empty_ref, null_str_as_empty, null_str_as_word_null};
use dom::bindings::utils::{null_str_as_empty_ref, null_str_as_empty, null_str_as_word_null}; use dom::bindings::utils::is_valid_element_name;
use dom::documentfragment::DocumentFragment; use dom::documentfragment::DocumentFragment;
use dom::element::{Element}; use dom::element::{Element};
use dom::element::{HTMLHeadElementTypeId, HTMLTitleElementTypeId}; use dom::element::{HTMLHeadElementTypeId, HTMLTitleElementTypeId};
use dom::event::{AbstractEvent, Event, HTMLEventTypeId, UIEventTypeId}; use dom::event::{AbstractEvent, Event, HTMLEventTypeId, UIEventTypeId};
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::htmldocument::HTMLDocument; use dom::htmldocument::HTMLDocument;
use dom::htmlelement::HTMLElement;
use dom::mouseevent::MouseEvent; use dom::mouseevent::MouseEvent;
use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, DocumentNodeTypeId}; use dom::node::{AbstractNode, ScriptView, Node, ElementNodeTypeId, DocumentNodeTypeId};
use dom::text::Text; use dom::text::Text;
@ -29,7 +28,6 @@ use servo_util::tree::{TreeNodeRef, ElementLike};
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::cast; use std::cast;
use std::ptr;
use std::str::eq_slice; use std::str::eq_slice;
use std::ascii::StrAsciiExt; use std::ascii::StrAsciiExt;
use std::unstable::raw::Box; use std::unstable::raw::Box;
@ -40,26 +38,12 @@ pub enum DocumentTypeId {
HTMLDocumentTypeId HTMLDocumentTypeId
} }
pub trait ReflectableDocument {
fn init_reflector(@mut self, cx: *JSContext);
fn init_node(@mut self, doc: AbstractDocument);
}
#[deriving(Eq)] #[deriving(Eq)]
pub struct AbstractDocument { pub struct AbstractDocument {
document: *mut Box<Document> document: *mut Box<Document>
} }
impl AbstractDocument { impl AbstractDocument {
pub fn as_abstract<T: ReflectableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument {
doc.init_reflector(cx);
let abstract = AbstractDocument {
document: unsafe { cast::transmute(doc) }
};
doc.init_node(abstract);
abstract
}
pub fn document<'a>(&'a self) -> &'a Document { pub fn document<'a>(&'a self) -> &'a Document {
unsafe { unsafe {
&(*self.document).data &(*self.document).data
@ -123,8 +107,24 @@ pub struct Document {
} }
impl Document { impl Document {
#[fixed_stack_segment] pub fn reflect_document<D: Reflectable>
pub fn new(window: @mut Window, doctype: DocumentType) -> Document { (document: @mut D,
window: @mut Window,
wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut D) -> *JSObject)
-> AbstractDocument {
assert!(document.reflector().get_jsobject().is_null());
let document = reflect_dom_object(document, window, wrap_fn);
assert!(document.reflector().get_jsobject().is_not_null());
// This surrenders memory management of the document!
let abstract = AbstractDocument {
document: unsafe { cast::transmute(document) }
};
abstract.mut_document().node.set_owner_doc(abstract);
abstract
}
pub fn new_inherited(window: @mut Window, doctype: DocumentType) -> Document {
let node_type = match doctype { let node_type = match doctype {
HTML => HTMLDocumentTypeId, HTML => HTMLDocumentTypeId,
SVG | XML => PlainDocumentTypeId SVG | XML => PlainDocumentTypeId
@ -139,19 +139,15 @@ impl Document {
} }
} }
pub fn new(window: @mut Window, doctype: DocumentType) -> AbstractDocument {
let document = Document::new_inherited(window, doctype);
Document::reflect_document(@mut document, window, DocumentBinding::Wrap)
}
}
impl Document {
pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> { pub fn Constructor(owner: @mut Window) -> Fallible<AbstractDocument> {
let cx = owner.get_cx(); Ok(Document::new(owner, XML))
Ok(AbstractDocument::as_abstract(cx, @mut Document::new(owner, XML)))
}
}
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);
} }
} }
@ -164,16 +160,8 @@ impl Reflectable for AbstractDocument {
self.mut_document().mut_reflector() self.mut_document().mut_reflector()
} }
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
match self.document().doctype { unreachable!()
HTML => {
let doc: @mut HTMLDocument = unsafe { cast::transmute(self.document) };
doc.wrap_object_shared(cx, scope)
}
XML | SVG => {
fail!("no wrapping for documents that don't exist")
}
}
} }
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> {
@ -199,8 +187,8 @@ impl Reflectable for Document {
self.node.mut_reflector() self.node.mut_reflector()
} }
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
DocumentBinding::Wrap(cx, scope, self) unreachable!()
} }
fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> { fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut Reflectable> {

View file

@ -38,13 +38,12 @@ impl DOMParser {
_s: &DOMString, _s: &DOMString,
ty: DOMParserBinding::SupportedType) ty: DOMParserBinding::SupportedType)
-> Fallible<AbstractDocument> { -> Fallible<AbstractDocument> {
let cx = self.owner.get_cx();
match ty { match ty {
Text_html => { Text_html => {
Ok(HTMLDocument::new(self.owner)) Ok(HTMLDocument::new(self.owner))
} }
Text_xml => { Text_xml => {
Ok(AbstractDocument::as_abstract(cx, @mut Document::new(self.owner, XML))) Ok(Document::new(self.owner, XML))
} }
_ => { _ => {
Err(FailureUnknown) Err(FailureUnknown)

View file

@ -4,7 +4,7 @@
use dom::bindings::codegen::HTMLDocumentBinding; use dom::bindings::codegen::HTMLDocumentBinding;
use dom::bindings::utils::{Reflectable, Reflector, Traceable}; use dom::bindings::utils::{Reflectable, Reflector, Traceable};
use dom::document::{AbstractDocument, Document, ReflectableDocument, HTML}; use dom::document::{AbstractDocument, Document, HTML};
use dom::element::HTMLHeadElementTypeId; use dom::element::HTMLHeadElementTypeId;
use dom::htmlcollection::HTMLCollection; use dom::htmlcollection::HTMLCollection;
use dom::node::{AbstractNode, ScriptView, ElementNodeTypeId}; use dom::node::{AbstractNode, ScriptView, ElementNodeTypeId};
@ -14,7 +14,6 @@ use js::jsapi::{JSObject, JSContext, JSTracer};
use servo_util::tree::{TreeNodeRef, ElementLike}; use servo_util::tree::{TreeNodeRef, ElementLike};
use std::ptr;
use std::str::eq_slice; use std::str::eq_slice;
pub struct HTMLDocument { pub struct HTMLDocument {
@ -22,22 +21,15 @@ pub struct HTMLDocument {
} }
impl HTMLDocument { impl HTMLDocument {
pub fn new_inherited(window: @mut Window) -> HTMLDocument {
HTMLDocument {
parent: Document::new_inherited(window, HTML)
}
}
pub fn new(window: @mut Window) -> AbstractDocument { pub fn new(window: @mut Window) -> AbstractDocument {
let doc = @mut HTMLDocument { let document = HTMLDocument::new_inherited(window);
parent: Document::new(window, HTML) Document::reflect_document(@mut document, window, HTMLDocumentBinding::Wrap)
};
AbstractDocument::as_abstract(window.get_cx(), doc)
}
}
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);
} }
} }
@ -97,8 +89,8 @@ impl Reflectable for HTMLDocument {
self.parent.mut_reflector() self.parent.mut_reflector()
} }
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
HTMLDocumentBinding::Wrap(cx, scope, self) unreachable!()
} }
fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut Reflectable> {