mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
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:
parent
82c9f9b84b
commit
5079e10882
9 changed files with 172 additions and 41 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit fc904d3a7c36934ad0b2a4f83ad99f3862febada
|
Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02
|
|
@ -13,7 +13,7 @@ import task::{spawn, spawn_listener};
|
||||||
import io::{read_whole_file, println};
|
import io::{read_whole_file, println};
|
||||||
import result::{ok, err};
|
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::event::{Event, ResizeEvent};
|
||||||
import dom::style;
|
import dom::style;
|
||||||
import dom::style::Stylesheet;
|
import dom::style::Stylesheet;
|
||||||
|
@ -80,6 +80,7 @@ struct Content<C:Compositor> {
|
||||||
let jsrt: jsrt;
|
let jsrt: jsrt;
|
||||||
|
|
||||||
let mut document: option<@Document>;
|
let mut document: option<@Document>;
|
||||||
|
let mut window: option<@Window>;
|
||||||
let mut doc_url: option<url>;
|
let mut doc_url: option<url>;
|
||||||
|
|
||||||
let resource_task: ResourceTask;
|
let resource_task: ResourceTask;
|
||||||
|
@ -95,7 +96,8 @@ struct Content<C:Compositor> {
|
||||||
self.jsrt = jsrt();
|
self.jsrt = jsrt();
|
||||||
|
|
||||||
self.document = none;
|
self.document = none;
|
||||||
self.doc_url = none;
|
self.window = none;
|
||||||
|
self.doc_url = none;
|
||||||
|
|
||||||
self.compositor.add_event_listener(self.event_port.chan());
|
self.compositor.add_event_listener(self.event_port.chan());
|
||||||
|
|
||||||
|
@ -129,13 +131,15 @@ struct Content<C:Compositor> {
|
||||||
let js_scripts = js_port.recv();
|
let js_scripts = js_port.recv();
|
||||||
|
|
||||||
// Apply the css rules to the dom tree:
|
// 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 document = Document(root, css_rules);
|
||||||
|
let window = Window(root);
|
||||||
self.relayout(document, &url);
|
self.relayout(document, &url);
|
||||||
self.document = some(@document);
|
self.document = some(@document);
|
||||||
|
self.window = some(@window);
|
||||||
self.doc_url = some(copy url);
|
self.doc_url = some(copy url);
|
||||||
|
|
||||||
//XXXjdm it was easier to duplicate the relevant ExecuteMsg code;
|
//XXXjdm it was easier to duplicate the relevant ExecuteMsg code;
|
||||||
|
@ -146,7 +150,8 @@ struct Content<C:Compositor> {
|
||||||
cx.set_logging_error_reporter();
|
cx.set_logging_error_reporter();
|
||||||
cx.new_compartment(global_class).chain(|compartment| {
|
cx.new_compartment(global_class).chain(|compartment| {
|
||||||
compartment.define_functions(debug_fns);
|
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)
|
cx.evaluate_script(compartment.global_obj, bytes, ~"???", 1u)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,13 @@ import bindings;
|
||||||
import std::arc::arc;
|
import std::arc::arc;
|
||||||
import style::Stylesheet;
|
import style::Stylesheet;
|
||||||
|
|
||||||
|
struct Window {
|
||||||
|
let root: Node;
|
||||||
|
new(root: Node) {
|
||||||
|
self.root = root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Document {
|
struct Document {
|
||||||
let root: Node;
|
let root: Node;
|
||||||
let css_rules: arc<Stylesheet>;
|
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::document::init(compartment, doc);
|
||||||
bindings::node::init(compartment);
|
bindings::node::init(compartment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT,
|
||||||
JS_SET_RVAL};
|
JS_SET_RVAL};
|
||||||
import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
|
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 result::{result, ok, err};
|
||||||
import ptr::null;
|
import ptr::null;
|
||||||
import libc::c_uint;
|
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 bindings::node::create;
|
||||||
import base::Document;
|
import base::{Document, Node};
|
||||||
|
|
||||||
enum DOMException {
|
enum DOMException {
|
||||||
INVALID_CHARACTER_ERR
|
INVALID_CHARACTER_ERR
|
||||||
|
@ -59,6 +60,8 @@ enum Element = int;
|
||||||
return 1;
|
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 {
|
extern fn getDocumentElement(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool unsafe {
|
||||||
let node = (*unwrap(obj)).payload.root;
|
let node = (*unwrap(obj)).payload.root;
|
||||||
*rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr);
|
*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 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"),
|
{name: compartment.add_name(~"DOMDocumentPrototype"),
|
||||||
flags: 0,
|
flags: 0,
|
||||||
addProperty: JS_PropertyStub,
|
addProperty: JS_PropertyStub,
|
||||||
|
@ -106,39 +109,16 @@ fn init(compartment: bare_compartment, doc: @Document) {
|
||||||
null(), null(), null(), null(), null())} // 40
|
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(DocumentProto_class);
|
||||||
compartment.register_class(Document_class);
|
compartment.register_class(|c| Document_class(c, ~"DOMDocument",
|
||||||
|
finalize));
|
||||||
|
|
||||||
//TODO error checking
|
//TODO error checking
|
||||||
let obj = result::unwrap(
|
let obj = result::unwrap(
|
||||||
compartment.new_object(~"DOMDocumentPrototype", null(),
|
compartment.new_object(~"DOMDocumentPrototype",
|
||||||
compartment.global_obj.ptr));
|
null(),
|
||||||
|
compartment.global_obj.ptr));
|
||||||
|
|
||||||
/*let methods = ~[
|
/*let methods = ~[
|
||||||
{name: compartment.add_name("getDocumentURI"),
|
{name: compartment.add_name("getDocumentURI"),
|
||||||
call: getDocumentURI,
|
call: getDocumentURI,
|
||||||
|
|
|
@ -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,
|
import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
|
||||||
JS_THIS_OBJECT, JS_SET_RVAL};
|
JS_THIS_OBJECT, JS_SET_RVAL};
|
||||||
import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
|
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_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate,
|
||||||
JS_GetClass, JS_GetPrototype};
|
JS_GetClass, JS_GetPrototype};
|
||||||
import js::glue::bindgen::*;
|
import js::glue::bindgen::*;
|
||||||
|
import ptr::null;
|
||||||
import result::{result, ok, err};
|
import result::{result, ok, err};
|
||||||
|
import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
|
||||||
|
JS_ResolveStub, JS_ConvertStub};
|
||||||
|
|
||||||
enum DOMString {
|
enum DOMString {
|
||||||
str(~str),
|
str(~str),
|
||||||
|
@ -91,3 +94,30 @@ extern fn has_instance(_cx: *JSContext, obj: *JSObject, v: *jsval, bp: *mut JSBo
|
||||||
}
|
}
|
||||||
return 1;
|
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
|
||||||
|
}
|
||||||
|
|
97
src/servo/dom/bindings/window.rs
Normal file
97
src/servo/dom/bindings/window.rs
Normal 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);
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ mod dom {
|
||||||
mod document;
|
mod document;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod node;
|
mod node;
|
||||||
|
mod window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
src/test/test-alert.js
Normal file
8
src/test/test-alert.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
function output (text)
|
||||||
|
{
|
||||||
|
window.alert(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
output("Opossums have pouches like kangaroos");
|
||||||
|
|
||||||
|
|
1
src/test/test-js-alert.html
Normal file
1
src/test/test-js-alert.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<script src="test-alert.js"></script>
|
Loading…
Add table
Add a link
Reference in a new issue