diff options
author | Josh Matthews <josh@joshmatthews.net> | 2012-07-12 19:12:20 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2012-07-24 19:31:25 -0400 |
commit | 4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01 (patch) | |
tree | 8dc4c289a74d3b0da532ae901a32a53b8938e23b /src/servo/dom/bindings/node.rs | |
parent | 82790f2bb1f275a8f0d86257357281aaa4506db4 (diff) | |
download | servo-4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01.tar.gz servo-4a1c8cc2ec2bf7ca1197a5404ef94e1509981c01.zip |
Add primitive binding example for Document (documentElement), and Node (firstChild, nextSibling, tagName).
Diffstat (limited to 'src/servo/dom/bindings/node.rs')
-rw-r--r-- | src/servo/dom/bindings/node.rs | 143 |
1 files changed, 143 insertions, 0 deletions
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; +} |