Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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.
  • Loading branch information...
commit 5079e1088217eb23a82487d3a352de4f7c3659a2 1 parent 82c9f9b
Tim Chevalier catamorphism authored
2  src/rust-mozjs
@@ -1 +1 @@
-Subproject commit fc904d3a7c36934ad0b2a4f83ad99f3862febada
+Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02
15 src/servo/content/content_task.rs
View
@@ -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)
});
}
11 src/servo/dom/base.rs
View
@@ -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);
}
46 src/servo/dom/bindings/document.rs
View
@@ -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,
32 src/servo/dom/bindings/utils.rs
View
@@ -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
View
@@ -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);
+}
1  src/servo/servo.rc
View
@@ -28,6 +28,7 @@ mod dom {
mod document;
mod utils;
mod node;
+ mod window;
}
}
8 src/test/test-alert.js
View
@@ -0,0 +1,8 @@
+function output (text)
+{
+ window.alert(text);
+}
+
+output("Opossums have pouches like kangaroos");
+
+
1  src/test/test-js-alert.html
View
@@ -0,0 +1 @@
+<script src="test-alert.js"></script>
Please sign in to comment.
Something went wrong with that request. Please try again.