mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +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 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)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
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 utils;
|
||||
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