aboutsummaryrefslogtreecommitdiffstats
path: root/src/servo/dom/bindings/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/servo/dom/bindings/utils.rs')
-rw-r--r--src/servo/dom/bindings/utils.rs139
1 files changed, 102 insertions, 37 deletions
diff --git a/src/servo/dom/bindings/utils.rs b/src/servo/dom/bindings/utils.rs
index c2cbd671483..47dafe5e6db 100644
--- a/src/servo/dom/bindings/utils.rs
+++ b/src/servo/dom/bindings/utils.rs
@@ -18,7 +18,7 @@ use js::jsapi::bindgen::{JS_ValueToString,
JS_DefineProperties,
JS_WrapValue, JS_ForwardGetPropertyTo,
JS_HasPropertyById, JS_GetPrototype, JS_GetGlobalForObject,
- JS_EncodeString, JS_free};
+ JS_EncodeString, JS_free, JS_GetStringCharsAndLength};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
use js::glue::bindgen::{DefineFunctionWithReserved, GetObjectJSClass, RUST_OBJECT_TO_JSVAL};
use js::glue::{PROPERTY_STUB, STRICT_PROPERTY_STUB, ENUMERATE_STUB, CONVERT_STUB,
@@ -30,7 +30,9 @@ use content::content_task::task_from_context;
use core::hashmap::HashMap;
+use dom::bindings::document;
use dom::bindings::node;
+use dom::document::Document;
use dom::node::AbstractNode;
static TOSTRING_CLASS_RESERVED_SLOT: u64 = 0;
@@ -356,6 +358,7 @@ pub mod prototypes {
pub enum Prototype {
ClientRect,
ClientRectList,
+ DOMParser,
HTMLCollection,
_ID_Count
}
@@ -540,7 +543,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) ->
}
pub fn initialize_global(global: *JSObject) {
- let protoArray = @mut ([0 as *JSObject, ..3]); //XXXjdm prototypes::_ID_COUNT
+ let protoArray = @mut ([0 as *JSObject, ..4]); //XXXjdm prototypes::_ID_COUNT
unsafe {
//XXXjdm we should be storing the box pointer instead of the inner
let box = squirrel_away(protoArray);
@@ -554,7 +557,7 @@ pub fn initialize_global(global: *JSObject) {
pub trait CacheableWrapper {
fn get_wrappercache(&mut self) -> &mut WrapperCache;
fn wrap_object_unique(~self, cx: *JSContext, scope: *JSObject) -> *JSObject;
- fn wrap_object_shared(@self, cx: *JSContext, scope: *JSObject) -> *JSObject;
+ fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject;
}
pub struct WrapperCache {
@@ -577,64 +580,48 @@ pub impl WrapperCache {
}
}
-pub fn WrapNewBindingObject<T: CacheableWrapper>(cx: *JSContext, scope: *JSObject,
- mut value: ~T, vp: *mut JSVal) -> bool {
+pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
+ mut value: @mut CacheableWrapper,
+ vp: *mut JSVal) -> bool {
unsafe {
- let obj = value.get_wrappercache().get_wrapper();
+ let mut cache = value.get_wrappercache();
+ let mut obj = cache.get_wrapper();
if obj.is_not_null() /*&& js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)*/ {
*vp = RUST_OBJECT_TO_JSVAL(obj);
return true;
}
- let obj = if obj.is_not_null() {
- obj
- } else {
- value.wrap_object_unique(cx, scope)
- };
-
+ let obj = value.wrap_object_shared(cx, scope);
if obj.is_null() {
return false;
}
// MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
+ cache.set_wrapper(obj);
*vp = RUST_OBJECT_TO_JSVAL(obj);
return JS_WrapValue(cx, cast::transmute(vp)) != 0;
}
}
-pub struct OpaqueBindingReference(Either<~CacheableWrapper, @CacheableWrapper>);
-
-pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, p: &mut OpaqueBindingReference) -> *JSObject {
- match p {
- &OpaqueBindingReference(Left(ref mut p)) => {
- let cache = p.get_wrappercache();
- let obj = cache.get_wrapper();
- if obj.is_not_null() {
- return obj;
- }
- let mut tmp: ~CacheableWrapper = unstable::intrinsics::init();
- tmp <-> *p;
- tmp.wrap_object_unique(cx, scope)
- }
- &OpaqueBindingReference(Right(ref mut p)) => {
- let cache = p.get_wrappercache();
- let obj = cache.get_wrapper();
- if obj.is_not_null() {
- return obj;
- }
- p.wrap_object_shared(cx, scope)
- }
+pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: @mut CacheableWrapper) -> *JSObject {
+ let cache = p.get_wrappercache();
+ let wrapper = cache.get_wrapper();
+ if wrapper.is_not_null() {
+ return wrapper;
}
+ let wrapper = p.wrap_object_shared(cx, scope);
+ cache.set_wrapper(wrapper);
+ wrapper
}
pub struct BindingReference<T>(Either<~T, @mut T>);
pub trait BindingObject {
- fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference;
+ fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper;
}
pub impl<T: BindingObject + CacheableWrapper> BindingReference<T> {
- fn GetParentObject(&self, cx: *JSContext) -> OpaqueBindingReference {
+ fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper {
match **self {
Left(ref obj) => obj.GetParentObject(cx),
Right(ref obj) => obj.GetParentObject(cx)
@@ -781,6 +768,7 @@ pub fn InitIds(cx: *JSContext, specs: &[JSPropertySpec], ids: &mut [jsid]) -> bo
pub trait DerivedWrapper {
fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32;
+ fn wrap_shared(@mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32;
}
impl DerivedWrapper for AbstractNode {
@@ -794,10 +782,87 @@ impl DerivedWrapper for AbstractNode {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(node::create(cx, self).ptr) };
return 1;
}
+
+ fn wrap_shared(@mut self, _cx: *JSContext, _scope: *JSObject, _vp: *mut JSVal) -> i32 {
+ fail!(~"nyi")
+ }
+}
+
+/*impl DerivedWrapper for Document {
+ fn wrap(&mut self, cx: *JSContext, scope: *JSObject, vp: *mut JSVal) -> i32 {
+ let cache = self.get_wrappercache();
+ let wrapper = cache.get_wrapper();
+ if wrapper.is_not_null() {
+ unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
+ return 1;
+ }
+ let content = task_from_context(cx);
+ unsafe {
+ let compartment = (*content).compartment.get();
+ *vp = RUST_OBJECT_TO_JSVAL(document::create(compartment, self));
+ }
+ return 1;
+ }
+}*/
+
+pub impl Document {
+ fn wrap(@mut self, cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
+ let cache = self.get_wrappercache();
+ let wrapper = cache.get_wrapper();
+ if wrapper.is_not_null() {
+ unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
+ return 1;
+ }
+ let content = task_from_context(cx);
+ unsafe {
+ let compartment = (*content).compartment.get();
+ *vp = RUST_OBJECT_TO_JSVAL(document::create(compartment, self));
+ }
+ return 1;
+ }
}
pub enum Error {
FailureUnknown
}
-pub type ErrorResult = Result<(), Error>; \ No newline at end of file
+pub type ErrorResult = Result<(), Error>;
+
+pub struct EnumEntry {
+ value: &'static str,
+ length: uint
+}
+
+pub fn FindEnumStringIndex(cx: *JSContext,
+ v: JSVal,
+ values: &[EnumEntry]) -> Result<uint, ()> {
+ unsafe {
+ let jsstr = JS_ValueToString(cx, v);
+ if jsstr.is_null() {
+ return Err(());
+ }
+ let length = 0;
+ let chars = JS_GetStringCharsAndLength(cx, jsstr, ptr::to_unsafe_ptr(&length));
+ if chars.is_null() {
+ return Err(());
+ }
+ for values.eachi |i, value| {
+ if value.length != length as uint {
+ loop;
+ }
+ let mut equal = true;
+ for uint::iterate(0, length as uint) |j| {
+ if value.value[j] as u16 != *chars.offset(j) {
+ equal = false;
+ break;
+ }
+ };
+
+ if equal {
+ return Ok(i);
+ }
+ }
+
+ return Err(()); //XXX pass in behaviour for value not found
+ }
+}