Skip to content
This repository
Browse code

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 authored August 20, 2012
2  src/rust-mozjs
... ...
@@ -1 +1 @@
1  
-Subproject commit fc904d3a7c36934ad0b2a4f83ad99f3862febada
  1
+Subproject commit 1a01c0063a4f0cd5ceaf04fbd84a59699f668a02
15  src/servo/content/content_task.rs
@@ -13,7 +13,7 @@ import task::{spawn, spawn_listener};
13 13
 import io::{read_whole_file, println};
14 14
 import result::{ok, err};
15 15
 
16  
-import dom::base::{Document, Node, NodeScope, define_bindings};
  16
+import dom::base::{Document, Node, NodeScope, Window, define_bindings};
17 17
 import dom::event::{Event, ResizeEvent};
18 18
 import dom::style;
19 19
 import dom::style::Stylesheet;
@@ -80,6 +80,7 @@ struct Content<C:Compositor> {
80 80
     let jsrt: jsrt;
81 81
 
82 82
     let mut document: option<@Document>;
  83
+    let mut window:   option<@Window>;
83 84
     let mut doc_url: option<url>;
84 85
 
85 86
     let resource_task: ResourceTask;
@@ -95,7 +96,8 @@ struct Content<C:Compositor> {
95 96
         self.jsrt = jsrt();
96 97
 
97 98
         self.document = none;
98  
-        self.doc_url = none;
  99
+        self.window   = none;
  100
+        self.doc_url  = none;
99 101
 
100 102
         self.compositor.add_event_listener(self.event_port.chan());
101 103
 
@@ -129,13 +131,15 @@ struct Content<C:Compositor> {
129 131
             let js_scripts = js_port.recv();
130 132
 
131 133
             // Apply the css rules to the dom tree:
132  
-            #debug["%?", css_rules];
  134
+            #debug["css_rules: %?", css_rules];
133 135
 
134  
-            #debug["%?", js_scripts];
  136
+            #debug["js_scripts: %?", js_scripts];
135 137
 
136 138
             let document = Document(root, css_rules);
  139
+            let window   = Window(root);
137 140
             self.relayout(document, &url);
138 141
             self.document = some(@document);
  142
+            self.window   = some(@window);
139 143
             self.doc_url = some(copy url);
140 144
 
141 145
             //XXXjdm it was easier to duplicate the relevant ExecuteMsg code;
@@ -146,7 +150,8 @@ struct Content<C:Compositor> {
146 150
                 cx.set_logging_error_reporter();
147 151
                 cx.new_compartment(global_class).chain(|compartment| {
148 152
                     compartment.define_functions(debug_fns);
149  
-                    define_bindings(*compartment, option::get(self.document));
  153
+                    define_bindings(*compartment, option::get(self.document),
  154
+                                    option::get(self.window));
150 155
                     cx.evaluate_script(compartment.global_obj, bytes, ~"???", 1u)
151 156
                 });
152 157
             }
11  src/servo/dom/base.rs
@@ -15,6 +15,13 @@ import bindings;
15 15
 import std::arc::arc;
16 16
 import style::Stylesheet;
17 17
 
  18
+struct Window {
  19
+    let root: Node;
  20
+    new(root: Node) {
  21
+        self.root = root;
  22
+    }
  23
+}
  24
+
18 25
 struct Document {
19 26
     let root: Node;
20 27
     let css_rules: arc<Stylesheet>;
@@ -69,7 +76,9 @@ struct Attr {
69 76
     }
70 77
 }
71 78
 
72  
-fn define_bindings(compartment: bare_compartment, doc: @Document) {
  79
+fn define_bindings(compartment: bare_compartment, doc: @Document,
  80
+                   win: @Window) {
  81
+    bindings::window::init(compartment, win);
73 82
     bindings::document::init(compartment, doc);
74 83
     bindings::node::init(compartment);
75 84
 }
46  src/servo/dom/bindings/document.rs
... ...
@@ -1,4 +1,4 @@
1  
-import js::rust::{bare_compartment, methods};
  1
+import js::rust::{compartment, bare_compartment, methods, jsobj};
2 2
 import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT,
3 3
             JS_SET_RVAL};
4 4
 import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@@ -10,9 +10,10 @@ import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_
10 10
 import result::{result, ok, err};
11 11
 import ptr::null;
12 12
 import libc::c_uint;
13  
-import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
  13
+import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str,
  14
+     Document_class};
14 15
 import bindings::node::create;
15  
-import base::Document;
  16
+import base::{Document, Node};
16 17
 
17 18
 enum DOMException {
18 19
     INVALID_CHARACTER_ERR
@@ -59,6 +60,8 @@ enum Element = int;
59 60
     return 1;
60 61
 }*/
61 62
 
  63
+// Unfortunately duplicated in document and window.
  64
+// Generalizing it triggers a trans bug
62 65
 extern fn getDocumentElement(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool unsafe {
63 66
     let node = (*unwrap(obj)).payload.root;
64 67
     *rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr);
@@ -80,7 +83,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
80 83
 }
81 84
 
82 85
 fn init(compartment: bare_compartment, doc: @Document) {
83  
-    fn DocumentProto_class(compartment: bare_compartment) -> JSClass {
  86
+  fn DocumentProto_class(compartment: bare_compartment) -> JSClass {
84 87
         {name: compartment.add_name(~"DOMDocumentPrototype"),
85 88
          flags: 0,
86 89
          addProperty: JS_PropertyStub,
@@ -106,39 +109,16 @@ fn init(compartment: bare_compartment, doc: @Document) {
106 109
                     null(), null(), null(), null(), null())} // 40
107 110
     };
108 111
 
109  
-    fn Document_class(compartment: bare_compartment) -> JSClass {
110  
-        {name: compartment.add_name(~"DOMDocument"),
111  
-         flags: JSCLASS_HAS_RESERVED_SLOTS(1),
112  
-         addProperty: JS_PropertyStub,
113  
-         delProperty: JS_PropertyStub,
114  
-         getProperty: JS_PropertyStub,
115  
-         setProperty: JS_StrictPropertyStub,
116  
-         enumerate: JS_EnumerateStub,
117  
-         resolve: JS_ResolveStub,
118  
-         convert: JS_ConvertStub,
119  
-         finalize: finalize,
120  
-         checkAccess: null(),
121  
-         call: null(),
122  
-         construct: null(),
123  
-         hasInstance: utils::has_instance,
124  
-         trace: null(),
125  
-         reserved: (null(), null(), null(), null(), null(),  // 05
126  
-                    null(), null(), null(), null(), null(),  // 10
127  
-                    null(), null(), null(), null(), null(),  // 15
128  
-                    null(), null(), null(), null(), null(),  // 20
129  
-                    null(), null(), null(), null(), null(),  // 25
130  
-                    null(), null(), null(), null(), null(),  // 30
131  
-                    null(), null(), null(), null(), null(),  // 35
132  
-                    null(), null(), null(), null(), null())} // 40
133  
-    };
134  
-
135 112
     compartment.register_class(DocumentProto_class);
136  
-    compartment.register_class(Document_class);
  113
+    compartment.register_class(|c| Document_class(c, ~"DOMDocument",
  114
+                                                  finalize));
137 115
 
138 116
     //TODO error checking
139 117
     let obj = result::unwrap(
140  
-        compartment.new_object(~"DOMDocumentPrototype", null(),
141  
-                               compartment.global_obj.ptr));
  118
+                compartment.new_object(~"DOMDocumentPrototype",
  119
+                                       null(),
  120
+                                       compartment.global_obj.ptr));
  121
+
142 122
     /*let methods = ~[
143 123
         {name: compartment.add_name("getDocumentURI"),
144 124
           call: getDocumentURI,
32  src/servo/dom/bindings/utils.rs
... ...
@@ -1,4 +1,4 @@
1  
-import js::rust::{compartment, bare_compartment};
  1
+import js::rust::{compartment, bare_compartment, methods};
2 2
 import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
3 3
             JS_THIS_OBJECT, JS_SET_RVAL};
4 4
 import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
@@ -7,7 +7,10 @@ import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_Re
7 7
                             JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate,
8 8
                             JS_GetClass, JS_GetPrototype};
9 9
 import js::glue::bindgen::*;
  10
+import ptr::null;
10 11
 import result::{result, ok, err};
  12
+import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
  13
+    JS_ResolveStub, JS_ConvertStub};
11 14
 
12 15
 enum DOMString {
13 16
     str(~str),
@@ -91,3 +94,30 @@ extern fn has_instance(_cx: *JSContext, obj: *JSObject, v: *jsval, bp: *mut JSBo
91 94
     }
92 95
     return 1;
93 96
 }
  97
+
  98
+fn Document_class(compartment: bare_compartment, name: ~str,
  99
+                  finalize: *u8) -> JSClass {
  100
+        {name: compartment.add_name(name),
  101
+         flags: JSCLASS_HAS_RESERVED_SLOTS(1),
  102
+         addProperty: JS_PropertyStub,
  103
+         delProperty: JS_PropertyStub,
  104
+         getProperty: JS_PropertyStub,
  105
+         setProperty: JS_StrictPropertyStub,
  106
+         enumerate: JS_EnumerateStub,
  107
+         resolve: JS_ResolveStub,
  108
+         convert: JS_ConvertStub,
  109
+         finalize: finalize,
  110
+         checkAccess: null(),
  111
+         call: null(),
  112
+         construct: null(),
  113
+         hasInstance: null(),
  114
+         trace: null(),
  115
+         reserved: (null(), null(), null(), null(), null(),  // 05
  116
+                    null(), null(), null(), null(), null(),  // 10
  117
+                    null(), null(), null(), null(), null(),  // 15
  118
+                    null(), null(), null(), null(), null(),  // 20
  119
+                    null(), null(), null(), null(), null(),  // 25
  120
+                    null(), null(), null(), null(), null(),  // 30
  121
+                    null(), null(), null(), null(), null(),  // 35
  122
+                    null(), null(), null(), null(), null())} // 40
  123
+}
97  src/servo/dom/bindings/window.rs
... ...
@@ -0,0 +1,97 @@
  1
+import js::rust::{bare_compartment, methods};
  2
+import js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT,
  3
+            JS_SET_RVAL};
  4
+import js::jsapi::{JSContext, jsval, JSObject, JSBool, jsid, JSClass, JSFreeOp};
  5
+import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
  6
+                            JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
  7
+    JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties, JS_EncodeString, JS_free};
  8
+import js::glue::bindgen::*;
  9
+import js::global::jsval_to_rust_str;
  10
+import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
  11
+import result::{result, ok, err};
  12
+import ptr::null;
  13
+import libc::c_uint;
  14
+import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str,
  15
+    Document_class};
  16
+import bindings::node::create;
  17
+import base::{Node, Window};
  18
+
  19
+enum DOMException {
  20
+    INVALID_CHARACTER_ERR
  21
+}
  22
+
  23
+enum Element = int;
  24
+
  25
+extern fn alert(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool {
  26
+  unsafe {
  27
+    let argv = JS_ARGV(cx, vp);
  28
+    assert (argc == 1);
  29
+    // Abstract this pattern and use it in debug, too?
  30
+    let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
  31
+    // Right now, just print to the console
  32
+    io::println(#fmt("ALERT: %s", jsval_to_rust_str(cx, jsstr)));
  33
+    JS_SET_RVAL(cx, vp, JSVAL_NULL);
  34
+  }
  35
+  1_i32
  36
+}
  37
+
  38
+// Unfortunately duplicated in document and window.
  39
+// Generalizing it triggers a trans bug
  40
+extern fn getDocumentElement(cx: *JSContext, obj: *JSObject,
  41
+      _id: jsid, rval: *mut jsval) -> JSBool unsafe {
  42
+  let node = (*unwrap(obj)).payload.root;
  43
+    *rval = RUST_OBJECT_TO_JSVAL(node::create(cx, node).ptr);
  44
+    return 1;
  45
+}
  46
+
  47
+unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
  48
+    let val = JS_GetReservedSlot(obj, 0);
  49
+    unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val))
  50
+}
  51
+
  52
+extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
  53
+    #debug("finalize!");
  54
+    unsafe {
  55
+        let val = JS_GetReservedSlot(obj, 0);
  56
+        let _: @Window = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val));
  57
+    }
  58
+}
  59
+
  60
+fn init(compartment: bare_compartment, win: @Window) {
  61
+
  62
+    compartment.register_class(|c| Document_class(c, ~"DOMWindow",
  63
+                                                  finalize));
  64
+
  65
+    let obj = result::unwrap(
  66
+                 compartment.new_object(~"DOMWindow", null(), null()));
  67
+
  68
+    /* Define methods on a window */
  69
+    let methods = ~[{name: compartment.add_name(~"alert"),
  70
+                     call: alert,
  71
+                     nargs: 1,
  72
+                     flags: 0}];
  73
+    
  74
+    vec::as_buf(methods, |fns, _len| {
  75
+        JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
  76
+      });
  77
+
  78
+    let attrs = @~[
  79
+        {name: compartment.add_name(~"DOMWindow"),
  80
+         tinyid: 0, // ???
  81
+         flags: 0,
  82
+         getter: getDocumentElement,
  83
+         setter: null()}];
  84
+    vec::push(compartment.global_props, attrs);
  85
+        vec::as_buf(*attrs, |specs, _len| {
  86
+        JS_DefineProperties(compartment.cx.ptr, obj.ptr, specs);
  87
+    });
  88
+
  89
+    unsafe {
  90
+        let raw_ptr: *libc::c_void = unsafe::reinterpret_cast(squirrel_away(win));
  91
+        JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
  92
+    }
  93
+
  94
+    compartment.define_property(~"window", RUST_OBJECT_TO_JSVAL(obj.ptr),
  95
+                                JS_PropertyStub, JS_StrictPropertyStub,
  96
+                                JSPROP_ENUMERATE);
  97
+}
1  src/servo/servo.rc
@@ -28,6 +28,7 @@ mod dom {
28 28
         mod document;
29 29
         mod utils;
30 30
         mod node;
  31
+        mod window;
31 32
     }
32 33
 }
33 34
 
8  src/test/test-alert.js
... ...
@@ -0,0 +1,8 @@
  1
+function output (text)
  2
+{
  3
+    window.alert(text);
  4
+}
  5
+
  6
+output("Opossums have pouches like kangaroos");
  7
+
  8
+
1  src/test/test-js-alert.html
... ...
@@ -0,0 +1 @@
  1
+<script src="test-alert.js"></script>

0 notes on commit 5079e10

Please sign in to comment.
Something went wrong with that request. Please try again.