aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/document.rs
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2013-07-30 13:30:24 -0700
committerbors-servo <release+servo@mozilla.com>2013-07-30 13:30:24 -0700
commit0c105b5307bb69e8d43a1c6263b09c1b8e52c355 (patch)
treef69dc2cc92dfdbd5db54c0f7c579b3f65ec43ff2 /src/components/script/dom/document.rs
parentad8fa8b3d75b58102f75848b90ab4721a7cfcfce (diff)
parent5546f2105bea0a3155a1090f3a9a8dfb65c7b47d (diff)
downloadservo-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.rs242
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)
}