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:
Josh Matthews 2013-07-27 14:28:05 -04:00
parent ad8fa8b3d7
commit 5546f2105b
18 changed files with 584 additions and 155 deletions

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use platform::{Application, Window};
use script::dom::event::{Event, ClickEvent, MouseDownEvent, MouseUpEvent, ResizeEvent};
use script::dom::event::{Event_, ClickEvent, MouseDownEvent, MouseUpEvent, ResizeEvent};
use script::script_task::{LoadMsg, NavigateMsg, SendEventMsg};
use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
@ -431,7 +431,7 @@ impl CompositorTask {
}
MouseWindowEventClass(mouse_window_event) => {
let event: Event;
let event: Event_;
let world_mouse_point = |layer_mouse_point: Point2D<f32>| {
layer_mouse_point + world_offset
};

View file

@ -135,6 +135,8 @@ DOMInterfaces = {
},
'Document': {
'nativeType': 'AbstractDocument',
'pointerType': '',
},
'DOMParser': {
@ -159,11 +161,8 @@ DOMInterfaces = {
}
}],
'Event': [
{
'nativeType': 'Event_'
'Event': {
},
],
'EventListener': [
{
@ -214,6 +213,11 @@ DOMInterfaces = {
'pointerType': '@mut '
}],
'HTMLDocument': {
'nativeType': 'AbstractDocument',
'pointerType': '',
},
'HTMLOptionsCollection': [
{
'nativeType': 'nsHTMLOptionCollection',
@ -529,7 +533,8 @@ addExternalIface('DOMStringList', nativeType='nsDOMStringList',
addExternalIface('Element', nativeType='AbstractNode<ScriptView>', pointerType='')
addExternalIface('File')
addExternalIface('HitRegionOptions', nativeType='nsISupports')
addExternalIface('HTMLElement')
addExternalIface('HTMLElement', nativeType='AbstractNode<ScriptView>', pointerType='')
addExternalIface('HTMLHeadElement', nativeType='AbstractNode<ScriptView>', pointerType='')
addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
addExternalIface('Node', nativeType='AbstractNode<ScriptView>', pointerType='')
addExternalIface('PaintRequest')

View file

@ -533,7 +533,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
return template
return CGWrapper(
CGIndenter(CGGeneric(template)),
pre="if ${haveValue} != 0 {\n",
pre="if ${haveValue} {\n",
post=("\n"
"} else {\n"
"%s;\n"
@ -1062,9 +1062,10 @@ for (uint32_t i = 0; i < length; ++i) {
"%s.SetNull()" % varName)
return handleDefault(
conversionCode,
("static const PRUnichar data[] = { %s };\n"
"%s.SetData(data, ArrayLength(data) - 1)" %
(", ".join(["'" + char + "'" for char in defaultValue.value] + ["0"]),
("static data: [u8, ..%s] = [ %s ];\n"
"%s = str(str::from_bytes(data));" %
(len(defaultValue.value) + 1,
", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
varName)))
if isMember:
@ -1256,7 +1257,7 @@ for (uint32_t i = 0; i < length; ++i) {
assert(tag == IDLType.Tags.bool)
defaultStr = toStringBool(defaultValue.value)
template = CGWrapper(CGIndenter(CGGeneric(template)),
pre="if ${haveValue} != 0 {\n",
pre="if ${haveValue} {\n",
post=("\n"
"} else {\n"
" %s = %s;\n"
@ -1536,7 +1537,12 @@ for (uint32_t i = 0; i < length; ++i) {
if not isCreator:
raise MethodNotCreatorError(descriptor.interface.identifier.name)
wrapMethod = "WrapNewBindingNonWrapperCachedObject"
wrap = "%s(cx, ${obj}, %s as @mut CacheableWrapper, ${jsvalPtr})" % (wrapMethod, result)
properResult = result
if descriptor.pointerType == '':
properResult = result + ".as_cacheable_wrapper()"
else:
properResult += " as @mut CacheableWrapper"
wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, properResult)
# We don't support prefable stuff in workers.
assert(not descriptor.prefable or not descriptor.workers)
if not descriptor.prefable:
@ -1604,7 +1610,7 @@ if %(resultStr)s.is_null() {
if type.nullable():
toValue = "RUST_OBJECT_TO_JSVAL(%s)"
else:
toValue = "JS::ObjectValue(*%s)"
toValue = "RUST_OBJECT_TO_JSVAL(%s)"
# NB: setValue(..., True) calls JS_WrapValue(), so is fallible
return (setValue(toValue % result, True), False)
@ -2485,7 +2491,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
def __init__(self, descriptor):
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'),
Argument('@mut ' + descriptor.nativeType, 'aObject'),
Argument('@mut ' + descriptor.name, 'aObject'),
Argument('*mut bool', 'aTriedToWrap')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap_', '*JSObject', args)
@ -2522,7 +2528,7 @@ class CGWrapMethod(CGAbstractMethod):
# XXX can we wrap if we don't have an interface prototype object?
assert descriptor.interface.hasInterfacePrototypeObject()
args = [Argument('*JSContext', 'aCx'), Argument('*JSObject', 'aScope'),
Argument(descriptor.pointerType + descriptor.nativeType, 'aObject'), Argument('*mut bool', 'aTriedToWrap')]
Argument('@mut ' + descriptor.name, 'aObject'), Argument('*mut bool', 'aTriedToWrap')]
CGAbstractMethod.__init__(self, descriptor, 'Wrap', '*JSObject', args, inline=True, pub=True)
def definition_body(self):
@ -2896,7 +2902,9 @@ class CGCallGenerator(CGThing):
if a.type.isObject() and not a.type.nullable() and not a.optional:
name = "(JSObject&)" + name
#XXXjdm Perhaps we should pass all nontrivial types by borrowed pointer
if a.type.isDictionary():
# Aoid passing Option<DOMString> by reference. If only one of optional or
# defaultValue are truthy we pass an Option, otherwise it's a concrete DOMString.
if a.type.isDictionary() or (a.type.isString() and not (bool(a.defaultValue) ^ a.optional)):
name = "&" + name
args.append(CGGeneric(name))
@ -2918,7 +2926,7 @@ class CGCallGenerator(CGThing):
call = CGGeneric(nativeMethodName)
if static:
call = CGWrapper(call, pre="%s::" % descriptorProvider.nativeType)
call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name)
else:
call = CGWrapper(call, pre="(*%s)." % object)
call = CGList([call, CGWrapper(args, pre="(", post=");")])
@ -3168,7 +3176,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
" return false as JSBool;\n"
"}\n"
"\n"
"let this: *rust_box<%s>;" % self.descriptor.nativeType))
"let this: *rust_box<%s>;" % self.descriptor.name))
def generate_code(self):
assert(False) # Override me
@ -3208,7 +3216,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
self.method = method
name = method.identifier.name
args = [Argument('*JSContext', 'cx'), Argument('JSHandleObject', 'obj'),
Argument('*mut %s' % descriptor.nativeType, 'this'),
Argument('*mut %s' % descriptor.name, 'this'),
Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
@ -3253,7 +3261,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
name = 'get_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'),
Argument('*%s' % descriptor.nativeType, 'this'),
Argument('*%s' % descriptor.name, 'this'),
Argument('*mut JSVal', 'vp') ]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -3312,7 +3320,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
name = 'set_' + attr.identifier.name
args = [ Argument('*JSContext', 'cx'),
Argument('JSHandleObject', 'obj'),
Argument('*mut %s' % descriptor.nativeType, 'this'),
Argument('*mut %s' % descriptor.name, 'this'),
Argument('*mut JSVal', 'argv')]
CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
@ -3717,8 +3725,8 @@ def finalizeHook(descriptor, hookName, context):
else:
assert descriptor.nativeIsISupports
release = """let val = JS_GetReservedSlot(obj, 0);
let _: %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
""" % (descriptor.pointerType + descriptor.nativeType)
let _: @mut %s = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
""" % descriptor.name
#return clearWrapper + release
return release
@ -4192,7 +4200,7 @@ class CGDictionary(CGThing):
if dealWithOptional:
replacements["declName"] = "(" + replacements["declName"] + ".Value())"
if member.defaultValue:
replacements["haveValue"] = "found"
replacements["haveValue"] = "found as bool"
# NOTE: jsids are per-runtime, so don't use them in workers
if True or self.workers: #XXXjdm hack until 'static mut' exists for global jsids
@ -4349,7 +4357,8 @@ class CGBindingRoot(CGThing):
'js::jsfriendapi::bindgen::*',
'js::glue::*',
'dom::node::AbstractNode', #XXXjdm
'dom::document::Document', #XXXjdm
'dom::document::{Document, AbstractDocument}', #XXXjdm
'dom::htmldocument::HTMLDocument', #XXXjdm
'dom::bindings::utils::*',
'dom::bindings::conversions::*',
'dom::blob::*', #XXXjdm

View file

@ -0,0 +1,76 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
interface Selection;
interface HTMLElement;
interface HTMLHeadElement;
[OverrideBuiltins]
interface HTMLDocument : Document {
[Throws]
attribute DOMString? domain;
[Throws]
attribute DOMString cookie;
// DOM tree accessors
[Throws]
getter object (DOMString name);
/*[SetterThrows]
attribute HTMLElement? body;*/
readonly attribute HTMLHeadElement? head;
readonly attribute HTMLCollection images;
readonly attribute HTMLCollection embeds;
readonly attribute HTMLCollection plugins;
readonly attribute HTMLCollection links;
readonly attribute HTMLCollection forms;
readonly attribute HTMLCollection scripts;
/*NodeList getElementsByName(DOMString elementName);
NodeList getItems(optional DOMString typeNames = ""); // microdata*/
// dynamic markup insertion
/*[Throws]
Document open(optional DOMString type = "text/html", optional DOMString replace = "");
[Throws]
WindowProxy open(DOMString url, DOMString name, DOMString features, optional boolean replace = false);*/
[Throws]
void close();
/*[Throws]
void write(DOMString... text);
[Throws]
void writeln(DOMString... text);*/
[SetterThrows]
attribute DOMString designMode;
[Throws]
boolean execCommand(DOMString commandId, optional boolean showUI = false,
optional DOMString value = "");
[Throws]
boolean queryCommandEnabled(DOMString commandId);
[Throws]
boolean queryCommandIndeterm(DOMString commandId);
[Throws]
boolean queryCommandState(DOMString commandId);
boolean queryCommandSupported(DOMString commandId);
[Throws]
DOMString queryCommandValue(DOMString commandId);
[TreatNullAs=EmptyString] attribute DOMString fgColor;
[TreatNullAs=EmptyString] attribute DOMString linkColor;
[TreatNullAs=EmptyString] attribute DOMString vlinkColor;
[TreatNullAs=EmptyString] attribute DOMString alinkColor;
[TreatNullAs=EmptyString] attribute DOMString bgColor;
readonly attribute HTMLCollection anchors;
readonly attribute HTMLCollection applets;
void clear();
[Throws]
readonly attribute object all;
// https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections
/*[Throws]
Selection getSelection();*/
};

View file

@ -91,6 +91,7 @@ extern fn InterfaceObjectToString(cx: *JSContext, _argc: uint, vp: *mut JSVal) -
}
}
#[deriving(Clone)]
pub enum DOMString {
str(~str),
null_string
@ -615,7 +616,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) ->
}
pub fn initialize_global(global: *JSObject) {
let protoArray = @mut ([0 as *JSObject, ..23]); //XXXjdm PrototyepList::id::_ID_Count
let protoArray = @mut ([0 as *JSObject, ..24]); //XXXjdm PrototyepList::id::_ID_Count
unsafe {
//XXXjdm we should be storing the box pointer instead of the inner
let box = squirrel_away(protoArray);

View file

@ -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();
unsafe {
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);
}
None => ()
Document {
root: root,
wrapper: WrapperCache::new(),
window: window,
doctype: doctype
}
doc
}
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)
}

View file

@ -3,9 +3,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::DOMParserBinding;
use dom::bindings::codegen::DOMParserBinding::SupportedTypeValues::{Text_html, Text_xml};
use dom::bindings::utils::{DOMString, ErrorResult, WrapperCache, CacheableWrapper};
use dom::document::Document;
use dom::document::{AbstractDocument, Document, XML};
use dom::element::{Element, HTMLHtmlElement, HTMLHtmlElementTypeId};
use dom::htmldocument::HTMLDocument;
use dom::node::Node;
use dom::window::Window;
@ -34,17 +36,29 @@ impl DOMParser {
}
pub fn ParseFromString(&self,
_s: DOMString,
_type: DOMParserBinding::SupportedType,
_s: &DOMString,
ty: DOMParserBinding::SupportedType,
_rv: &mut ErrorResult)
-> @mut Document {
-> AbstractDocument {
unsafe {
let root = ~HTMLHtmlElement {
parent: Element::new(HTMLHtmlElementTypeId, ~"html")
};
let root = Node::as_abstract_node((*self.owner.page).js_info.get_ref().js_compartment.cx.ptr, root);
Document(root, None)
let cx = (*self.owner.page).js_info.get_ref().js_compartment.cx.ptr;
match ty {
Text_html => {
HTMLDocument::new(root, None)
}
Text_xml => {
AbstractDocument::as_abstract(cx, @mut Document::new(root, None, XML))
}
_ => {
fail!("unsupported document type")
}
}
}
}
}

View file

@ -161,7 +161,7 @@ impl<'self> Element {
}
match self.parent.owner_doc {
Some(owner) => owner.content_changed(),
Some(owner) => do owner.with_base |owner| { owner.content_changed() },
None => {}
}
}
@ -169,7 +169,7 @@ impl<'self> Element {
pub fn getClientRects(&self) -> Option<@mut ClientRectList> {
let (rects, cx, scope) = match self.parent.owner_doc {
Some(doc) => {
match doc.window {
match doc.with_base(|doc| doc.window) {
Some(win) => {
let node = self.parent.abstract.get();
assert!(node.is_element());
@ -217,7 +217,7 @@ impl<'self> Element {
pub fn getBoundingClientRect(&self) -> Option<@mut ClientRect> {
match self.parent.owner_doc {
Some(doc) => {
match doc.window {
match doc.with_base(|doc| doc.window) {
Some(win) => {
let page = win.page;
let node = self.parent.abstract.get();

View file

@ -17,7 +17,7 @@ use script_task::page_from_context;
use std::cast;
pub enum Event {
pub enum Event_ {
ResizeEvent(uint, uint),
ReflowEvent,
ClickEvent(uint, Point2D<f32>),
@ -25,7 +25,7 @@ pub enum Event {
MouseUpEvent(uint, Point2D<f32>),
}
pub struct Event_ {
pub struct Event {
wrapper: WrapperCache,
type_: DOMString,
default_prevented: bool,
@ -34,11 +34,11 @@ pub struct Event_ {
trusted: bool,
}
impl Event_ {
pub fn new(type_: DOMString) -> Event_ {
Event_ {
impl Event {
pub fn new(type_: &DOMString) -> Event {
Event {
wrapper: WrapperCache::new(),
type_: type_,
type_: (*type_).clone(),
default_prevented: false,
cancelable: true,
bubbles: true,
@ -93,11 +93,11 @@ impl Event_ {
}
pub fn InitEvent(&mut self,
type_: DOMString,
type_: &DOMString,
bubbles: bool,
cancelable: bool,
_rv: &mut ErrorResult) {
self.type_ = type_;
self.type_ = (*type_).clone();
self.cancelable = cancelable;
self.bubbles = bubbles;
}
@ -107,14 +107,14 @@ impl Event_ {
}
pub fn Constructor(_global: @mut Window,
type_: DOMString,
type_: &DOMString,
_init: &EventBinding::EventInit,
_rv: &mut ErrorResult) -> @mut Event_ {
@mut Event_::new(type_)
_rv: &mut ErrorResult) -> @mut Event {
@mut Event::new(type_)
}
}
impl CacheableWrapper for Event_ {
impl CacheableWrapper for Event {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}
@ -125,7 +125,7 @@ impl CacheableWrapper for Event_ {
}
}
impl BindingObject for Event_ {
impl BindingObject for Event {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
let page = page_from_context(cx);
unsafe {
@ -134,7 +134,7 @@ impl BindingObject for Event_ {
}
}
impl DerivedWrapper for Event_ {
impl DerivedWrapper for Event {
fn wrap(&mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
fail!(~"nyi")
}

View file

@ -36,7 +36,7 @@ impl FormData {
self.wrap_object_shared(cx, scope);
}
pub fn Append(&mut self, name: DOMString, value: @mut Blob, filename: Option<DOMString>) {
pub fn Append(&mut self, name: &DOMString, value: @mut Blob, filename: Option<DOMString>) {
let blob = BlobData {
blob: value,
name: filename.get_or_default(str(~"default"))
@ -44,8 +44,8 @@ impl FormData {
self.data.insert(name.to_str(), blob);
}
pub fn Append_(&mut self, name: DOMString, value: DOMString) {
self.data.insert(name.to_str(), StringData(value));
pub fn Append_(&mut self, name: &DOMString, value: &DOMString) {
self.data.insert(name.to_str(), StringData((*value).clone()));
}
}

View file

@ -44,7 +44,7 @@ impl HTMLCollection {
}
}
pub fn NamedItem(&self, _cx: *JSContext, _name: DOMString, rv: &mut ErrorResult) -> *JSObject {
pub fn NamedItem(&self, _cx: *JSContext, _name: &DOMString, rv: &mut ErrorResult) -> *JSObject {
*rv = Ok(());
ptr::null()
}

View file

@ -0,0 +1,216 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::document::{AbstractDocument, Document, WrappableDocument, HTML};
use dom::bindings::codegen::HTMLDocumentBinding;
use dom::bindings::utils::{DOMString, ErrorResult, null_string};
use dom::bindings::utils::{CacheableWrapper, BindingObject, WrapperCache};
use dom::htmlcollection::HTMLCollection;
use dom::node::{AbstractNode, ScriptView};
use dom::window::Window;
use js::JSPROP_ENUMERATE;
use js::glue::*;
use js::jsapi::{JSObject, JSContext};
use std::libc;
use std::ptr;
pub struct HTMLDocument {
parent: Document
}
impl HTMLDocument {
pub fn new(root: AbstractNode<ScriptView>, window: Option<@mut Window>) -> AbstractDocument {
let doc = @mut HTMLDocument {
parent: Document::new(root, window, HTML)
};
let cache = ptr::to_mut_unsafe_ptr(doc.get_wrappercache());
let compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
let abstract = AbstractDocument::as_abstract(compartment.cx.ptr, doc);
match window {
Some(win) => {
unsafe {
//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((*cache).wrapper),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
}
}
None => ()
}
abstract
}
fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
let win = self.parent.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)
}
}
impl WrappableDocument for HTMLDocument {
pub fn init_wrapper(@mut self, cx: *JSContext) {
self.wrap_object_shared(cx, ptr::null()); //XXXjdm a proper scope would be nice
}
}
impl HTMLDocument {
pub fn GetDomain(&self, _rv: &mut ErrorResult) -> DOMString {
null_string
}
pub fn SetDomain(&self, _domain: &DOMString, _rv: &mut ErrorResult) {
}
pub fn GetCookie(&self, _rv: &mut ErrorResult) -> DOMString {
null_string
}
pub fn SetCookie(&self, _cookie: &DOMString, _rv: &mut ErrorResult) {
}
pub fn GetHead(&self) -> Option<AbstractNode<ScriptView>> {
None
}
pub fn Images(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Embeds(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Plugins(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Links(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Forms(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Scripts(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Close(&self, _rv: &mut ErrorResult) {
}
pub fn DesignMode(&self) -> DOMString {
null_string
}
pub fn SetDesignMode(&self, _mode: &DOMString, _rv: &mut ErrorResult) {
}
pub fn ExecCommand(&self, _command_id: &DOMString, _show_ui: bool, _value: &DOMString, _rv: &mut ErrorResult) -> bool {
false
}
pub fn QueryCommandEnabled(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
false
}
pub fn QueryCommandIndeterm(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
false
}
pub fn QueryCommandState(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> bool {
false
}
pub fn QueryCommandSupported(&self, _command_id: &DOMString) -> bool {
false
}
pub fn QueryCommandValue(&self, _command_id: &DOMString, _rv: &mut ErrorResult) -> DOMString {
null_string
}
pub fn FgColor(&self) -> DOMString {
null_string
}
pub fn SetFgColor(&self, _color: &DOMString) {
}
pub fn LinkColor(&self) -> DOMString {
null_string
}
pub fn SetLinkColor(&self, _color: &DOMString) {
}
pub fn VlinkColor(&self) -> DOMString {
null_string
}
pub fn SetVlinkColor(&self, _color: &DOMString) {
}
pub fn AlinkColor(&self) -> DOMString {
null_string
}
pub fn SetAlinkColor(&self, _color: &DOMString) {
}
pub fn BgColor(&self) -> DOMString {
null_string
}
pub fn SetBgColor(&self, _color: &DOMString) {
}
pub fn Anchors(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Applets(&self) -> @mut HTMLCollection {
let (scope, cx) = self.get_scope_and_cx();
HTMLCollection::new(~[], cx, scope)
}
pub fn Clear(&self) {
}
pub fn GetAll(&self, _cx: *JSContext, _rv: &mut ErrorResult) -> *libc::c_void {
ptr::null()
}
}
impl CacheableWrapper for HTMLDocument {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
self.parent.get_wrappercache()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
HTMLDocumentBinding::Wrap(cx, scope, self, &mut unused)
}
}
impl BindingObject for HTMLDocument {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
self.parent.GetParentObject(cx)
}
}

View file

@ -28,7 +28,7 @@ pub struct MouseEvent {
}
impl MouseEvent {
pub fn new(type_: DOMString, can_bubble: bool, cancelable: bool,
pub fn new(type_: &DOMString, can_bubble: bool, cancelable: bool,
view: Option<@mut WindowProxy>, detail: i32, screen_x: i32,
screen_y: i32, client_x: i32, client_y: i32, ctrl_key: bool,
shift_key: bool, alt_key: bool, meta_key: bool, button: u16,
@ -53,7 +53,7 @@ impl MouseEvent {
}
pub fn Constructor(_owner: @mut Window,
type_: DOMString,
type_: &DOMString,
init: &MouseEventBinding::MouseEventInit,
_rv: &mut ErrorResult) -> @mut MouseEvent {
@mut MouseEvent::new(type_, init.bubbles, init.cancelable, init.view, init.detail,
@ -107,13 +107,13 @@ impl MouseEvent {
self.related_target
}
pub fn GetModifierState(&self, _keyArg: DOMString) -> bool {
pub fn GetModifierState(&self, _keyArg: &DOMString) -> bool {
//TODO
false
}
pub fn InitMouseEvent(&mut self,
typeArg: DOMString,
typeArg: &DOMString,
canBubbleArg: bool,
cancelableArg: bool,
viewArg: Option<@mut WindowProxy>,

View file

@ -8,7 +8,7 @@ use dom::bindings::node;
use dom::bindings::utils::WrapperCache;
use dom::bindings;
use dom::characterdata::CharacterData;
use dom::document::Document;
use dom::document::AbstractDocument;
use dom::element::{Element, ElementTypeId, HTMLImageElement, HTMLImageElementTypeId, HTMLIframeElementTypeId, HTMLIframeElement};
use dom::element::{HTMLStyleElementTypeId};
@ -80,7 +80,7 @@ pub struct Node<View> {
prev_sibling: Option<AbstractNode<View>>,
/// The document that this node belongs to.
owner_doc: Option<@mut Document>,
owner_doc: Option<AbstractDocument>,
/// Layout information. Only the layout task may touch this data.
priv layout_data: Option<@mut ()>
@ -433,7 +433,7 @@ impl Node<ScriptView> {
node
}
pub fn add_to_doc(&mut self, doc: @mut Document) {
pub fn add_to_doc(&mut self, doc: AbstractDocument) {
self.owner_doc = Some(doc);
let mut node = self.first_child;
while node.is_some() {

View file

@ -6,7 +6,7 @@ use dom::bindings::codegen::UIEventBinding;
use dom::bindings::utils::{ErrorResult, DOMString};
use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject, DerivedWrapper};
use dom::node::{AbstractNode, ScriptView};
use dom::event::Event_;
use dom::event::Event;
use dom::window::Window;
use dom::windowproxy::WindowProxy;
@ -14,7 +14,7 @@ use js::glue::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSObject, JSContext, JSVal};
pub struct UIEvent {
parent: Event_,
parent: Event,
can_bubble: bool,
cancelable: bool,
view: Option<@mut WindowProxy>,
@ -22,10 +22,10 @@ pub struct UIEvent {
}
impl UIEvent {
pub fn new(type_: DOMString, can_bubble: bool, cancelable: bool,
pub fn new(type_: &DOMString, can_bubble: bool, cancelable: bool,
view: Option<@mut WindowProxy>, detail: i32) -> UIEvent {
UIEvent {
parent: Event_::new(type_),
parent: Event::new(type_),
can_bubble: can_bubble,
cancelable: cancelable,
view: view,
@ -38,7 +38,7 @@ impl UIEvent {
}
pub fn Constructor(_owner: @mut Window,
type_: DOMString,
type_: &DOMString,
init: &UIEventBinding::UIEventInit,
_rv: &mut ErrorResult) -> @mut UIEvent {
@mut UIEvent::new(type_, init.parent.bubbles, init.parent.cancelable,
@ -54,7 +54,7 @@ impl UIEvent {
}
pub fn InitUIEvent(&mut self,
type_: DOMString,
type_: &DOMString,
can_bubble: bool,
cancelable: bool,
view: Option<@mut WindowProxy>,

View file

@ -42,6 +42,7 @@ pub mod dom {
pub mod EventTargetBinding;
pub mod FormDataBinding;
pub mod HTMLCollectionBinding;
pub mod HTMLDocumentBinding;
pub mod MouseEventBinding;
pub mod PrototypeList;
pub mod RegisterBindings;
@ -60,6 +61,7 @@ pub mod dom {
pub mod eventtarget;
pub mod formdata;
pub mod htmlcollection;
pub mod htmldocument;
pub mod mouseevent;
pub mod node;
pub mod uievent;

View file

@ -8,10 +8,11 @@
use servo_msg::compositor_msg::{ScriptListener, Loading, PerformingLayout};
use servo_msg::compositor_msg::FinishedLoading;
use dom::bindings::utils::GlobalStaticData;
use dom::document::Document;
use dom::document::AbstractDocument;
use dom::element::Element;
use dom::event::{Event, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseUpEvent};
use dom::node::define_bindings;
use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseUpEvent};
use dom::htmldocument::HTMLDocument;
use dom::node::{define_bindings};
use dom::window::Window;
use layout_interface::{AddStylesheetMsg, DocumentDamage};
use layout_interface::{DocumentDamageLevel, HitTestQuery, HitTestResponse, LayoutQuery};
@ -63,7 +64,7 @@ pub enum ScriptMsg {
/// Instructs the script task to send a navigate message to the constellation.
NavigateMsg(NavigationDirection),
/// Sends a DOM event.
SendEventMsg(PipelineId, Event),
SendEventMsg(PipelineId, Event_),
/// Fires a JavaScript timeout.
FireTimerMsg(PipelineId, ~TimerData),
/// Notifies script that reflow is finished.
@ -194,14 +195,14 @@ impl Page {
None => {}
Some(ref mut damage) => {
// FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor.
damage.root = self.frame.get_ref().document.root;
damage.root = do self.frame.get_ref().document.with_base |doc| { doc.root };
damage.level.add(level);
return
}
}
self.damage = Some(DocumentDamage {
root: self.frame.get_ref().document.root,
root: do self.frame.get_ref().document.with_base |doc| { doc.root },
level: level,
})
}
@ -260,7 +261,7 @@ impl Page {
Some(ref frame) => {
// Send new document and relevant styles to layout.
let reflow = ~Reflow {
document_root: frame.document.root,
document_root: do frame.document.with_base |doc| { doc.root },
url: copy self.url.get_ref().first(),
goal: goal,
window_size: self.window_size.get(),
@ -321,7 +322,7 @@ impl Page {
/// Information for one frame in the browsing context.
pub struct Frame {
document: @mut Document,
document: AbstractDocument,
window: @mut Window,
}
@ -553,7 +554,9 @@ impl ScriptTask {
fn handle_exit_msg(&mut self) {
for self.page_tree.iter().advance |page| {
page.join_layout();
page.frame.get().document.teardown();
do page.frame.get().document.with_mut_base |doc| {
doc.teardown();
}
page.layout_chan.send(layout_interface::ExitMsg);
}
}
@ -602,7 +605,7 @@ impl ScriptTask {
// Create the window and document objects.
let window = Window::new(&mut *page, self.chan.clone(), self.compositor);
let document = Document(root, Some(window));
let document = HTMLDocument::new(root, Some(window));
// Tie the root into the document.
do root.with_mut_base |base| {
@ -689,7 +692,7 @@ impl ScriptTask {
/// This is the main entry point for receiving and dispatching DOM events.
///
/// TODO: Actually perform DOM event dispatch.
fn handle_event(&mut self, pipeline_id: PipelineId, event: Event) {
fn handle_event(&mut self, pipeline_id: PipelineId, event: Event_) {
let page = self.page_tree.find(pipeline_id).expect("ScriptTask: received an event
message for a layout channel that is not associated with this script task. This
is a bug.").page;
@ -721,7 +724,9 @@ impl ScriptTask {
ClickEvent(_button, point) => {
debug!("ClickEvent: clicked at %?", point);
let root = page.frame.expect("root frame is None").document.root;
let root = do page.frame.expect("root frame is None").document.with_base |doc| {
doc.root
};
let (port, chan) = comm::stream();
match page.query_layout(HitTestQuery(root, point, chan), port) {
Ok(node) => match node {

View file

@ -1,7 +1,14 @@
//window.alert(ClientRect);
//window.alert(ClientRectList);
window.alert("==1==");
let elem = document.getElementsByTagName('div')[0];
window.alert(document.documentElement);
window.alert(document.documentElement.firstChild);
window.alert(document.documentElement.nextSibling);
window.alert(document instanceof HTMLDocument);
window.alert(document instanceof Document);
var elems = document.getElementsByTagName('div');
window.alert(elems.length);
let elem = elems[0];
window.alert(elem.nodeType);
window.alert(elem);
window.alert("==1.5==");