aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_bindings/conversions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script_bindings/conversions.rs')
-rw-r--r--components/script_bindings/conversions.rs52
1 files changed, 49 insertions, 3 deletions
diff --git a/components/script_bindings/conversions.rs b/components/script_bindings/conversions.rs
index c9f67605c5a..ec05d0c33f8 100644
--- a/components/script_bindings/conversions.rs
+++ b/components/script_bindings/conversions.rs
@@ -8,16 +8,30 @@ use js::conversions::{
latin1_to_string, ConversionResult, FromJSValConvertible, ToJSValConvertible,
};
use js::error::throw_type_error;
+use js::glue::{GetProxyHandlerExtra, IsProxyHandlerFamily};
use js::jsapi::{
- JSContext, JSString, JS_DeprecatedStringHasLatin1Chars, JS_GetLatin1StringCharsAndLength,
- JS_GetTwoByteStringCharsAndLength, JS_NewStringCopyN,
+ JSContext, JSObject, JSString, JS_DeprecatedStringHasLatin1Chars,
+ JS_GetLatin1StringCharsAndLength, JS_GetTwoByteStringCharsAndLength, JS_NewStringCopyN,
};
use js::jsval::{ObjectValue, StringValue};
-use js::rust::{maybe_wrap_value, HandleValue, MutableHandleValue, ToString};
+use js::rust::{
+ get_object_class, is_dom_class, maybe_wrap_value, HandleValue, MutableHandleValue, ToString,
+};
use servo_config::opts;
+use crate::inheritance::Castable;
use crate::reflector::Reflector;
use crate::str::{ByteString, DOMString, USVString};
+use crate::utils::{DOMClass, DOMJSClass};
+
+/// A trait to check whether a given `JSObject` implements an IDL interface.
+pub trait IDLInterface {
+ /// Returns whether the given DOM class derives that interface.
+ fn derives(_: &'static DOMClass) -> bool;
+}
+
+/// A trait to mark an IDL interface as deriving from another one.
+pub trait DerivedFrom<T: Castable>: Castable {}
// http://heycam.github.io/webidl/#es-USVString
impl ToJSValConvertible for USVString {
@@ -201,3 +215,35 @@ impl ToJSValConvertible for Reflector {
maybe_wrap_value(cx, rval);
}
}
+
+/// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object.
+///
+/// # Safety
+/// obj must point to a valid, non-null JS object.
+#[allow(clippy::result_unit_err)]
+pub unsafe fn get_dom_class(obj: *mut JSObject) -> Result<&'static DOMClass, ()> {
+ let clasp = get_object_class(obj);
+ if is_dom_class(&*clasp) {
+ trace!("plain old dom object");
+ let domjsclass: *const DOMJSClass = clasp as *const DOMJSClass;
+ return Ok(&(*domjsclass).dom_class);
+ }
+ if is_dom_proxy(obj) {
+ trace!("proxy dom object");
+ let dom_class: *const DOMClass = GetProxyHandlerExtra(obj) as *const DOMClass;
+ return Ok(&*dom_class);
+ }
+ trace!("not a dom object");
+ Err(())
+}
+
+/// Returns whether `obj` is a DOM object implemented as a proxy.
+///
+/// # Safety
+/// obj must point to a valid, non-null JS object.
+pub unsafe fn is_dom_proxy(obj: *mut JSObject) -> bool {
+ unsafe {
+ let clasp = get_object_class(obj);
+ ((*clasp).flags & js::JSCLASS_IS_PROXY) != 0 && IsProxyHandlerFamily(obj)
+ }
+}