diff options
author | bors-servo <release+servo@mozilla.com> | 2013-07-30 13:30:24 -0700 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2013-07-30 13:30:24 -0700 |
commit | 0c105b5307bb69e8d43a1c6263b09c1b8e52c355 (patch) | |
tree | f69dc2cc92dfdbd5db54c0f7c579b3f65ec43ff2 /src/components/script/dom/document.rs | |
parent | ad8fa8b3d75b58102f75848b90ab4721a7cfcfce (diff) | |
parent | 5546f2105bea0a3155a1090f3a9a8dfb65c7b47d (diff) | |
download | servo-0c105b5307bb69e8d43a1c6263b09c1b8e52c355.tar.gz servo-0c105b5307bb69e8d43a1c6263b09c1b8e52c355.zip |
auto merge of #641 : jdm/servo/htmldoc2, r=jdm
There are several mechanical changes here that make this look more intimidating than it is. DOMStrings are now passed by reference, and Event and Event_ have swapped names. Finally, there are the various places that need to use `document.with_base |doc| { document.foo }` instead of `document.foo`.
Diffstat (limited to 'src/components/script/dom/document.rs')
-rw-r--r-- | src/components/script/dom/document.rs | 242 |
1 files changed, 168 insertions, 74 deletions
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index 80f677e35cf..c4a1099d8b6 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -3,68 +3,177 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::DocumentBinding; -use dom::bindings::codegen::DocumentBinding::VisibilityState; -use dom::bindings::codegen::DocumentBinding::VisibilityStateValues::Visible; use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string}; -use dom::bindings::utils::{BindingObject, CacheableWrapper}; +use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box, DerivedWrapper}; use dom::element::{HTMLHtmlElement, HTMLHtmlElementTypeId, Element}; -use dom::event::Event_; +use dom::event::Event; use dom::htmlcollection::HTMLCollection; +use dom::htmldocument::HTMLDocument; use dom::node::{AbstractNode, ScriptView, Node}; use dom::window::Window; use dom::windowproxy::WindowProxy; -use js::JSPROP_ENUMERATE; -use js::glue::*; -use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSObject, JSContext}; +use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot, JSObject, JSContext, JSVal}; +use js::glue::RUST_OBJECT_TO_JSVAL; use servo_util::tree::{TreeNodeRef, TreeUtils}; use std::cast; use std::ptr; use std::str::eq_slice; +pub trait WrappableDocument { + fn init_wrapper(@mut self, cx: *JSContext); +} + +pub struct AbstractDocument { + document: *Document +} + +impl AbstractDocument { + pub fn as_abstract<T: WrappableDocument>(cx: *JSContext, doc: @mut T) -> AbstractDocument { + doc.init_wrapper(cx); + AbstractDocument { + document: unsafe { cast::transmute(doc) } + } + } + + pub unsafe fn as_cacheable_wrapper(&self) -> @mut CacheableWrapper { + match self.with_base(|doc| doc.doctype) { + HTML => { + let doc: @mut HTMLDocument = cast::transmute(self.document); + doc as @mut CacheableWrapper + } + SVG | XML => { + fail!("no SVG or XML documents yet") + } + } + } + + unsafe fn transmute<T, R>(&self, f: &fn(&T) -> R) -> R { + let box: *rust_box<T> = cast::transmute(self.document); + f(&(*box).payload) + } + + unsafe fn transmute_mut<T, R>(&self, f: &fn(&mut T) -> R) -> R { + let box: *mut rust_box<T> = cast::transmute(self.document); + f(&mut (*box).payload) + } + + pub fn with_base<R>(&self, callback: &fn(&Document) -> R) -> R { + unsafe { + self.transmute(callback) + } + } + + pub fn with_mut_base<R>(&self, callback: &fn(&mut Document) -> R) -> R { + unsafe { + self.transmute_mut(callback) + } + } + + pub fn with_html<R>(&self, callback: &fn(&HTMLDocument) -> R) -> R { + match self.with_base(|doc| doc.doctype) { + HTML => unsafe { self.transmute(callback) }, + _ => fail!("attempt to downcast a non-HTMLDocument to HTMLDocument") + } + } +} + +pub enum DocumentType { + HTML, + SVG, + XML +} + pub struct Document { root: AbstractNode<ScriptView>, wrapper: WrapperCache, window: Option<@mut Window>, + doctype: DocumentType } -pub fn Document(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> @mut Document { - unsafe { - let doc = @mut Document { - root: root, - wrapper: WrapperCache::new(), - window: window - }; - let compartment = (*window.get_ref().page).js_info.get_ref().js_compartment; +impl Document { + pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>, doctype: DocumentType) -> Document { + let compartment = unsafe {(*window.get_ref().page).js_info.get_ref().js_compartment }; do root.with_base |base| { assert!(base.wrapper.get_wrapper().is_not_null()); let rootable = base.wrapper.get_rootable(); - JS_AddObjectRoot(compartment.cx.ptr, rootable); + unsafe { + JS_AddObjectRoot(compartment.cx.ptr, rootable); + } + } + Document { + root: root, + wrapper: WrapperCache::new(), + window: window, + doctype: doctype + } + } + + pub fn Constructor(owner: @mut Window, _rv: &mut ErrorResult) -> AbstractDocument { + let root = ~HTMLHtmlElement { + parent: Element::new(HTMLHtmlElementTypeId, ~"html") + }; + + let cx = unsafe {(*owner.page).js_info.get_ref().js_compartment.cx.ptr}; + let root = unsafe { Node::as_abstract_node(cx, root) }; + AbstractDocument::as_abstract(cx, @mut Document::new(root, None, XML)) + } +} + +impl WrappableDocument for Document { + pub fn init_wrapper(@mut self, cx: *JSContext) { + self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice + } +} + +impl CacheableWrapper for AbstractDocument { + fn get_wrappercache(&mut self) -> &mut WrapperCache { + do self.with_mut_base |doc| { + doc.get_wrappercache() } + } - let cx = (*window.get_ref().page).js_info.get_ref().js_compartment.cx.ptr; - doc.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice - - match window { - Some(win) => { - //FIXME: This is a hack until Window is autogenerated - let compartment = (*win.page).js_info.get_ref().js_compartment; - compartment.define_property(~"document", - RUST_OBJECT_TO_JSVAL(doc.wrapper.wrapper), - GetJSClassHookStubPointer(PROPERTY_STUB) as *u8, - GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8, - JSPROP_ENUMERATE); + fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { + match self.with_base(|doc| doc.doctype) { + 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") } - None => () } - doc } } +impl BindingObject for AbstractDocument { + fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { + do self.with_mut_base |doc| { + doc.GetParentObject(cx) + } + } +} + +impl DerivedWrapper for AbstractDocument { + fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 { + let cache = self.get_wrappercache(); + let wrapper = cache.get_wrapper(); + unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) }; + return 1; + } + + fn wrap_shared(@mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 { + fail!(~"nyi") + } +} + + impl CacheableWrapper for Document { fn get_wrappercache(&mut self) -> &mut WrapperCache { - unsafe { cast::transmute(&self.wrapper) } + unsafe { + cast::transmute(&self.wrapper) + } } fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { @@ -83,16 +192,6 @@ impl BindingObject for Document { } impl Document { - pub fn Constructor(_owner: @mut Window, _rv: &mut ErrorResult) -> @mut Document { - let root = ~HTMLHtmlElement { - parent: Element::new(HTMLHtmlElementTypeId, ~"html") - }; - - let cx = unsafe {(*_owner.page).js_info.get_ref().js_compartment.cx.ptr}; - let root = unsafe { Node::as_abstract_node(cx, root) }; - Document(root, None) - } - pub fn URL(&self) -> DOMString { null_string } @@ -117,7 +216,15 @@ impl Document { Some(self.root) } - pub fn GetElementsByTagName(&self, tag: DOMString) -> @mut HTMLCollection { + fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) { + let win = self.window.get_ref(); + let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr}; + let cache = win.get_wrappercache(); + let scope = cache.get_wrapper(); + (scope, cx) + } + + pub fn GetElementsByTagName(&self, tag: &DOMString) -> @mut HTMLCollection { let mut elements = ~[]; let tag = tag.to_str(); let _ = for self.root.traverse_preorder |child| { @@ -129,43 +236,33 @@ impl Document { } } }; - let win = self.window.get_ref(); - let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); + let (scope, cx) = self.get_scope_and_cx(); HTMLCollection::new(elements, cx, scope) } - pub fn GetElementsByTagNameNS(&self, _ns: DOMString, _tag: DOMString) -> @mut HTMLCollection { - let win = self.window.get_ref(); - let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); + pub fn GetElementsByTagNameNS(&self, _ns: &DOMString, _tag: &DOMString) -> @mut HTMLCollection { + let (scope, cx) = self.get_scope_and_cx(); HTMLCollection::new(~[], cx, scope) } - pub fn GetElementsByClassName(&self, _class: DOMString) -> @mut HTMLCollection { - let win = self.window.get_ref(); - let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); + pub fn GetElementsByClassName(&self, _class: &DOMString) -> @mut HTMLCollection { + let (scope, cx) = self.get_scope_and_cx(); HTMLCollection::new(~[], cx, scope) - } - pub fn GetElementById(&self, _id: DOMString) -> Option<AbstractNode<ScriptView>> { + pub fn GetElementById(&self, _id: &DOMString) -> Option<AbstractNode<ScriptView>> { None } - pub fn CreateElement(&self, _local_name: DOMString, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { + pub fn CreateElement(&self, _local_name: &DOMString, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { fail!("stub") } - pub fn CreateElementNS(&self, _namespace: DOMString, _qualified_name: DOMString, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { + pub fn CreateElementNS(&self, _namespace: &DOMString, _qualified_name: &DOMString, _rv: &mut ErrorResult) -> AbstractNode<ScriptView> { fail!("stub") } - pub fn CreateEvent(&self, _interface: DOMString, _rv: &mut ErrorResult) -> @mut Event_ { + pub fn CreateEvent(&self, _interface: &DOMString, _rv: &mut ErrorResult) -> @mut Event { fail!("stub") } @@ -189,14 +286,14 @@ impl Document { null_string } - pub fn SetTitle(&self, _title: DOMString, _rv: &mut ErrorResult) { + pub fn SetTitle(&self, _title: &DOMString, _rv: &mut ErrorResult) { } pub fn Dir(&self) -> DOMString { null_string } - pub fn SetDir(&self, _dir: DOMString) { + pub fn SetDir(&self, _dir: &DOMString) { } pub fn GetDefaultView(&self) -> Option<@mut WindowProxy> { @@ -241,11 +338,11 @@ impl Document { self.Hidden() } - pub fn VisibilityState(&self) -> VisibilityState { - Visible + pub fn VisibilityState(&self) -> DocumentBinding::VisibilityState { + DocumentBinding::VisibilityStateValues::Visible } - pub fn MozVisibilityState(&self) -> VisibilityState { + pub fn MozVisibilityState(&self) -> DocumentBinding::VisibilityState { self.VisibilityState() } @@ -253,7 +350,7 @@ impl Document { null_string } - pub fn SetSelectedStyleSheetSet(&self, _sheet: DOMString) { + pub fn SetSelectedStyleSheetSet(&self, _sheet: &DOMString) { } pub fn GetLastStyleSheetSet(&self) -> DOMString { @@ -264,18 +361,18 @@ impl Document { null_string } - pub fn EnableStyleSheetsForSet(&self, _name: DOMString) { + pub fn EnableStyleSheetsForSet(&self, _name: &DOMString) { } pub fn ElementFromPoint(&self, _x: f32, _y: f32) -> Option<AbstractNode<ScriptView>> { None } - pub fn QuerySelector(&self, _selectors: DOMString, _rv: &mut ErrorResult) -> Option<AbstractNode<ScriptView>> { + pub fn QuerySelector(&self, _selectors: &DOMString, _rv: &mut ErrorResult) -> Option<AbstractNode<ScriptView>> { None } - pub fn GetElementsByName(&self, name: DOMString) -> @mut HTMLCollection { + pub fn GetElementsByName(&self, name: &DOMString) -> @mut HTMLCollection { let mut elements = ~[]; let name = name.to_str(); let _ = for self.root.traverse_preorder |child| { @@ -288,10 +385,7 @@ impl Document { } } }; - let win = self.window.get_ref(); - let cx = unsafe {(*win.page).js_info.get_ref().js_compartment.cx.ptr}; - let cache = win.get_wrappercache(); - let scope = cache.get_wrapper(); + let (scope, cx) = self.get_scope_and_cx(); HTMLCollection::new(elements, cx, scope) } |