aboutsummaryrefslogtreecommitdiffstats
path: root/src/servo
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2012-07-12 19:12:20 -0400
committerJosh Matthews <josh@joshmatthews.net>2012-07-24 19:31:25 -0400
commit4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01 (patch)
tree8dc4c289a74d3b0da532ae901a32a53b8938e23b /src/servo
parent82790f2bb1f275a8f0d86257357281aaa4506db4 (diff)
downloadservo-4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01.tar.gz
servo-4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01.zip
Add primitive binding example for Document (documentElement), and Node (firstChild, nextSibling, tagName).
Diffstat (limited to 'src/servo')
-rw-r--r--src/servo/content.rs30
-rw-r--r--src/servo/dom/base.rs16
-rw-r--r--src/servo/dom/bindings/document.rs139
-rw-r--r--src/servo/dom/bindings/node.rs143
-rw-r--r--src/servo/dom/bindings/utils.rs77
-rw-r--r--src/servo/parser/html_builder.rs69
-rwxr-xr-xsrc/servo/servo.rc5
-rw-r--r--src/servo/text/font.rs8
-rw-r--r--src/servo/text/native_font/quartz_native_font.rs4
-rw-r--r--src/servo/text/shaper.rs4
10 files changed, 476 insertions, 19 deletions
diff --git a/src/servo/content.rs b/src/servo/content.rs
index 72200e804da..82e163c15b8 100644
--- a/src/servo/content.rs
+++ b/src/servo/content.rs
@@ -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;
@@ -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 {
@@ -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;
@@ -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;
}
@@ -181,7 +201,7 @@ class Content<S:Sink send copy> {
// Nothing to do.
}
some(document) {
- self.relayout(document);
+ self.relayout(*document);
}
}
ret true;
diff --git a/src/servo/dom/base.rs b/src/servo/dom/base.rs
index b5955e87672..36fe1f8501a 100644
--- a/src/servo/dom/base.rs
+++ b/src/servo/dom/base.rs
@@ -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};
@@ -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="
diff --git a/src/servo/dom/bindings/document.rs b/src/servo/dom/bindings/document.rs
new file mode 100644
index 00000000000..5f8d91d3f89
--- /dev/null
+++ b/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);
+}
diff --git a/src/servo/dom/bindings/node.rs b/src/servo/dom/bindings/node.rs
new file mode 100644
index 00000000000..7c5d705b329
--- /dev/null
+++ b/src/servo/dom/bindings/node.rs
@@ -0,0 +1,143 @@
+import js::rust::{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, JSPropertySpec};
+import js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
+ JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
+ JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate};
+import js::jsapi::bindgen::*;
+import js::glue::bindgen::*;
+import js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
+
+import dom::base::{Node, Element};
+import utils::{rust_box, squirrel_away_unique, get_compartment, domstring_to_jsval, str};
+import libc::c_uint;
+import ptr::null;
+import rcu::ReaderMethods;
+
+extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
+ #debug("node finalize!");
+ unsafe {
+ let val = JS_GetReservedSlot(obj, 0);
+ let _node: ~Node = unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val));
+ }
+}
+
+fn create(cx: *JSContext, node: Node) -> jsobj unsafe {
+ let compartment = get_compartment(cx);
+ fn Node_class(compartment: bare_compartment) -> JSClass {
+ {name: compartment.add_name(~"Node"),
+ flags: JSCLASS_HAS_RESERVED_SLOTS(1),
+ addProperty: JS_PropertyStub,
+ delProperty: JS_PropertyStub,
+ getProperty: JS_PropertyStub,
+ setProperty: JS_StrictPropertyStub,
+ enumerate: JS_EnumerateStub,
+ resolve: JS_PropertyStub,
+ 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(Node_class, null(),
+ (*compartment).global_obj.ptr));
+ let attrs = @~[
+ {name: (*compartment).add_name(~"firstChild"),
+ tinyid: 0,
+ flags: 0,
+ getter: getFirstChild,
+ setter: null()},
+
+ {name: (*compartment).add_name(~"nextSibling"),
+ tinyid: 0,
+ flags: 0,
+ getter: getNextSibling,
+ setter: null()},
+
+ {name: (*compartment).add_name(~"tagName"),
+ tinyid: 0,
+ flags: 0,
+ getter: getTagName,
+ 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_unique(~node));
+ JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
+ }
+
+ ret obj;
+}
+
+unsafe fn unwrap(obj: *JSObject) -> *rust_box<Node> {
+ let val = JS_GetReservedSlot(obj, 0);
+ unsafe::reinterpret_cast(RUST_JSVAL_TO_PRIVATE(val))
+}
+
+extern fn getFirstChild(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool {
+ unsafe {
+ (*unwrap(obj)).payload.read(|nd| {
+ alt nd.tree.first_child {
+ some(n) {
+ let obj = create(cx, n).ptr;
+ *rval = RUST_OBJECT_TO_JSVAL(obj);
+ }
+ none {
+ *rval = JSVAL_NULL;
+ }
+ }
+ });
+ }
+ ret 1;
+}
+
+extern fn getNextSibling(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool {
+ unsafe {
+ (*unwrap(obj)).payload.read(|nd| {
+ alt nd.tree.next_sibling {
+ some(n) {
+ let obj = create(cx, n).ptr;
+ *rval = RUST_OBJECT_TO_JSVAL(obj);
+ }
+ none {
+ *rval = JSVAL_NULL;
+ }
+ }
+ });
+ }
+ ret 1;
+}
+
+extern fn getTagName(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval) -> JSBool {
+ unsafe {
+ (*unwrap(obj)).payload.read(|nd| {
+ alt nd.kind {
+ ~Element(ed) {
+ let s = str(ed.tag_name);
+ *rval = domstring_to_jsval(cx, s);
+ }
+ _ {
+ //XXXjdm should probably read the spec to figure out what to do here
+ *rval = JSVAL_NULL;
+ }
+ }
+ });
+ }
+ ret 1;
+}
diff --git a/src/servo/dom/bindings/utils.rs b/src/servo/dom/bindings/utils.rs
new file mode 100644
index 00000000000..00b49f90ee0
--- /dev/null
+++ b/src/servo/dom/bindings/utils.rs
@@ -0,0 +1,77 @@
+import js::rust::{compartment, bare_compartment};
+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_GetContextPrivate};
+import js::glue::bindgen::*;
+import result::{result, ok, err};
+
+enum DOMString {
+ str(~str),
+ null_string
+}
+
+type rust_box<T> = {rc: uint, td: *sys::type_desc, next: *(), prev: *(), payload: T};
+
+unsafe fn squirrel_away<T>(+x: @T) -> *rust_box<T> {
+ let y: *rust_box<T> = unsafe::reinterpret_cast(x);
+ unsafe::forget(x);
+ y
+}
+
+type rust_unique<T> = {payload: T};
+
+unsafe fn squirrel_away_unique<T>(+x: ~T) -> *rust_box<T> {
+ let y: *rust_box<T> = unsafe::reinterpret_cast(x);
+ unsafe::forget(x);
+ y
+}
+
+//XXX very incomplete
+fn jsval_to_str(cx: *JSContext, v: jsval) -> result<~str, ()> {
+ let jsstr;
+ if RUST_JSVAL_IS_STRING(v) == 1 {
+ jsstr = RUST_JSVAL_TO_STRING(v)
+ } else {
+ jsstr = JS_ValueToString(cx, v);
+ if jsstr.is_null() {
+ ret err(());
+ }
+ }
+
+ let len = 0;
+ let chars = JS_GetStringCharsZAndLength(cx, jsstr, ptr::addr_of(len));
+ ret if chars.is_null() {
+ err(())
+ } else {
+ unsafe {
+ let buf = vec::unsafe::from_buf(chars as *u8, len as uint);
+ ok(str::from_bytes(buf))
+ }
+ }
+}
+
+unsafe fn domstring_to_jsval(cx: *JSContext, str: DOMString) -> jsval {
+ alt str {
+ null_string {
+ JSVAL_NULL
+ }
+ str(s) {
+ str::as_buf(s, |buf, len| {
+ let cbuf = unsafe::reinterpret_cast(buf);
+ RUST_STRING_TO_JSVAL(JS_NewStringCopyN(cx, cbuf, len as libc::size_t))
+ })
+ }
+ }
+}
+
+fn get_compartment(cx: *JSContext) -> *bare_compartment {
+ unsafe {
+ let priv: *libc::c_void = JS_GetContextPrivate(cx);
+ let compartment: *bare_compartment = unsafe::reinterpret_cast(priv);
+ assert cx == (*compartment).cx.ptr;
+ compartment
+ }
+}
diff --git a/src/servo/parser/html_builder.rs b/src/servo/parser/html_builder.rs
index c96bc17f593..189952ccde6 100644
--- a/src/servo/parser/html_builder.rs
+++ b/src/servo/parser/html_builder.rs
@@ -1,6 +1,7 @@
#[doc="Constructs a DOM tree from an incoming token stream."]
-import dom::base::{Attr, Element, ElementData, ElementKind, HTMLDivElement, HTMLHeadElement};
+import dom::base::{Attr, Element, ElementData, ElementKind, HTMLDivElement, HTMLHeadElement,
+ HTMLScriptElement};
import dom::base::{HTMLImageElement, Node, NodeScope, Text, TreeReadMethods, TreeWriteMethods};
import dom::base::{UnknownElement};
import dom::rcu::WriterMethods;
@@ -19,6 +20,11 @@ enum CSSMessage {
Exit
}
+enum js_message {
+ js_file(~str),
+ js_exit
+}
+
#[warn(no_non_implicitly_copyable_typarams)]
fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
// TODO: Implement atoms so that we don't always perform string comparisons.
@@ -45,7 +51,8 @@ fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
}
}
}
- HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement | UnknownElement {
+ HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement |
+ HTMLScriptElement | UnknownElement {
// Drop on the floor.
}
}
@@ -67,6 +74,7 @@ fn build_element_kind(tag_name: ~str) -> ~ElementKind {
geometry::px_to_au(100))
})
}
+ ~"script" { ~HTMLScriptElement }
~"head" { ~HTMLHeadElement }
_ { ~UnknownElement }
}
@@ -116,8 +124,38 @@ fn css_link_listener(to_parent : chan<Stylesheet>, from_parent : port<CSSMessage
to_parent.send(css_rules);
}
+fn js_script_listener(to_parent : chan<~[~[u8]]>, from_parent : port<js_message>) {
+ let mut result_vec = ~[];
+
+ loop {
+ alt from_parent.recv() {
+ js_file(filename) {
+ let result_port = comm::port();
+ let result_chan = comm::chan(result_port);
+ let filename = copy filename;
+ do task::spawn {
+ let filename <- copy filename;
+ let file_try = io::read_whole_file(filename);
+ if (file_try.is_ok()) {
+ result_chan.send(file_try.get());
+ } else {
+ #error("error loading script %s", filename);
+ }
+ }
+ push(result_vec, result_port);
+ }
+ js_exit {
+ break;
+ }
+ }
+ }
+
+ let js_scripts = vec::map(result_vec, |result_port| result_port.recv());
+ to_parent.send(js_scripts);
+}
+
#[warn(no_non_implicitly_copyable_typarams)]
-fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>) {
+fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>, port<~[~[u8]]>) {
// The current reference node.
let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
// We will spawn a separate task to parse any css that is
@@ -131,6 +169,12 @@ fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>)
css_link_listener(child_chan, child_port);
});
+ let js_port = comm::port();
+ let child_chan = comm::chan(js_port);
+ let js_chan = task::spawn_listener(|child_port| {
+ js_script_listener(child_chan, child_port);
+ });
+
loop {
let token = stream.recv();
alt token {
@@ -174,8 +218,22 @@ fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>)
});
cur_node = scope.get_parent(cur_node).get();
}
- parser::EndTag(_) {
+ parser::EndTag(tag_name) {
// TODO: Assert that the closing tag has the right name.
+ scope.read(cur_node, |n| {
+ alt *n.kind {
+ Element(elmt) if elmt.tag_name == ~"script" {
+ alt elmt.get_attr(~"src") {
+ some(filename) {
+ #debug["Linking to a js script named: %s", filename];
+ js_chan.send(js_file(copy filename));
+ }
+ none { /* fall through */ }
+ }
+ }
+ _ { /* fall though */ }
+ }
+ });
cur_node = scope.get_parent(cur_node).get();
}
parser::Text(s) if !s.is_whitespace() {
@@ -192,6 +250,7 @@ fn build_dom(scope: NodeScope, stream: port<Token>) -> (Node, port<Stylesheet>)
}
style_chan.send(Exit);
+ js_chan.send(js_exit);
- ret (cur_node, style_port);
+ ret (cur_node, style_port, js_port);
}
diff --git a/src/servo/servo.rc b/src/servo/servo.rc
index 223bf9b7ccf..144cf894297 100755
--- a/src/servo/servo.rc
+++ b/src/servo/servo.rc
@@ -22,6 +22,11 @@ mod dom {
mod event;
mod rcu;
mod style;
+ mod bindings {
+ mod document;
+ mod utils;
+ mod node;
+ }
}
mod gfx {
diff --git a/src/servo/text/font.rs b/src/servo/text/font.rs
index 53dd1879fd1..e0304041c93 100644
--- a/src/servo/text/font.rs
+++ b/src/servo/text/font.rs
@@ -200,8 +200,8 @@ fn get_cairo_face(buf: &~[u8]) -> (*cairo_font_face_t, fn@()) {
dtor = fn@(move dtor) { FT_Done_FreeType(library).for_sure(); dtor() };
let face: FT_Face = null();
- vec::as_buf(*buf, |cbuf| {
- if FT_New_Memory_Face(library, cbuf, (*buf).len() as FT_Long,
+ vec::as_buf(*buf, |cbuf, len| {
+ if FT_New_Memory_Face(library, cbuf, len as FT_Long,
0 as FT_Long, addr_of(face)).failed() {
dtor();
fail ~"unable to create FreeType face";
@@ -241,11 +241,11 @@ fn get_cairo_face(buf: &~[u8]) -> (*cairo_font_face_t, fn@()) {
let mut dtor = fn@() { };
- let fontprov = vec::as_buf(*buf, |cbuf| {
+ let fontprov = vec::as_buf(*buf, |cbuf, len| {
CGDataProviderCreateWithData(
null(),
unsafe { reinterpret_cast(cbuf) },
- (*buf).len() as size_t,
+ len as size_t,
null()
)
});
diff --git a/src/servo/text/native_font/quartz_native_font.rs b/src/servo/text/native_font/quartz_native_font.rs
index 4f80e413151..a4adf5eb6bb 100644
--- a/src/servo/text/native_font/quartz_native_font.rs
+++ b/src/servo/text/native_font/quartz_native_font.rs
@@ -49,11 +49,11 @@ class QuartzNativeFont/& {
}
fn create(buf: ~[u8]) -> result<QuartzNativeFont, ()> {
- let fontprov = vec::as_buf(buf, |cbuf| {
+ let fontprov = vec::as_buf(buf, |cbuf, len| {
CGDataProviderCreateWithData(
null(),
unsafe { reinterpret_cast(cbuf) },
- buf.len() as size_t,
+ len as size_t,
null())
});
// FIXME: Error handling
diff --git a/src/servo/text/shaper.rs b/src/servo/text/shaper.rs
index 5a2bd426df9..72277b4e9e2 100644
--- a/src/servo/text/shaper.rs
+++ b/src/servo/text/shaper.rs
@@ -38,9 +38,9 @@ when rendered in a specific font.
fn shape_text(font: &Font, text: ~str) -> ~[Glyph] unsafe {
#debug("shaping text '%s'", text);
- let face_blob = vec::as_buf(*(*font).buf(), |buf| {
+ let face_blob = vec::as_buf(*(*font).buf(), |buf, len| {
hb_blob_create(reinterpret_cast(buf),
- (*(*font).buf()).len() as c_uint,
+ len as c_uint,
HB_MEMORY_MODE_READONLY,
null(),
null())