Skip to content

Commit

Permalink
Add primitive binding example for Document (documentElement), and Nod…
Browse files Browse the repository at this point in the history
…e (firstChild, nextSibling, tagName).
  • Loading branch information
jdm committed Jul 24, 2012
1 parent 82790f2 commit 4a1c8cc
Show file tree
Hide file tree
Showing 16 changed files with 501 additions and 22 deletions.
5 changes: 5 additions & 0 deletions Makefile.in
Expand Up @@ -87,6 +87,7 @@ CLEAN_DEPS += \
clean-ragel \
clean-harfbuzz \
clean-rust-harfbuzz \
clean-mozjs \
clean-rust-mozjs \
clean-rust-sdl \
clean-rust-azure \
Expand Down Expand Up @@ -213,6 +214,10 @@ clean-harfbuzz:
clean-rust-harfbuzz:
$(MAKE) clean -C src/rust-harfbuzz

.PHONY: clean-mozjs
clean-mozjs:
$(MAKE) clean -C src/mozjs

.PHONY: clean-rust-mozjs
clean-rust-mozjs:
$(MAKE) clean -C src/rust-mozjs
Expand Down
2 changes: 1 addition & 1 deletion configure.in
Expand Up @@ -19,7 +19,7 @@ mkdir -p src/rust-layers || exit $?

(cd src/ragel && sh ${SRCDIR}/src/ragel/configure) || exit $?
(cd src/harfbuzz && sh ${SRCDIR}/src/harfbuzz/configure --enable-static) || exit $?
(cd src/mozjs && sh ${SRCDIR}/src/mozjs/js/src/configure) || exit $?
(cd src/mozjs && sh ${SRCDIR}/src/mozjs/js/src/configure --enable-debug --disable-optimize) || exit $?
(cd src/rust-opengles && sh ${SRCDIR}/src/rust-opengles/configure) || exit $?
(cd src/rust-harfbuzz && sh ${SRCDIR}/src/rust-harfbuzz/configure) || exit $?
(cd src/rust-mozjs && sh ${SRCDIR}/src/rust-mozjs/configure) || exit $?
Expand Down
2 changes: 1 addition & 1 deletion src/rust-mozjs
Submodule rust-mozjs updated 6 files
+1 −1 crust.rs
+3 −5 global.rs
+58 −11 js.rs
+510 −427 jsapi.rs
+4 −0 name_pool.rs
+58 −19 rust.rs
2 changes: 1 addition & 1 deletion src/rust-sdl
Submodule rust-sdl updated 3 files
+1 −1 sdl.rs
+2 −10 test.rs
+2 −2 video.rs
30 changes: 25 additions & 5 deletions src/servo/content.rs
Expand Up @@ -7,13 +7,14 @@ export Content;
export ControlMsg, ExecuteMsg, ParseMsg, ExitMsg;
export PingMsg, PongMsg;
export create_content;
export Document;

import comm::{port, chan, listen, select2};
import task::{spawn, spawn_listener};
import io::{read_whole_file, println};
import result::{ok, err};

import dom::base::{Node, NodeScope};
import dom::base::{Node, NodeScope, define_bindings};
import dom::event::{Event, ResizeEvent};
import dom::rcu::WriterMethods;
import dom::style;
Expand All @@ -31,6 +32,9 @@ import js::global::{global_class, debug_fns};
import either::{either, left, right};
import result::extensions;

import dom::bindings::utils::rust_box;
import js::rust::compartment;

type Content = chan<ControlMsg>;

enum ControlMsg {
Expand Down Expand Up @@ -75,7 +79,7 @@ class Content<S:Sink send copy> {
let scope: NodeScope;
let jsrt: jsrt;

let mut document: option<Document>;
let mut document: option<@Document>;

new(layout: Layout, sink: S, from_master: port<ControlMsg>) {
self.layout = layout;
Expand Down Expand Up @@ -116,15 +120,31 @@ class Content<S:Sink send copy> {
// Note: we can parse the next document in parallel
// with any previous documents.
let stream = spawn_html_lexer_task(copy filename);
let (root, style_port) = build_dom(self.scope, stream);
let (root, style_port, js_port) = build_dom(self.scope, stream);
let css_rules = style_port.recv();
let js_scripts = js_port.recv();

// Apply the css rules to the dom tree:
#debug["%?", css_rules];

#debug["%?", js_scripts];

let document = Document(root, css_rules);
self.relayout(document);
self.document = some(document);
self.document = some(@document);

//XXXjdm it was easier to duplicate the relevant ExecuteMsg code;
// they should be merged somehow in the future.
for vec::each(js_scripts) |bytes| {
let cx = self.jsrt.cx();
cx.set_default_options_and_version();
cx.set_logging_error_reporter();
cx.new_compartment(global_class).chain(|compartment| {
compartment.define_functions(debug_fns);
define_bindings(*compartment, option::get(self.document));
cx.evaluate_script(compartment.global_obj, bytes, ~"???", 1u)
});
}

ret true;
}
Expand Down Expand Up @@ -181,7 +201,7 @@ class Content<S:Sink send copy> {
// Nothing to do.
}
some(document) {
self.relayout(document);
self.relayout(*document);
}
}
ret true;
Expand Down
16 changes: 15 additions & 1 deletion src/servo/dom/base.rs
Expand Up @@ -5,6 +5,14 @@ import gfx::geometry::au;
import geom::size::Size2D;
import layout::base::LayoutData;
import util::tree;
import js::rust::{bare_compartment, compartment, methods};
import js::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, jsval, JSBool};
import js::{JSPROP_ENUMERATE, JSPROP_SHARED};
import js::crust::*;
import js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
import ptr::null;
import content::Document;
import bindings;

import dvec::{dvec, extensions};

Expand Down Expand Up @@ -52,11 +60,17 @@ class Attr {
}
}

fn define_bindings(compartment: bare_compartment, doc: @Document) {
//bindings::window::init(compartment);
bindings::document::init(compartment, doc);
}

enum ElementKind {
UnknownElement,
HTMLDivElement,
HTMLHeadElement,
HTMLImageElement({mut size: Size2D<au>})
HTMLImageElement({mut size: Size2D<au>}),
HTMLScriptElement
}

#[doc="
Expand Down
139 changes: 139 additions & 0 deletions src/servo/dom/bindings/document.rs
@@ -0,0 +1,139 @@
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};
import js::glue::bindgen::*;
import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
import js::ptr_methods;
import result::{result, ok, err};
import ptr::null;
import libc::c_uint;
import utils::{DOMString, domstring_to_jsval, rust_box, squirrel_away, str};
import bindings::node::create;
import content::Document;

enum DOMException {
INVALID_CHARACTER_ERR
}

enum Element = int;

/*extern fn getElementById(cx: *JSContext, argc: c_uint, vp: *jsval) -> JSBool {
//XXX check if actually document object
if argc != 1 {
//XXX throw proper DOM exception
str::as_c_str("Not enough arguments", |s| {
JS_ReportError(cx, s);
});
ret 0;
}
let id;
unsafe {
id = JS_ARGV(cx, vp)[0];
}
alt jsval_to_str(cx, id) {
ok(s) {
unsafe {
let doc: *Document = unsafe::reinterpret_cast(JS_GetContextPrivate(cx));
let elem = (*doc).getElementById(s);
}
//XXX wrap result
ret 1;
}
err(_) {
str::as_c_str("???", |s| {
JS_ReportError(cx, s);
});
ret 0;
}
}
}*/

/*extern fn getDocumentURI(cx: *JSContext, _argc: c_uint, vp: *jsval) -> JSBool {
unsafe {
let uri = (*unwrap(JS_THIS_OBJECT(cx, vp))).payload.getDocumentURI();
JS_SET_RVAL(cx, vp, domstring_to_jsval(cx, uri));
}
ret 1;
}*/

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);
ret 1;
}

unsafe fn unwrap(obj: *JSObject) -> *rust_box<Document> {
let val = JS_GetReservedSlot(obj, 0);
unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val))
}

extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
#debug("document finalize!");
unsafe {
let val = JS_GetReservedSlot(obj, 0);
let _doc: @Document = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val));
}
}

fn init(compartment: bare_compartment, doc: @Document) {
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: 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
};

let obj = result::unwrap(
compartment.new_object(Document_class, null(), null()));
/*let methods = ~[
{name: compartment.add_name("getDocumentURI"),
call: getDocumentURI,
nargs: 0,
flags: 0}];
vec::as_buf(methods, |fns| {
JS_DefineFunctions(compartment.cx.ptr, obj.ptr, fns);
});*/

let attrs = @~[
{name: compartment.add_name(~"documentElement"),
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(doc));
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
}

compartment.define_property(~"document", RUST_OBJECT_TO_JSVAL(obj.ptr),
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE);
}

0 comments on commit 4a1c8cc

Please sign in to comment.