Generate bindings for Window.

This commit is contained in:
Josh Matthews 2013-07-30 14:51:16 -04:00
parent 5546f2105b
commit a2bdab7989
24 changed files with 227 additions and 278 deletions

View file

@ -401,6 +401,9 @@ DOMInterfaces = {
'implicitJSContext': [ 'constructor' ] 'implicitJSContext': [ 'constructor' ]
}], }],
'Window': {
},
'WindowProxy': { 'WindowProxy': {
}, },
@ -567,5 +570,4 @@ addExternalIface('WebGLShaderPrecisionFormat',
headerFile='WebGLContext.h') headerFile='WebGLContext.h')
addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture', addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture',
headerFile='WebGLContext.h') headerFile='WebGLContext.h')
addExternalIface('Window')
addExternalIface('XULElement') addExternalIface('XULElement')

View file

@ -1158,8 +1158,8 @@ for (uint32_t i = 0; i < length; ++i) {
"rooting issues") "rooting issues")
templateBody = "${declName} = ${val};" templateBody = "${declName} = ${val};"
templateBody = handleDefaultNull(templateBody, templateBody = handleDefaultNull(templateBody,
"${declName} = JS::NullValue()") "${declName} = JSVAL_NULL")
return (templateBody, CGGeneric("JS::Value"), None, isOptional, None) return (templateBody, CGGeneric("JSVal"), None, isOptional, "JSVAL_NULL")
if type.isObject(): if type.isObject():
assert not isEnforceRange and not isClamp assert not isEnforceRange and not isClamp
@ -1263,7 +1263,7 @@ for (uint32_t i = 0; i < length; ++i) {
" %s = %s;\n" " %s = %s;\n"
"}" % (dataLoc, defaultStr))).define() "}" % (dataLoc, defaultStr))).define()
return (template, declType, None, isOptional, None) return (template, declType, None, isOptional, "0 as %s" % typeName)
def instantiateJSToNativeConversionTemplate(templateTuple, replacements, def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
argcAndIndex=None): argcAndIndex=None):
@ -1308,11 +1308,7 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
originalDeclName = replacements["declName"] originalDeclName = replacements["declName"]
if declType is not None: if declType is not None:
if dealWithOptional: if dealWithOptional:
replacements["declName"] = ( mutableDeclType = CGWrapper(declType, pre="Option< ", post=" >")
"const_cast< %s & >(%s.Value())" %
(declType.define(), originalDeclName))
mutableDeclType = CGWrapper(declType, pre="Optional< ", post=" >")
declType = CGWrapper(mutableDeclType, pre="const ")
newDecl = [CGGeneric("let mut "), newDecl = [CGGeneric("let mut "),
CGGeneric(originalDeclName), CGGeneric(originalDeclName),
CGGeneric(": "), CGGeneric(": "),
@ -1327,17 +1323,6 @@ def instantiateJSToNativeConversionTemplate(templateTuple, replacements,
) )
if argcAndIndex is not None: if argcAndIndex is not None:
if dealWithOptional:
declConstruct = CGIndenter(
CGGeneric("const_cast< %s &>(%s).Construct();" %
(mutableDeclType.define(), originalDeclName)))
if holderType is not None:
holderConstruct = CGIndenter(
CGGeneric("const_cast< %s &>(%s).Construct();" %
(mutableHolderType.define(), originalHolderName)))
else:
holderConstruct = None
else:
declConstruct = None declConstruct = None
holderConstruct = None holderConstruct = None
@ -2155,7 +2140,7 @@ class CGImports(CGWrapper):
# TODO imports to cover descriptors, etc. # TODO imports to cover descriptors, etc.
def _useString(imports): def _useString(imports):
return '#[allow(non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut)];' + ''.join(['use %s;\n' % i for i in imports]) + '\n' return '#[allow(non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut,dead_assignment)];\n' + ''.join(['use %s;\n' % i for i in imports]) + '\n'
CGWrapper.__init__(self, child, CGWrapper.__init__(self, child,
declarePre=_useString(sorted(declareImports))) declarePre=_useString(sorted(declareImports)))
@ -4373,6 +4358,7 @@ class CGBindingRoot(CGThing):
'dom::mouseevent::*', #XXXjdm 'dom::mouseevent::*', #XXXjdm
'dom::uievent::*', #XXXjdm 'dom::uievent::*', #XXXjdm
'dom::windowproxy::*', #XXXjdm 'dom::windowproxy::*', #XXXjdm
'dom::window::Window', #XXXjdm
'dom::bindings::codegen::*', #XXXjdm 'dom::bindings::codegen::*', #XXXjdm
'script_task::{JSPageInfo, page_from_context}', 'script_task::{JSPageInfo, page_from_context}',
'dom::bindings::utils::EnumEntry', 'dom::bindings::utils::EnumEntry',

View file

@ -0,0 +1,71 @@
/* -*- 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/.
*
* The origin of this IDL file is:
* http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-window-object
*/
[NamedPropertiesObject]
/*sealed*/ interface Window /*: EventTarget*/ {
// the current browsing context
/*[Unforgeable] readonly attribute WindowProxy window;
[Replaceable] readonly attribute WindowProxy self;*/
[Unforgeable] readonly attribute Document document;
attribute DOMString name;
/*[PutForwards=href, Unforgeable] readonly attribute Location location;
readonly attribute History history;
[Replaceable] readonly attribute BarProp locationbar;
[Replaceable] readonly attribute BarProp menubar;
[Replaceable] readonly attribute BarProp personalbar;
[Replaceable] readonly attribute BarProp scrollbars;
[Replaceable] readonly attribute BarProp statusbar;
[Replaceable] readonly attribute BarProp toolbar;*/
attribute DOMString status;
void close();
readonly attribute boolean closed;
void stop();
void focus();
void blur();
// other browsing contexts
/*[Replaceable] readonly attribute WindowProxy frames;
[Replaceable] readonly attribute unsigned long length;
[Unforgeable] readonly attribute WindowProxy top;
attribute WindowProxy? opener;
readonly attribute WindowProxy parent;*/
readonly attribute Element? frameElement;
/*WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", optional DOMString features = "", optional boolean replace = false);
getter WindowProxy (unsigned long index);*/
getter object (DOMString name);
// the user agent
/*readonly attribute Navigator navigator;
readonly attribute External external;
readonly attribute ApplicationCache applicationCache;*/
// user prompts
void alert(optional DOMString message = "");
boolean confirm(optional DOMString message = "");
DOMString? prompt(optional DOMString message = "", optional DOMString default = "");
void print();
any showModalDialog(DOMString url, optional any argument);
};
/*Window implements GlobalEventHandlers;
Window implements WindowEventHandlers;*/
[NoInterfaceObject]
interface WindowTimers {
//long setTimeout(Function handler, optional long timeout, any... arguments);
//XXXjdm No support for Function or variadic arguments yet
long setTimeout(any handler, optional long timeout/*, any... arguments*/);
/*long setTimeout(DOMString handler, optional long timeout, any... arguments);
void clearTimeout(long handle);
long setInterval(Function handler, optional long timeout, any... arguments);
long setInterval(DOMString handler, optional long timeout, any... arguments);
void clearInterval(long handle);*/
};
Window implements WindowTimers;

View file

@ -24,8 +24,8 @@ impl CacheableWrapper for DOMParser {
} }
impl BindingObject for DOMParser { impl BindingObject for DOMParser {
fn GetParentObject(&self, _cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
return self.owner as @mut CacheableWrapper; Some(self.owner as @mut CacheableWrapper)
} }
} }

View file

@ -20,7 +20,7 @@ use js::glue::*;
use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL}; use js::glue::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily}; use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB}; use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB, RESOLVE_STUB};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction}; use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewObject, JS_NewFunction, JS_GetGlobalObject};
use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo}; use js::jsapi::{JS_DefineProperties, JS_WrapValue, JS_ForwardGetPropertyTo};
use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength}; use js::jsapi::{JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype}; use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype};
@ -616,7 +616,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) ->
} }
pub fn initialize_global(global: *JSObject) { pub fn initialize_global(global: *JSObject) {
let protoArray = @mut ([0 as *JSObject, ..24]); //XXXjdm PrototyepList::id::_ID_Count let protoArray = @mut ([0 as *JSObject, ..25]); //XXXjdm PrototyepList::id::_ID_Count
unsafe { unsafe {
//XXXjdm we should be storing the box pointer instead of the inner //XXXjdm we should be storing the box pointer instead of the inner
let box = squirrel_away(protoArray); let box = squirrel_away(protoArray);
@ -679,7 +679,9 @@ pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
} }
} }
pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableWrapper) -> *JSObject { pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: Option<@mut CacheableWrapper>) -> *JSObject {
match p {
Some(ref mut p) => {
let cache = p.get_wrappercache(); let cache = p.get_wrappercache();
let wrapper = cache.get_wrapper(); let wrapper = cache.get_wrapper();
if wrapper.is_not_null() { if wrapper.is_not_null() {
@ -688,10 +690,13 @@ pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableW
let wrapper = p.wrap_object_shared(cx, scope); let wrapper = p.wrap_object_shared(cx, scope);
cache.set_wrapper(wrapper); cache.set_wrapper(wrapper);
wrapper wrapper
}
None => unsafe { JS_GetGlobalObject(cx) }
}
} }
pub trait BindingObject { pub trait BindingObject {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper; fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper>;
} }
pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool, pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool,

View file

@ -1,168 +0,0 @@
/* 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/. */
// DOM bindings for the Window object.
use dom::bindings::utils::{rust_box, squirrel_away, CacheableWrapper};
use dom::bindings::utils::{WrapperCache};
use dom::window::Window;
use super::utils;
use std::cast;
use std::libc;
use std::libc::c_uint;
use std::ptr::null;
use std::ptr;
use std::result;
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub};
use js::global::jsval_to_rust_str;
use js::glue::*;
use js::glue::RUST_JSVAL_TO_INT;
use js::jsapi::{JS_DefineFunctions, JS_GC, JS_GetRuntime};
use js::jsapi::{JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JS_ValueToString};
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, JSFreeOp, JSFunctionSpec};
use js::jsapi::{JSNativeWrapper};
use js::rust::Compartment;
use js::{JS_ARGV, JSPROP_ENUMERATE, JSVAL_NULL};
use js::{JS_THIS_OBJECT, JS_SET_RVAL};
extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let argv = JS_ARGV(cx, vp);
assert!(argc == 1);
// Abstract this pattern and use it in debug, too?
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
if jsstr.is_null() {
return 0;
}
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.alert(jsval_to_rust_str(cx, jsstr));
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return 1;
}
}
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
let argv = JS_ARGV(cx, vp);
assert!(argc >= 2);
//TODO: don't crash when passed a non-integer value for the timeout
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.setTimeout(
RUST_JSVAL_TO_INT(*ptr::offset(argv, 1)) as int,
argc, argv);
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return 1;
}
}
extern fn close(cx: *JSContext, _argc: c_uint, vp: *JSVal) -> JSBool {
unsafe {
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.close();
JS_SET_RVAL(cx, vp, JSVAL_NULL);
return 1;
}
}
extern fn gc(cx: *JSContext, _argc: c_uint, _vp: *JSVal) -> JSBool {
unsafe {
let runtime = JS_GetRuntime(cx);
JS_GC(runtime);
return 1;
}
}
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
let val = JS_GetReservedSlot(obj, 0);
cast::transmute(RUST_JSVAL_TO_PRIVATE(val))
}
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
debug!("finalize!");
unsafe {
let val = JS_GetReservedSlot(obj, 0);
let _: @Window = cast::transmute(RUST_JSVAL_TO_PRIVATE(val));
}
}
pub fn init(compartment: @mut Compartment) {
let proto = utils::define_empty_prototype(~"Window", None, compartment);
compartment.register_class(utils::instance_jsclass(~"WindowInstance", finalize, null()));
/* Define methods on a window */
let methods = [
JSFunctionSpec {
name: compartment.add_name(~"alert"),
call: JSNativeWrapper { op: alert, info: null() },
nargs: 1,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"setTimeout"),
call: JSNativeWrapper { op: setTimeout, info: null() },
nargs: 2,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"close"),
call: JSNativeWrapper { op: close, info: null() },
nargs: 0,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: compartment.add_name(~"_trigger_gc"),
call: JSNativeWrapper { op: gc, info: null() },
nargs: 0,
flags: 0,
selfHostedName: null()
},
JSFunctionSpec {
name: null(),
call: JSNativeWrapper { op: null(), info: null() },
nargs: 0,
flags: 0,
selfHostedName: null()
}
];
unsafe {
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
}
}
pub fn create(compartment: @mut Compartment, win: @mut Window) {
let obj = result::unwrap(
compartment.new_object_with_proto(~"WindowInstance",
~"Window", null()));
win.get_wrappercache().set_wrapper(obj.ptr);
unsafe {
let raw_ptr: *libc::c_void = cast::transmute(squirrel_away(win));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
//TODO: All properties/methods on Window need to be available on the global
// object as well. We probably want a special JSClass with a resolve hook.
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE);
}
}
impl CacheableWrapper for Window {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"should this be called?");
}
}

View file

@ -34,10 +34,10 @@ impl CacheableWrapper for Blob {
} }
impl BindingObject for Blob { impl BindingObject for Blob {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -76,10 +76,10 @@ impl CacheableWrapper for ClientRect {
} }
impl BindingObject for ClientRect { impl BindingObject for ClientRect {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -62,10 +62,10 @@ impl CacheableWrapper for ClientRectList {
} }
impl BindingObject for ClientRectList { impl BindingObject for ClientRectList {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -148,7 +148,7 @@ impl CacheableWrapper for AbstractDocument {
} }
impl BindingObject for AbstractDocument { impl BindingObject for AbstractDocument {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
do self.with_mut_base |doc| { do self.with_mut_base |doc| {
doc.GetParentObject(cx) doc.GetParentObject(cx)
} }
@ -183,10 +183,10 @@ impl CacheableWrapper for Document {
} }
impl BindingObject for Document { impl BindingObject for Document {
fn GetParentObject(&self, _cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
match self.window { match self.window {
Some(win) => win as @mut CacheableWrapper, Some(win) => Some(win as @mut CacheableWrapper),
None => fail!("whoops") None => None
} }
} }
} }

View file

@ -126,10 +126,10 @@ impl CacheableWrapper for Event {
} }
impl BindingObject for Event { impl BindingObject for Event {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -39,11 +39,11 @@ impl CacheableWrapper for EventTarget {
} }
impl BindingObject for EventTarget { impl BindingObject for EventTarget {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
// TODO(tkuehn): This only handles top-level pages. Needs to handle subframes. // TODO(tkuehn): This only handles top-level pages. Needs to handle subframes.
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -63,10 +63,10 @@ impl CacheableWrapper for FormData {
} }
impl BindingObject for FormData { impl BindingObject for FormData {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -56,11 +56,11 @@ impl HTMLCollection {
} }
impl BindingObject for HTMLCollection { impl BindingObject for HTMLCollection {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
// TODO(tkuehn): This only handles the top-level frame. Need to grab subframes. // TODO(tkuehn): This only handles the top-level frame. Need to grab subframes.
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -10,8 +10,6 @@ use dom::htmlcollection::HTMLCollection;
use dom::node::{AbstractNode, ScriptView}; use dom::node::{AbstractNode, ScriptView};
use dom::window::Window; use dom::window::Window;
use js::JSPROP_ENUMERATE;
use js::glue::*;
use js::jsapi::{JSObject, JSContext}; use js::jsapi::{JSObject, JSContext};
use std::libc; use std::libc;
@ -27,24 +25,8 @@ impl HTMLDocument {
parent: Document::new(root, window, HTML) 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 compartment = unsafe { (*window.get_ref().page).js_info.get_ref().js_compartment };
let abstract = AbstractDocument::as_abstract(compartment.cx.ptr, doc); 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) { fn get_scope_and_cx(&self) -> (*JSObject, *JSContext) {
@ -210,7 +192,7 @@ impl CacheableWrapper for HTMLDocument {
} }
impl BindingObject for HTMLDocument { impl BindingObject for HTMLDocument {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
self.parent.GetParentObject(cx) self.parent.GetParentObject(cx)
} }
} }

View file

@ -155,7 +155,7 @@ impl CacheableWrapper for MouseEvent {
} }
impl BindingObject for MouseEvent { impl BindingObject for MouseEvent {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
self.parent.GetParentObject(cx) self.parent.GetParentObject(cx)
} }
} }

View file

@ -512,7 +512,6 @@ impl VoidPtrLike for AbstractNode<LayoutView> {
} }
pub fn define_bindings(compartment: @mut Compartment) { pub fn define_bindings(compartment: @mut Compartment) {
bindings::window::init(compartment);
bindings::node::init(compartment); bindings::node::init(compartment);
bindings::element::init(compartment); bindings::element::init(compartment);
bindings::text::init(compartment); bindings::text::init(compartment);

View file

@ -129,7 +129,7 @@ impl CacheableWrapper for UIEvent {
} }
impl BindingObject for UIEvent { impl BindingObject for UIEvent {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
self.parent.GetParentObject(cx) self.parent.GetParentObject(cx)
} }
} }

View file

@ -2,16 +2,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::utils::WrapperCache; use dom::bindings::codegen::WindowBinding;
use dom::bindings::window; use dom::bindings::utils::{WrapperCache, DOMString, null_string};
use dom::bindings::utils::{CacheableWrapper, BindingObject};
use dom::document::AbstractDocument;
use dom::node::{AbstractNode, ScriptView};
use layout_interface::ReflowForScriptQuery; use layout_interface::ReflowForScriptQuery;
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan}; use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
use servo_msg::compositor_msg::ScriptListener; use servo_msg::compositor_msg::ScriptListener;
use js::glue::*;
use js::jsapi::{JSObject, JSContext};
use js::{JSVAL_NULL, JSPROP_ENUMERATE};
use std::cast;
use std::comm; use std::comm;
use std::comm::Chan; use std::comm::Chan;
use std::libc;
use std::int; use std::int;
use std::io; use std::io;
use std::ptr; use std::ptr;
@ -49,44 +56,101 @@ pub struct TimerData {
args: ~[JSVal], args: ~[JSVal],
} }
pub fn TimerData(argc: libc::c_uint, argv: *JSVal) -> TimerData {
unsafe {
let mut args = ~[];
let mut i = 2;
while i < argc as uint {
args.push(*ptr::offset(argv, i));
i += 1;
};
TimerData {
funval : *argv,
args : args,
}
}
}
// FIXME: delayed_send shouldn't require Copy
#[allow(non_implicitly_copyable_typarams)]
impl Window { impl Window {
pub fn alert(&self, s: &str) { pub fn Alert(&self, s: &DOMString) {
// Right now, just print to the console // Right now, just print to the console
io::println(fmt!("ALERT: %s", s)); io::println(fmt!("ALERT: %s", s.to_str()));
} }
pub fn close(&self) { pub fn Close(&self) {
self.timer_chan.send(TimerMessage_TriggerExit); self.timer_chan.send(TimerMessage_TriggerExit);
} }
pub fn setTimeout(&self, timeout: int, argc: libc::c_uint, argv: *JSVal) { pub fn Document(&self) -> AbstractDocument {
unsafe {
(*self.page).frame.get().document
}
}
pub fn Name(&self) -> DOMString {
null_string
}
pub fn SetName(&self, _name: &DOMString) {
}
pub fn Status(&self) -> DOMString {
null_string
}
pub fn SetStatus(&self, _status: &DOMString) {
}
pub fn Closed(&self) -> bool {
false
}
pub fn Stop(&self) {
}
pub fn Focus(&self) {
}
pub fn Blur(&self) {
}
pub fn GetFrameElement(&self) -> Option<AbstractNode<ScriptView>> {
None
}
pub fn Confirm(&self, _message: &DOMString) -> bool {
false
}
pub fn Prompt(&self, _message: &DOMString, _default: &DOMString) -> DOMString {
null_string
}
pub fn Print(&self) {
}
pub fn ShowModalDialog(&self, _cx: *JSContext, _url: &DOMString, _argument: JSVal) -> JSVal {
JSVAL_NULL
}
}
impl CacheableWrapper for Window {
fn get_wrappercache(&mut self) -> &mut WrapperCache {
unsafe { cast::transmute(&self.wrapper) }
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
WindowBinding::Wrap(cx, scope, self, &mut unused)
}
}
impl BindingObject for Window {
fn GetParentObject(&self, _cx: *JSContext) -> Option<@mut CacheableWrapper> {
None
}
}
impl Window {
pub fn SetTimeout(&self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 {
let timeout = int::max(0, timeout) as uint; let timeout = int::max(0, timeout) as uint;
// Post a delayed message to the per-window timer task; it will dispatch it // Post a delayed message to the per-window timer task; it will dispatch it
// to the relevant script handler that will deal with it. // to the relevant script handler that will deal with it.
let data = ~TimerData {
funval: callback,
args: ~[]
};
timer::delayed_send(&uv_global_loop::get(), timer::delayed_send(&uv_global_loop::get(),
timeout, timeout,
&self.timer_chan, &self.timer_chan,
TimerMessage_Fire(~TimerData(argc, argv))); TimerMessage_Fire(data));
return 0; //TODO return handle into list of active timers
} }
pub fn content_changed(&self) { pub fn content_changed(&self) {
@ -121,7 +185,13 @@ impl Window {
unsafe { unsafe {
// TODO(tkuehn): This just grabs the top-level page. Need to handle subframes. // TODO(tkuehn): This just grabs the top-level page. Need to handle subframes.
let compartment = (*page).js_info.get_ref().js_compartment; let compartment = (*page).js_info.get_ref().js_compartment;
window::create(compartment, win); let cache = ptr::to_unsafe_ptr(win.get_wrappercache());
win.wrap_object_shared(compartment.cx.ptr, ptr::null()); //XXXjdm proper scope
compartment.define_property(~"window",
RUST_OBJECT_TO_JSVAL((*cache).wrapper),
GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
JSPROP_ENUMERATE);
} }
win win
} }

View file

@ -24,10 +24,10 @@ impl WindowProxy {
} }
impl BindingObject for WindowProxy { impl BindingObject for WindowProxy {
fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { fn GetParentObject(&self, cx: *JSContext) -> Option<@mut CacheableWrapper> {
let page = page_from_context(cx); let page = page_from_context(cx);
unsafe { unsafe {
(*page).frame.get_ref().window as @mut CacheableWrapper Some((*page).frame.get_ref().window as @mut CacheableWrapper)
} }
} }
} }

View file

@ -29,7 +29,6 @@ pub mod dom {
pub mod text; pub mod text;
pub mod utils; pub mod utils;
pub mod conversions; pub mod conversions;
pub mod window;
pub mod proxyhandler; pub mod proxyhandler;
pub mod domparser; pub mod domparser;
pub mod codegen { pub mod codegen {
@ -47,6 +46,7 @@ pub mod dom {
pub mod PrototypeList; pub mod PrototypeList;
pub mod RegisterBindings; pub mod RegisterBindings;
pub mod UIEventBinding; pub mod UIEventBinding;
pub mod WindowBinding;
pub mod WindowProxyBinding; pub mod WindowProxyBinding;
} }
} }

View file

@ -1,5 +1,7 @@
//window.alert(ClientRect); //window.alert(ClientRect);
//window.alert(ClientRectList); //window.alert(ClientRectList);
window.alert(window);
var document = window.document;
window.alert("==1=="); window.alert("==1==");
window.alert(document.documentElement); window.alert(document.documentElement);
window.alert(document.documentElement.firstChild); window.alert(document.documentElement.firstChild);

View file

@ -1,4 +1,4 @@
var divs = document.getElementsByTagName("div"); var divs = window.document.getElementsByTagName("div");
var div = divs[0]; var div = divs[0];
var count = 1000000; var count = 1000000;

View file

@ -7,7 +7,7 @@ function setWidth(w, i) {
window.setTimeout(function() { setWidth(w, i); }, 50); window.setTimeout(function() { setWidth(w, i); }, 50);
} }
var elem = document.documentElement.firstChild.firstChild.nextSibling.firstChild; var elem = window.document.documentElement.firstChild.firstChild.nextSibling.firstChild;
window.alert(elem.tagName); window.alert(elem.tagName);
window.alert(elem instanceof HTMLImageElement); window.alert(elem instanceof HTMLImageElement);
window.alert(elem instanceof HTMLElement); window.alert(elem instanceof HTMLElement);