diff options
author | Josh Matthews <josh@joshmatthews.net> | 2013-11-01 10:19:45 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2013-11-05 12:58:28 -0500 |
commit | 7ecf5abbbdf0d75a1e794cde6ac71fe982468414 (patch) | |
tree | cd228a9204ecc7b8d4ae52f66638a19e63f08c29 /src/components/script/dom/bindings/callback.rs | |
parent | 06b1db8818c09201989b017434eef105f4d99e51 (diff) | |
download | servo-7ecf5abbbdf0d75a1e794cde6ac71fe982468414.tar.gz servo-7ecf5abbbdf0d75a1e794cde6ac71fe982468414.zip |
Generate code for handling callbacks. Implement add/removeEventListener and hacky dispatchEvent proof-of-concept.
Diffstat (limited to 'src/components/script/dom/bindings/callback.rs')
-rw-r--r-- | src/components/script/dom/bindings/callback.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/components/script/dom/bindings/callback.rs b/src/components/script/dom/bindings/callback.rs new file mode 100644 index 00000000000..6cf88b353ed --- /dev/null +++ b/src/components/script/dom/bindings/callback.rs @@ -0,0 +1,105 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use dom::bindings::utils::{WrapNativeParent, Reflectable}; +use js::jsapi::{JSContext, JSObject, JS_WrapObject, JSVal, JS_ObjectIsCallable}; +use js::jsapi::JS_GetProperty; +use js::{JSVAL_IS_OBJECT, JSVAL_TO_OBJECT}; + +use std::libc; +use std::ptr; + +pub enum ExceptionHandling { + // Report any exception and don't throw it to the caller code. + eReportExceptions, + // Throw an exception to the caller code if the thrown exception is a + // binding object for a DOMError from the caller's scope, otherwise report + // it. + eRethrowContentExceptions, + // Throw any exception to the caller code. + eRethrowExceptions +} + +#[deriving(Clone,Eq)] +pub struct CallbackInterface { + callback: *JSObject +} + +pub trait CallbackContainer { + fn callback(&self) -> *JSObject; +} + +impl CallbackContainer for CallbackInterface { + fn callback(&self) -> *JSObject { + self.callback + } +} + +impl CallbackInterface { + pub fn new(callback: *JSObject) -> CallbackInterface { + CallbackInterface { + callback: callback + } + } + + #[fixed_stack_segment] + pub fn GetCallableProperty(&self, cx: *JSContext, name: *libc::c_char, callable: &mut JSVal) -> bool { + unsafe { + if JS_GetProperty(cx, self.callback, name, &*callable) == 0 { + return false; + } + + if !JSVAL_IS_OBJECT(*callable) || + JS_ObjectIsCallable(cx, JSVAL_TO_OBJECT(*callable)) == 0 { + //ThrowErrorMessage(cx, MSG_NOT_CALLABLE, description.get()); + return false; + } + + return true; + } + } +} + +pub fn GetJSObjectFromCallback<T: CallbackContainer>(callback: &T) -> *JSObject { + callback.callback() +} + +#[fixed_stack_segment] +pub fn WrapCallThisObject<T: 'static + CallbackContainer + Reflectable>(cx: *JSContext, + scope: *JSObject, + p: @mut T) -> *JSObject { + let mut obj = GetJSObjectFromCallback(p); + if obj.is_null() { + obj = WrapNativeParent(cx, scope, Some(p as @mut Reflectable)); + if obj.is_null() { + return ptr::null(); + } + } + + unsafe { + if JS_WrapObject(cx, &obj) == 0 { + return ptr::null(); + } + } + + return obj; +} + +pub struct CallSetup { + cx: *JSContext, + handling: ExceptionHandling +} + +impl CallSetup { + pub fn new(cx: *JSContext, handling: ExceptionHandling) -> CallSetup { + CallSetup { + cx: cx, + handling: handling + } + } + + pub fn GetContext(&self) -> *JSContext { + self.cx + } +} |