aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/callback.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2013-11-01 10:19:45 -0400
committerJosh Matthews <josh@joshmatthews.net>2013-11-05 12:58:28 -0500
commit7ecf5abbbdf0d75a1e794cde6ac71fe982468414 (patch)
treecd228a9204ecc7b8d4ae52f66638a19e63f08c29 /src/components/script/dom/bindings/callback.rs
parent06b1db8818c09201989b017434eef105f4d99e51 (diff)
downloadservo-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.rs105
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
+ }
+}