mirror of
https://github.com/servo/servo.git
synced 2025-06-20 23:28:59 +01:00
Generate HTMLDocument bindings. Introduce invariant into generated bindings that associated DOM classes are named the same as their interfaces, so Event and Event_ need to be swapped.
This commit is contained in:
parent
ad8fa8b3d7
commit
5546f2105b
18 changed files with 584 additions and 155 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
unsafe {
|
||||
JS_AddObjectRoot(compartment.cx.ptr, rootable);
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
doc
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue