Add a window object with an alert method

test/test-js-alert.html tests use of the alert method, which currently
just prints to the console.
This commit is contained in:
Tim Chevalier 2012-08-20 18:49:13 -07:00
parent 82c9f9b84b
commit 5079e10882
9 changed files with 172 additions and 41 deletions

@ -1 +1 @@
Subproject commit fc904d3a7c36934ad0b2a4f83ad99f3862febada
Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02

View file

@ -13,7 +13,7 @@ import task::{spawn, spawn_listener};
import io::{read_whole_file, println};
import result::{ok, err};
import dom::base::{Document, Node, NodeScope, define_bindings};
import dom::base::{Document, Node, NodeScope, Window, define_bindings};
import dom::event::{Event, ResizeEvent};
import dom::style;
import dom::style::Stylesheet;
@ -80,6 +80,7 @@ struct Content<C:Compositor> {
let jsrt: jsrt;
let mut document: option<@Document>;
let mut window: option<@Window>;
let mut doc_url: option<url>;
let resource_task: ResourceTask;
@ -95,7 +96,8 @@ struct Content<C:Compositor> {
self.jsrt = jsrt();
self.document = none;
self.doc_url = none;
self.window = none;
self.doc_url = none;
self.compositor.add_event_listener(self.event_port.chan());
@ -129,13 +131,15 @@ struct Content<C:Compositor> {
let js_scripts = js_port.recv();
// Apply the css rules to the dom tree:
#debug["%?", css_rules];
#debug["css_rules: %?", css_rules];
#debug["%?", js_scripts];
#debug["js_scripts: %?", js_scripts];
let document = Document(root, css_rules);
let window = Window(root);
self.relayout(document, &url);
self.document = some(@document);
self.window = some(@window);
self.doc_url = some(copy url);
//XXXjdm it was easier to duplicate the relevant ExecuteMsg code;
@ -146,7 +150,8 @@ struct Content<C:Compositor> {
cx.set_logging_error_reporter();
cx.new_compartment(global_class).chain(|compartment| {
compartment.define_functions(debug_fns);
define_bindings(*compartment, option::get(self.document));
define_bindings(*compartment, option::get(self.document),
option::get(self.window));
cx.evaluate_script(compartment.global_obj, bytes, ~"???", 1u)
});
}

View file

@ -15,6 +15,13 @@ import bindings;
import std::arc::arc;
import style::Stylesheet;
struct Window {
let root: Node;
new(root: Node) {
self.root = root;
}
}
struct Document {
let root: Node;
let css_rules: arc<Stylesheet>;
@ -69,7 +76,9 @@ struct Attr {
}
}
fn define_bindings(compartment: bare_compartment, doc: @Document) {
fn define_bindings(compartment: bare_compartment, doc: @Document,
win: @Window) {
bindings::window::init(compartment, win);
bindings::document::init(compartment, doc);
bindings::node::init(compartment);
}

View file

@ -1,4 +1,4 @@
import js::rust::{bare_compartment, methods};
import js::rust::{compartment, bare_compartment, methods, jsobj};
import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT,
JS_SET_RVAL};
import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@ -10,9 +10,10 @@ import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_
import result::{result, ok, err};
import ptr::null;
import libc::c_uint;
import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str,
Document_class};
import bindings::node::create;
import base::Document;
import base::{Document, Node};
enum DOMException {
INVALID_CHARACTER_ERR
@ -59,6 +60,8 @@ enum Element = int;
return 1;
}*/
// Unfortunately duplicated in document and window.
// Generalizing it triggers a trans bug
extern fn getDocumentElement(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool unsafe {
let node = (*unwrap(obj)).payload.root;
*rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr);
@ -80,7 +83,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
}
fn init(compartment: bare_compartment, doc: @Document) {
fn DocumentProto_class(compartment: bare_compartment) -> JSClass {
fn DocumentProto_class(compartment: bare_compartment) -> JSClass {
{name: compartment.add_name(~"DOMDocumentPrototype"),
flags: 0,
addProperty: JS_PropertyStub,
@ -106,39 +109,16 @@ fn init(compartment: bare_compartment, doc: @Document) {
null(), null(), null(), null(), null())} // 40
};
fn Document_class(compartment: bare_compartment) -> JSClass {
{name: compartment.add_name(~"DOMDocument"),
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
addProperty: JS_PropertyStub,
delProperty: JS_PropertyStub,
getProperty: JS_PropertyStub,
setProperty: JS_StrictPropertyStub,
enumerate: JS_EnumerateStub,
resolve: JS_ResolveStub,
convert: JS_ConvertStub,
finalize: finalize,
checkAccess: null(),
call: null(),
construct: null(),
hasInstance: utils::has_instance,
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null())} // 40
};
compartment.register_class(DocumentProto_class);
compartment.register_class(Document_class);
compartment.register_class(|c| Document_class(c, ~"DOMDocument",
finalize));
//TODO error checking
let obj = result::unwrap(
compartment.new_object(~"DOMDocumentPrototype", null(),
compartment.global_obj.ptr));
compartment.new_object(~"DOMDocumentPrototype",
null(),
compartment.global_obj.ptr));
/*let methods = ~[
{name: compartment.add_name("getDocumentURI"),
call: getDocumentURI,

View file

@ -1,4 +1,4 @@
import js::rust::{compartment, bare_compartment};
import js::rust::{compartment, bare_compartment, methods};
import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
JS_THIS_OBJECT, JS_SET_RVAL};
import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@ -7,7 +7,10 @@ import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_Re
JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate,
JS_GetClass, JS_GetPrototype};
import js::glue::bindgen::*;
import ptr::null;
import result::{result, ok, err};
import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub};
enum DOMString {
str(~str),
@ -91,3 +94,30 @@ extern fn has_instance(_cx: *JSContext, obj: *JSObject, v: *jsval, bp: *mut JSBo
}
return 1;
}
fn Document_class(compartment: bare_compartment, name: ~str,
finalize: *u8) -> JSClass {
{name: compartment.add_name(name),
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
addProperty: JS_PropertyStub,
delProperty: JS_PropertyStub,
getProperty: JS_PropertyStub,
setProperty: JS_StrictPropertyStub,
enumerate: JS_EnumerateStub,
resolve: JS_ResolveStub,
convert: JS_ConvertStub,
finalize: finalize,
checkAccess: null(),
call: null(),
construct: null(),
hasInstance: null(),
trace: null(),
reserved: (null(), null(), null(), null(), null(), // 05
null(), null(), null(), null(), null(), // 10
null(), null(), null(), null(), null(), // 15
null(), null(), null(), null(), null(), // 20
null(), null(), null(), null(), null(), // 25
null(), null(), null(), null(), null(), // 30
null(), null(), null(), null(), null(), // 35
null(), null(), null(), null(), null())} // 40
}

View file

@ -0,0 +1,97 @@
import js::rust::{bare_compartment, methods};
import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT,
JS_SET_RVAL};
import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties, JS_EncodeString, JS_free};
import js::glue::bindgen::*;
import js::global::jsval_to_rust_str;
import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
import result::{result, ok, err};
import ptr::null;
import libc::c_uint;
import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str,
Document_class};
import bindings::node::create;
import base::{Node, Window};
enum DOMException {
INVALID_CHARACTER_ERR
}
enum Element = int;
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));
// Right now, just print to the console
io::println(#fmt("ALERT: %s", jsval_to_rust_str(cx, jsstr)));
JS_SET_RVAL(cx, vp, JSVAL_NULL);
}
1_i32
}
// Unfortunately duplicated in document and window.
// Generalizing it triggers a trans bug
extern fn getDocumentElement(cx: *JSContext, obj: *JSObject,
_id: jsid, rval: *mut jsval) -> JSBool unsafe {
let node = (*unwrap(obj)).payload.root;
*rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr);
return 1;
}
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
let val = JS_GetReservedSlot(obj, 0);
unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val))
}
extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
#debug("finalize!");
unsafe {
let val = JS_GetReservedSlot(obj, 0);
let _: @Window = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val));
}
}
fn init(compartment: bare_compartment, win: @Window) {
compartment.register_class(|c| Document_class(c, ~"DOMWindow",
finalize));
let obj = result::unwrap(
compartment.new_object(~"DOMWindow", null(), null()));
/* Define methods on a window */
let methods = ~[{name: compartment.add_name(~"alert"),
call: alert,
nargs: 1,
flags: 0}];
vec::as_buf(methods, |fns, _len| {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
});
let attrs = @~[
{name: compartment.add_name(~"DOMWindow"),
tinyid: 0, // ???
flags: 0,
getter: getDocumentElement,
setter: null()}];
vec::push(compartment.global_props, attrs);
vec::as_buf(*attrs, |specs, _len| {
JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
});
unsafe {
let raw_ptr: *libc::c_void = unsafe::reinterpret_cast(squirrel_away(win));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}
compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE);
}

View file

@ -28,6 +28,7 @@ mod dom {
mod document;
mod utils;
mod node;
mod window;
}
}

8
src/test/test-alert.js Normal file
View file

@ -0,0 +1,8 @@
function output (text)
{
window.alert(text);
}
output("Opossums have pouches like kangaroos");

View file

@ -0,0 +1 @@
<script src="test-alert.js"></script>