mirror of
https://github.com/servo/servo.git
synced 2025-06-25 01:24:37 +01:00
Merge branch 'windowbinding'
This commit is contained in:
commit
eaada181b1
11 changed files with 185 additions and 40 deletions
|
@ -20,7 +20,10 @@ $(eval $(call DEF_SUBMODULE_TEST_RULES,$(submodule))))
|
||||||
servo-test: $(DEPS_servo)
|
servo-test: $(DEPS_servo)
|
||||||
$(CFG_RUSTC) $(RFLAGS_servo) --test -o $@ $<
|
$(CFG_RUSTC) $(RFLAGS_servo) --test -o $@ $<
|
||||||
|
|
||||||
reftest: src/reftest/reftest.rs servo
|
reftest: $(S)src/reftest/reftest.rs servo
|
||||||
|
$(CFG_RUSTC) $(RFLAGS_servo) -o $@ $< -L .
|
||||||
|
|
||||||
|
contenttest: $(S)src/contenttest/contenttest.rs servo
|
||||||
$(CFG_RUSTC) $(RFLAGS_servo) -o $@ $< -L .
|
$(CFG_RUSTC) $(RFLAGS_servo) -o $@ $< -L .
|
||||||
|
|
||||||
.PHONY: check $(DEPS_CHECK)
|
.PHONY: check $(DEPS_CHECK)
|
||||||
|
@ -31,5 +34,7 @@ check-servo: servo-test
|
||||||
./servo-test $(TESTNAME)
|
./servo-test $(TESTNAME)
|
||||||
|
|
||||||
check-ref: reftest
|
check-ref: reftest
|
||||||
./reftest --source-dir=$(VPATH)/src/test/ref --work-dir=src/test/ref $(TESTNAME)
|
./reftest --source-dir=$(VPATH)/test/ref --work-dir=src/test/ref $(TESTNAME)
|
||||||
|
|
||||||
|
check-content: contenttest
|
||||||
|
./contenttest --source-dir=$(VPATH)/test/content $(TESTNAME)
|
||||||
|
|
73
src/contenttest/contenttest.rs
Normal file
73
src/contenttest/contenttest.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
extern mod std;
|
||||||
|
|
||||||
|
use std::test::{TestOpts, run_tests_console, TestDesc};
|
||||||
|
use std::getopts::{getopts, reqopt, opt_str, fail_str};
|
||||||
|
use os::list_dir_path;
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
source_dir: ~str,
|
||||||
|
filter: Option<~str>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main(args: ~[~str]) {
|
||||||
|
let config = parse_config(args);
|
||||||
|
let opts = test_options(config);
|
||||||
|
let tests = find_tests(config);
|
||||||
|
run_tests_console(&opts, tests);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_config(args: ~[~str]) -> Config {
|
||||||
|
let args = args.tail();
|
||||||
|
let opts = ~[reqopt(~"source-dir")];
|
||||||
|
let matches = match getopts(args, opts) {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(f) => fail fail_str(f)
|
||||||
|
};
|
||||||
|
|
||||||
|
Config {
|
||||||
|
source_dir: opt_str(matches, ~"source-dir"),
|
||||||
|
filter: if matches.free.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(matches.free.head())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_options(config: Config) -> TestOpts {
|
||||||
|
{
|
||||||
|
filter: config.filter,
|
||||||
|
run_ignored: false,
|
||||||
|
logfile: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_tests(config: Config) -> ~[TestDesc] {
|
||||||
|
let all_files = list_dir_path(&Path(config.source_dir));
|
||||||
|
let html_files = all_files.filter( |file| file.to_str().ends_with(".html") );
|
||||||
|
return html_files.map(|file| make_test(config, (*file).to_str()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_test(config: Config, file: ~str) -> TestDesc {
|
||||||
|
{
|
||||||
|
name: file,
|
||||||
|
testfn: fn~() { run_test(config, file) },
|
||||||
|
ignore: false,
|
||||||
|
should_fail: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_test(config: Config, file: ~str) {
|
||||||
|
let infile = ~"file://" + os::make_absolute(&Path(file)).to_str();
|
||||||
|
let res = run::program_output("./servo", ~[infile]);
|
||||||
|
io::print(res.out);
|
||||||
|
do str::split_char_each(res.out, '\n') |line| {
|
||||||
|
if line.contains("TEST-UNEXPECTED-FAIL") {
|
||||||
|
fail str::from_slice(line);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_servo(config: Config, file: ~str) {
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ use ptr::null;
|
||||||
enum ControlMsg {
|
enum ControlMsg {
|
||||||
ParseMsg(Url),
|
ParseMsg(Url),
|
||||||
ExecuteMsg(Url),
|
ExecuteMsg(Url),
|
||||||
Timer(~dom::bindings::window::TimerData),
|
Timer(~dom::window::TimerData),
|
||||||
ExitMsg
|
ExitMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,54 +23,34 @@ extern fn alert(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool {
|
||||||
assert (argc == 1);
|
assert (argc == 1);
|
||||||
// Abstract this pattern and use it in debug, too?
|
// Abstract this pattern and use it in debug, too?
|
||||||
let jsstr = JS_ValueToString(cx, *ptr::offset(argv, 0));
|
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)));
|
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.alert(jsval_to_rust_str(cx, jsstr));
|
||||||
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||||
}
|
}
|
||||||
1_i32
|
1_i32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Holder for the various JS values associated with setTimeout
|
|
||||||
// (ie. function value to invoke and all arguments to pass
|
|
||||||
// to the function when calling it)
|
|
||||||
struct TimerData {
|
|
||||||
funval: jsval,
|
|
||||||
args: DVec<jsval>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn TimerData(argc: c_uint, argv: *jsval) -> TimerData unsafe {
|
|
||||||
let data = TimerData {
|
|
||||||
funval : *argv,
|
|
||||||
args : DVec(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut i = 2;
|
|
||||||
while i < argc as uint {
|
|
||||||
data.args.push(*ptr::offset(argv, i));
|
|
||||||
i += 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
data
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool unsafe {
|
extern fn setTimeout(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool unsafe {
|
||||||
let argv = JS_ARGV(cx, vp);
|
let argv = JS_ARGV(cx, vp);
|
||||||
assert (argc >= 2);
|
assert (argc >= 2);
|
||||||
|
|
||||||
//TODO: don't crash when passed a non-integer value for the timeout
|
//TODO: don't crash when passed a non-integer value for the timeout
|
||||||
|
|
||||||
// Post a delayed message to the per-window timer task; it will dispatch it
|
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.setTimeout(
|
||||||
// to the relevant content handler that will deal with it.
|
RUST_JSVAL_TO_INT(*ptr::offset(argv, 1)) as int,
|
||||||
std::timer::delayed_send(std::uv_global_loop::get(),
|
argc, argv);
|
||||||
RUST_JSVAL_TO_INT(*ptr::offset(argv, 1)) as uint,
|
|
||||||
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.timer_chan,
|
|
||||||
TimerMessage_Fire(~TimerData(argc, argv)));
|
|
||||||
|
|
||||||
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern fn close(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool unsafe {
|
||||||
|
(*unwrap(JS_THIS_OBJECT(cx, vp))).payload.close();
|
||||||
|
JS_SET_RVAL(cx, vp, JSVAL_NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
|
unsafe fn unwrap(obj: *JSObject) -> *rust_box<Window> {
|
||||||
let val = JS_GetReservedSlot(obj, 0);
|
let val = JS_GetReservedSlot(obj, 0);
|
||||||
cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val))
|
cast::reinterpret_cast(&RUST_JSVAL_TO_PRIVATE(val))
|
||||||
|
@ -102,6 +82,11 @@ fn init(compartment: bare_compartment, win: @Window) {
|
||||||
call: {op: setTimeout, info: null()},
|
call: {op: setTimeout, info: null()},
|
||||||
nargs: 2,
|
nargs: 2,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
|
selfHostedName: null()},
|
||||||
|
{name: compartment.add_name(~"close"),
|
||||||
|
call: {op: close, info: null()},
|
||||||
|
nargs: 2,
|
||||||
|
flags: 0,
|
||||||
selfHostedName: null()}];
|
selfHostedName: null()}];
|
||||||
|
|
||||||
vec::as_imm_buf(methods, |fns, _len| {
|
vec::as_imm_buf(methods, |fns, _len| {
|
||||||
|
|
|
@ -23,7 +23,6 @@ enum NodeData = {
|
||||||
kind: ~NodeKind,
|
kind: ~NodeKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* The tree holding Nodes (read-only) */
|
/* The tree holding Nodes (read-only) */
|
||||||
enum NodeTree { NodeTree }
|
enum NodeTree { NodeTree }
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use comm::{Port, Chan};
|
use comm::{Port, Chan};
|
||||||
use content::content_task::{ControlMsg, Timer};
|
use content::content_task::{ControlMsg, Timer, ExitMsg};
|
||||||
|
use js::jsapi::jsval;
|
||||||
|
use dvec::DVec;
|
||||||
|
|
||||||
enum TimerControlMsg {
|
enum TimerControlMsg {
|
||||||
TimerMessage_Fire(~dom::bindings::window::TimerData),
|
TimerMessage_Fire(~TimerData),
|
||||||
TimerMessage_Close
|
TimerMessage_Close,
|
||||||
|
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the content task
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
|
@ -14,6 +17,50 @@ struct Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Holder for the various JS values associated with setTimeout
|
||||||
|
// (ie. function value to invoke and all arguments to pass
|
||||||
|
// to the function when calling it)
|
||||||
|
struct TimerData {
|
||||||
|
funval: jsval,
|
||||||
|
args: DVec<jsval>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn TimerData(argc: libc::c_uint, argv: *jsval) -> TimerData unsafe {
|
||||||
|
let data = TimerData {
|
||||||
|
funval : *argv,
|
||||||
|
args : DVec(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut i = 2;
|
||||||
|
while i < argc as uint {
|
||||||
|
data.args.push(*ptr::offset(argv, i));
|
||||||
|
i += 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
data
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Window {
|
||||||
|
fn alert(s: &str) {
|
||||||
|
// Right now, just print to the console
|
||||||
|
io::println(#fmt("ALERT: %s", s));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close() {
|
||||||
|
self.timer_chan.send(TimerMessage_TriggerExit);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setTimeout(&self, timeout: int, argc: libc::c_uint, argv: *jsval) {
|
||||||
|
let timeout = int::max(0, timeout) as uint;
|
||||||
|
|
||||||
|
// Post a delayed message to the per-window timer task; it will dispatch it
|
||||||
|
// to the relevant content handler that will deal with it.
|
||||||
|
std::timer::delayed_send(std::uv_global_loop::get(),
|
||||||
|
timeout, self.timer_chan,
|
||||||
|
TimerMessage_Fire(~TimerData(argc, argv)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn Window(content_port: Port<ControlMsg>) -> Window {
|
fn Window(content_port: Port<ControlMsg>) -> Window {
|
||||||
let content_chan = Chan(content_port);
|
let content_chan = Chan(content_port);
|
||||||
|
|
||||||
|
@ -25,6 +72,7 @@ fn Window(content_port: Port<ControlMsg>) -> Window {
|
||||||
TimerMessage_Fire(td) => {
|
TimerMessage_Fire(td) => {
|
||||||
content_chan.send(Timer(copy td));
|
content_chan.send(Timer(copy td));
|
||||||
}
|
}
|
||||||
|
TimerMessage_TriggerExit => content_chan.send(ExitMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/test/content/harness.js
Normal file
16
src/test/content/harness.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
function _fail(s) {
|
||||||
|
window.alert("TEST-UNEXPECTED-FAIL | " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pass(s) {
|
||||||
|
window.alert("TEST-PASS | " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is(a, b) {
|
||||||
|
let f = a != b ? _fail : _pass;
|
||||||
|
f(a + " == " + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
window.close();
|
||||||
|
}
|
8
src/test/content/test_prototypes.html
Normal file
8
src/test/content/test_prototypes.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="harness.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="test_prototypes.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
src/test/content/test_prototypes.js
Normal file
7
src/test/content/test_prototypes.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
is(HTMLImageElement instanceof HTMLElement, true);
|
||||||
|
is(HTMLElement instanceof Element, true);
|
||||||
|
is(Element instanceof Node, true);
|
||||||
|
is(document instanceof Document, true);
|
||||||
|
is(document.documentElement instanceof HTMLElement, true);
|
||||||
|
is(document.documentElement instanceof Element, true);
|
||||||
|
finish();
|
3
src/test/test_close.html
Normal file
3
src/test/test_close.html
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<html>
|
||||||
|
<script src="test_close.js"></script>
|
||||||
|
</html>
|
1
src/test/test_close.js
Normal file
1
src/test/test_close.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
window.setTimeout(function() { window.close(); }, 3000);
|
Loading…
Add table
Add a link
Reference in a new issue