mirror of
https://github.com/servo/servo.git
synced 2025-06-21 07:38:59 +01:00
Implement JSManaged for DOM objects.
This commit is contained in:
parent
061269f963
commit
625325434b
137 changed files with 3644 additions and 2778 deletions
|
@ -4,11 +4,13 @@
|
|||
|
||||
use dom::bindings::codegen::PrototypeList;
|
||||
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
||||
use dom::bindings::js::JS;
|
||||
use dom::window;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
use std::libc::c_uint;
|
||||
use std::cast;
|
||||
use std::cmp::Eq;
|
||||
use std::hashmap::HashMap;
|
||||
use std::libc;
|
||||
use std::ptr;
|
||||
|
@ -32,7 +34,7 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative, JSTracer};
|
|||
use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
|
||||
use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
|
||||
use js::jsapi::{JSString, JS_CallTracer, JSTRACE_OBJECT};
|
||||
use js::jsapi::{JS_IsExceptionPending};
|
||||
use js::jsapi::{JS_IsExceptionPending, JS_AllowGC, JS_InhibitGC};
|
||||
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
||||
use js::{JSPROP_ENUMERATE, JSVAL_NULL, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
||||
use js::{JSPROP_PERMANENT, JSID_VOID, JSPROP_NATIVE_ACCESSORS, JSPROP_GETTER};
|
||||
|
@ -174,6 +176,17 @@ pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_d
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject,
|
||||
proto_id: PrototypeList::id::ID,
|
||||
proto_depth: uint) -> Result<JS<T>, ()> {
|
||||
let result: Result<*mut Box<T>, ()> = unwrap_object(obj, proto_id, proto_depth);
|
||||
result.map(|unwrapped| {
|
||||
unsafe {
|
||||
JS::from_box(unwrapped)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
|
||||
unsafe {
|
||||
let obj = RUST_JSVAL_TO_OBJECT(*val);
|
||||
|
@ -182,8 +195,11 @@ pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth
|
|||
}
|
||||
|
||||
pub unsafe fn squirrel_away<T>(x: @mut T) -> *Box<T> {
|
||||
let y: *Box<T> = cast::transmute(x);
|
||||
y
|
||||
cast::transmute(x)
|
||||
}
|
||||
|
||||
pub unsafe fn squirrel_away_unique<T>(x: ~T) -> *Box<T> {
|
||||
cast::transmute(x)
|
||||
}
|
||||
|
||||
pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString {
|
||||
|
@ -557,10 +573,6 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trace_option<T: Reflectable>(tracer: *mut JSTracer, description: &str, option: Option<@mut T>) {
|
||||
option.map(|some| trace_reflector(tracer, description, some.reflector()));
|
||||
}
|
||||
|
||||
pub fn initialize_global(global: *JSObject) {
|
||||
let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]);
|
||||
unsafe {
|
||||
|
@ -579,21 +591,17 @@ pub trait Reflectable {
|
|||
}
|
||||
|
||||
pub fn reflect_dom_object<T: Reflectable>
|
||||
(obj: @mut T,
|
||||
(obj: ~T,
|
||||
window: &window::Window,
|
||||
wrap_fn: extern "Rust" fn(*JSContext, *JSObject, @mut T) -> *JSObject)
|
||||
-> @mut T {
|
||||
let cx = window.get_cx();
|
||||
let scope = window.reflector().get_jsobject();
|
||||
if wrap_fn(cx, scope, obj).is_null() {
|
||||
fail!("Could not eagerly wrap object");
|
||||
}
|
||||
assert!(obj.reflector().get_jsobject().is_not_null());
|
||||
obj
|
||||
wrap_fn: extern "Rust" fn(*JSContext, *JSObject, ~T) -> *JSObject)
|
||||
-> JS<T> {
|
||||
JS::new(obj, window, wrap_fn)
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct Reflector {
|
||||
object: *JSObject
|
||||
object: *JSObject,
|
||||
force_box_layout: @int,
|
||||
}
|
||||
|
||||
impl Reflector {
|
||||
|
@ -610,7 +618,8 @@ impl Reflector {
|
|||
|
||||
pub fn new() -> Reflector {
|
||||
Reflector {
|
||||
object: ptr::null()
|
||||
object: ptr::null(),
|
||||
force_box_layout: @1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -849,11 +858,11 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
|
|||
}
|
||||
|
||||
/// Returns the global object of the realm that the given DOM object was created in.
|
||||
pub fn global_object_for_dom_object<T: Reflectable>(obj: &mut T) -> *Box<window::Window> {
|
||||
pub fn global_object_for_dom_object<T: Reflectable>(obj: &T) -> *Box<window::Window> {
|
||||
global_object_for_js_object(obj.reflector().get_jsobject())
|
||||
}
|
||||
|
||||
pub fn cx_for_dom_object<T: Reflectable>(obj: &mut T) -> *JSContext {
|
||||
pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext {
|
||||
cx_for_dom_reflector(obj.reflector().get_jsobject())
|
||||
}
|
||||
|
||||
|
@ -870,6 +879,26 @@ pub fn throw_method_failed_with_details<T>(cx: *JSContext,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// Execute arbitrary code with the JS GC enabled, then disable it afterwards.
|
||||
pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R {
|
||||
unsafe {
|
||||
JS_AllowGC(cx);
|
||||
let rv = f();
|
||||
JS_InhibitGC(cx);
|
||||
rv
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute arbitrary code with the JS GC disabled, then enable it afterwards.
|
||||
pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R {
|
||||
unsafe {
|
||||
JS_InhibitGC(cx);
|
||||
let rv = f();
|
||||
JS_AllowGC(cx);
|
||||
rv
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name
|
||||
/// for details.
|
||||
#[deriving(Eq)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue