diff options
-rw-r--r-- | src/components/script/dom/bindings/callback.rs | 35 | ||||
-rw-r--r-- | src/components/script/dom/bindings/conversions.rs | 12 | ||||
-rw-r--r-- | src/components/script/dom/bindings/error.rs | 14 | ||||
-rw-r--r-- | src/components/script/dom/bindings/global.rs | 15 | ||||
-rw-r--r-- | src/components/script/dom/bindings/js.rs | 3 | ||||
-rw-r--r-- | src/components/script/dom/bindings/proxyhandler.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/bindings/str.rs | 15 | ||||
-rw-r--r-- | src/components/script/dom/bindings/trace.rs | 37 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 85 | ||||
-rw-r--r-- | src/components/script/script.rs | 11 |
10 files changed, 215 insertions, 14 deletions
diff --git a/src/components/script/dom/bindings/callback.rs b/src/components/script/dom/bindings/callback.rs index 865bd9d3ef7..41d4c5b73ce 100644 --- a/src/components/script/dom/bindings/callback.rs +++ b/src/components/script/dom/bindings/callback.rs @@ -2,6 +2,8 @@ * 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/. */ +//! Base classes to work with IDL callbacks. + use dom::bindings::js::JSRef; use dom::bindings::trace::Traceable; use dom::bindings::utils::{Reflectable, global_object_for_js_object}; @@ -13,17 +15,19 @@ use std::ptr; use serialize::{Encodable, Encoder}; +/// The exception handling used for a call. pub enum ExceptionHandling { - // Report any exception and don't throw it to the caller code. + /// Report any exception and don't throw it to the caller code. ReportExceptions, - // 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. + /// 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. RethrowContentExceptions, - // Throw any exception to the caller code. + /// Throw any exception to the caller code. RethrowExceptions } +/// A common base class for representing IDL callback function types. #[deriving(Clone,PartialEq,Encodable)] pub struct CallbackFunction { object: CallbackObject @@ -39,35 +43,46 @@ impl CallbackFunction { } } +/// A common base class for representing IDL callback interface types. #[deriving(Clone,PartialEq,Encodable)] pub struct CallbackInterface { object: CallbackObject } +/// A common base class for representing IDL callback function and +/// callback interface types. #[allow(raw_pointer_deriving)] #[deriving(Clone,PartialEq,Encodable)] struct CallbackObject { + /// The underlying `JSObject`. callback: Traceable<*mut JSObject>, } +/// A trait to be implemented by concrete IDL callback function and +/// callback interface types. pub trait CallbackContainer { + /// Create a new CallbackContainer object for the given `JSObject`. fn new(callback: *mut JSObject) -> Self; + /// Returns the underlying `JSObject`. fn callback(&self) -> *mut JSObject; } impl CallbackInterface { + /// Returns the underlying `JSObject`. pub fn callback(&self) -> *mut JSObject { *self.object.callback } } impl CallbackFunction { + /// Returns the underlying `JSObject`. pub fn callback(&self) -> *mut JSObject { *self.object.callback } } impl CallbackInterface { + /// Create a new CallbackInterface object for the given `JSObject`. pub fn new(callback: *mut JSObject) -> CallbackInterface { CallbackInterface { object: CallbackObject { @@ -76,6 +91,9 @@ impl CallbackInterface { } } + /// Returns the property with the given `name`, if it is a callable object, + /// or `Err(())` otherwise. If it returns `Err(())`, a JSAPI exception is + /// pending. pub fn GetCallableProperty(&self, cx: *mut JSContext, name: &str) -> Result<JSVal, ()> { let mut callable = UndefinedValue(); unsafe { @@ -93,6 +111,7 @@ impl CallbackInterface { } } +/// Wraps the reflector for `p` into the compartment of `cx`. pub fn WrapCallThisObject<T: Reflectable>(cx: *mut JSContext, p: &JSRef<T>) -> *mut JSObject { let mut obj = p.reflector().get_jsobject(); @@ -107,12 +126,17 @@ pub fn WrapCallThisObject<T: Reflectable>(cx: *mut JSContext, return obj; } +/// A class that performs whatever setup we need to safely make a call while +/// this class is on the stack. After `new` returns, the call is safe to make. pub struct CallSetup { + /// The `JSContext` used for the call. cx: *mut JSContext, + /// The exception handling used for the call. _handling: ExceptionHandling } impl CallSetup { + /// Performs the setup needed to make a call. pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup { let global = global_object_for_js_object(callback.callback()).root(); let cx = global.root_ref().get_cx(); @@ -122,6 +146,7 @@ impl CallSetup { } } + /// Returns the `JSContext` used for the call. pub fn GetContext(&self) -> *mut JSContext { self.cx } diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index ddbbcf433a4..60d8d2a2b98 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -2,6 +2,8 @@ * 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/. */ +//! Conversions of Rust values to and from `JSVal`. + use dom::bindings::js::{JS, JSRef, Root}; use dom::bindings::str::ByteString; use dom::bindings::utils::{Reflectable, Reflector}; @@ -33,11 +35,18 @@ pub trait IDLInterface { fn get_prototype_depth(_: Option<Self>) -> uint; } +/// A trait to convert Rust types to `JSVal`s. pub trait ToJSValConvertible { + /// Convert `self` to a `JSVal`. JSAPI failure causes a task failure. fn to_jsval(&self, cx: *mut JSContext) -> JSVal; } +/// A trait to convert `JSVal`s to Rust types. pub trait FromJSValConvertible<T> { + /// Convert `val` to type `Self`. + /// Optional configuration of type `T` can be passed as the `option` + /// argument. + /// If it returns `Err(())`, a JSAPI exception is pending. fn from_jsval(cx: *mut JSContext, val: JSVal, option: T) -> Result<Self, ()>; } @@ -228,9 +237,12 @@ impl ToJSValConvertible for DOMString { } } +/// Behavior for stringification of `JSVal`s. #[deriving(PartialEq)] pub enum StringificationBehavior { + /// Convert `null` to the string `"null"`. Default, + /// Convert `null` to the empty string. Empty, } diff --git a/src/components/script/dom/bindings/error.rs b/src/components/script/dom/bindings/error.rs index cef1de163fd..aa0642179a3 100644 --- a/src/components/script/dom/bindings/error.rs +++ b/src/components/script/dom/bindings/error.rs @@ -2,6 +2,8 @@ * 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/. */ +//! Utilities to throw exceptions from Rust bindings. + use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::global::GlobalRef; use dom::domexception::DOMException; @@ -16,6 +18,7 @@ use js::rust::with_compartment; use libc; use std::ptr; +/// DOM exceptions that can be thrown by a native DOM method. #[deriving(Show)] pub enum Error { IndexSize, @@ -34,10 +37,14 @@ pub enum Error { Timeout } +/// The return type for IDL operations that can throw DOM exceptions. pub type Fallible<T> = Result<T, Error>; +/// The return type for IDL operations that can throw DOM exceptions and +/// return `()`. pub type ErrorResult = Fallible<()>; +/// Set a pending DOM exception for the given `result` on `cx`. pub fn throw_dom_exception(cx: *mut JSContext, global: &GlobalRef, result: Error) { assert!(unsafe { JS_IsExceptionPending(cx) } == 0); @@ -48,6 +55,7 @@ pub fn throw_dom_exception(cx: *mut JSContext, global: &GlobalRef, } } +/// Report a pending exception, thereby clearing it. pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) { unsafe { if JS_IsExceptionPending(cx) != 0 { @@ -62,6 +70,8 @@ pub fn report_pending_exception(cx: *mut JSContext, obj: *mut JSObject) { } } +/// Throw an exception to signal that a `JSVal` can not be converted to any of +/// the types in an IDL union type. pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool { assert!(unsafe { JS_IsExceptionPending(cx) } == 0); let message = format!("argument could not be converted to any of: {}", names); @@ -71,6 +81,7 @@ pub fn throw_not_in_union(cx: *mut JSContext, names: &'static str) -> JSBool { return 0; } +/// Format string used to throw `TypeError`s. static ERROR_FORMAT_STRING_STRING: [libc::c_char, ..4] = [ '{' as libc::c_char, '0' as libc::c_char, @@ -78,12 +89,14 @@ static ERROR_FORMAT_STRING_STRING: [libc::c_char, ..4] = [ 0 as libc::c_char, ]; +/// Format string struct used to throw `TypeError`s. static ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString { format: &ERROR_FORMAT_STRING_STRING as *libc::c_char, argCount: 1, exnType: JSEXN_TYPEERR as i16, }; +/// Callback used to throw `TypeError`s. extern fn get_error_message(_user_ref: *mut libc::c_void, _locale: *libc::c_char, error_number: libc::c_uint) -> *JSErrorFormatString @@ -92,6 +105,7 @@ extern fn get_error_message(_user_ref: *mut libc::c_void, &ERROR_FORMAT_STRING as *JSErrorFormatString } +/// Throw a `TypeError` with the given message. pub fn throw_type_error(cx: *mut JSContext, error: &str) { let error = error.to_c_str(); error.with_ref(|error| unsafe { diff --git a/src/components/script/dom/bindings/global.rs b/src/components/script/dom/bindings/global.rs index 2c4d9537fd2..ed7807f9d72 100644 --- a/src/components/script/dom/bindings/global.rs +++ b/src/components/script/dom/bindings/global.rs @@ -3,6 +3,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! Abstractions for global scopes. +//! +//! This module contains smart pointers to global scopes, to simplify writing +//! code that works in workers as well as window scopes. use dom::bindings::js::{JS, JSRef, Root}; use dom::bindings::utils::{Reflectable, Reflector}; @@ -16,16 +19,20 @@ use js::jsapi::JSContext; use url::Url; +/// A freely-copyable reference to a rooted global object. pub enum GlobalRef<'a> { Window(JSRef<'a, Window>), Worker(JSRef<'a, WorkerGlobalScope>), } +/// A stack-based rooted reference to a global object. pub enum GlobalRoot<'a, 'b> { WindowRoot(Root<'a, 'b, Window>), WorkerRoot(Root<'a, 'b, WorkerGlobalScope>), } +/// A traced reference to a global object, for use in fields of traced Rust +/// structures. #[deriving(Encodable)] pub enum GlobalField { WindowField(JS<Window>), @@ -33,6 +40,8 @@ pub enum GlobalField { } impl<'a> GlobalRef<'a> { + /// Get the `JSContext` for the `JSRuntime` associated with the thread + /// this global object is on. pub fn get_cx(&self) -> *mut JSContext { match *self { Window(ref window) => window.get_cx(), @@ -40,6 +49,8 @@ impl<'a> GlobalRef<'a> { } } + /// Extract a `Window`, causing task failure if the global object is not + /// a `Window`. pub fn as_window<'b>(&'b self) -> &'b JSRef<'b, Window> { match *self { Window(ref window) => window, @@ -79,6 +90,8 @@ impl<'a> Reflectable for GlobalRef<'a> { } impl<'a, 'b> GlobalRoot<'a, 'b> { + /// Obtain a safe reference to the global object that cannot outlive the + /// lifetime of this root. pub fn root_ref<'c>(&'c self) -> GlobalRef<'c> { match *self { WindowRoot(ref window) => Window(window.root_ref()), @@ -88,6 +101,7 @@ impl<'a, 'b> GlobalRoot<'a, 'b> { } impl GlobalField { + /// Create a new `GlobalField` from a rooted reference. pub fn from_rooted(global: &GlobalRef) -> GlobalField { match *global { Window(ref window) => WindowField(JS::from_rooted(window)), @@ -95,6 +109,7 @@ impl GlobalField { } } + /// Create a stack-bounded root for this reference. pub fn root(&self) -> GlobalRoot { match *self { WindowField(ref window) => WindowRoot(window.root()), diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index b83115e289d..73cb19c5072 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -2,6 +2,8 @@ * 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/. */ +//! Smart pointers for the JS-managed DOM objects. +//! //! The DOM is made up of Rust types whose lifetime is entirely controlled by the whims of //! the SpiderMonkey garbage collector. The types in this module are designed to ensure //! that any interactions with said Rust types only occur on values that will remain alive @@ -10,6 +12,7 @@ //! Here is a brief overview of the important types: //! //! - `JSRef<T>`: a freely-copyable reference to a rooted value. +//! - `Root<T>`: a stack-based reference to a rooted value. //! - `JS<T>`: a pointer to JS-owned memory that can automatically be traced by the GC when //! encountered as a field of a Rust structure. //! - `Temporary<T>`: a value that will remain rooted for the duration of its lifetime. diff --git a/src/components/script/dom/bindings/proxyhandler.rs b/src/components/script/dom/bindings/proxyhandler.rs index 66984ebdc19..07d750e438e 100644 --- a/src/components/script/dom/bindings/proxyhandler.rs +++ b/src/components/script/dom/bindings/proxyhandler.rs @@ -2,6 +2,8 @@ * 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/. */ +///! Utilities for the implementation of JSAPI proxy handlers. + use dom::bindings::utils::is_dom_proxy; use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar}; use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free}; diff --git a/src/components/script/dom/bindings/str.rs b/src/components/script/dom/bindings/str.rs index b42845b6e77..825716bdf3e 100644 --- a/src/components/script/dom/bindings/str.rs +++ b/src/components/script/dom/bindings/str.rs @@ -2,38 +2,49 @@ * 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/. */ +//! The `ByteString` struct. + use std::from_str::FromStr; use std::hash::{Hash, sip}; use std::path::BytesContainer; use std::str; +/// Encapsulates the IDL `ByteString` type. #[deriving(Encodable,Clone,Eq,PartialEq)] pub struct ByteString(Vec<u8>); impl ByteString { + /// Creates a new `ByteString`. pub fn new(value: Vec<u8>) -> ByteString { ByteString(value) } + + /// Returns `self` as a string, if it encodes valid UTF-8, and `None` + /// otherwise. pub fn as_str<'a>(&'a self) -> Option<&'a str> { let ByteString(ref vec) = *self; str::from_utf8(vec.as_slice()) } + /// Returns the underlying vector as a slice. pub fn as_slice<'a>(&'a self) -> &'a [u8] { let ByteString(ref vector) = *self; vector.as_slice() } + /// Returns the length. pub fn len(&self) -> uint { let ByteString(ref vector) = *self; vector.len() } + /// Compare `self` to `other`, matching A–Z and a–z as equal. pub fn eq_ignore_case(&self, other: &ByteString) -> bool { // XXXManishearth make this more efficient self.to_lower() == other.to_lower() } + /// Returns `self` with A–Z replaced by a–z. pub fn to_lower(&self) -> ByteString { let ByteString(ref vec) = *self; ByteString::new(vec.iter().map(|&x| { @@ -45,6 +56,8 @@ impl ByteString { }).collect()) } + /// Returns whether `self` is a `token`, as defined by + /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-17). pub fn is_token(&self) -> bool { let ByteString(ref vec) = *self; if vec.len() == 0 { @@ -64,6 +77,8 @@ impl ByteString { }) } + /// Returns whether `self` is a `field-value`, as defined by + /// [RFC 2616](http://tools.ietf.org/html/rfc2616#page-32). pub fn is_field_value(&self) -> bool { // Classifications of characters necessary for the [CRLF] (SP|HT) rule #[deriving(PartialEq)] diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 8cbf32e0cbd..b9865eeec91 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -2,6 +2,30 @@ * 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/. */ +//! Utilities for tracing JS-managed values. +//! +//! The lifetime of DOM objects is managed by the SpiderMonkey Garbage +//! Collector. A rooted DOM object implementing the interface `Foo` is traced +//! as follows: +//! +//! 1. The GC calls `_trace` defined in `FooBinding` during the marking +//! phase. (This happens through `JSClass.trace` for non-proxy bindings, and +//! through `ProxyTraps.trace` otherwise.) +//! 2. `_trace` calls `Foo::trace()` (an implementation of `JSTraceable`, +//! defined in `InheritTypes.rs`). +//! 3. `Foo::trace()` calls `Foo::encode()` (an implementation of `Encodable`). +//! This implementation is typically derived by a `#[deriving(Encodable)]` +//! annotation on the Rust struct. +//! 4. For all fields (except those wrapped in `Untraceable`), `Foo::encode()` +//! calls `encode()` on the field. +//! +//! For example, for fields of type `JS<T>`, `JS<T>::encode()` calls +//! `trace_reflector()`. +//! 6. `trace_reflector()` calls `trace_object()` with the `JSObject` for the +//! reflector. +//! 7. `trace_object()` calls `JS_CallTracer()` to notify the GC, which will +//! add the object to the graph, and will trace that object as well. + use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; @@ -37,10 +61,12 @@ impl<S: Encoder<E>, E> Encodable<S, E> for Reflector { } } +/// A trait to allow tracing (only) DOM objects. pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } +/// Trace a `JSVal`. pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { if !val.is_gcthing() { return; @@ -57,10 +83,12 @@ pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: JSVal) { } } +/// Trace the `JSObject` held by `reflector`. pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) { trace_object(tracer, description, reflector.get_jsobject()) } +/// Trace a `JSObject`. pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject) { unsafe { description.to_c_str().with_ref(|name| { @@ -73,8 +101,9 @@ pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject } } -/// Encapsulates a type that cannot easily have Encodable derived automagically, +/// Encapsulates a type that cannot easily have `Encodable` derived automagically, /// but also does not need to be made known to the SpiderMonkey garbage collector. +/// /// Use only with types that are not associated with a JS reflector and do not contain /// fields of types associated with JS reflectors. /// @@ -104,8 +133,10 @@ impl<T> Deref<T> for Untraceable<T> { } } -/// Encapsulates a type that can be traced but is boxed in a type we don't control -/// (such as RefCell). Wrap a field in Traceable and implement the Encodable trait +/// Encapsulates a type that can be traced but is boxed in a type we don't +/// control (such as `RefCell`). +/// +/// Wrap a field in Traceable and implement the `Encodable` trait /// for that new concrete type to achieve magic compiler-derived trace hooks. /// /// We always prefer this, in case the contained type ever changes to something that should be traced. diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 36f68a93f3e..1e2e38c0141 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -2,6 +2,8 @@ * 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/. */ +//! Various utilities to glue JavaScript and the DOM implementation together. + use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::{FromJSValConvertible, IDLInterface}; @@ -61,12 +63,14 @@ pub fn GlobalStaticData() -> GlobalStaticData { } } +/// Returns whether the given `clasp` is one for a DOM object. fn is_dom_class(clasp: *JSClass) -> bool { unsafe { ((*clasp).flags & js::JSCLASS_IS_DOMJSCLASS) != 0 } } +/// Returns whether `obj` is a DOM object implemented as a proxy. pub fn is_dom_proxy(obj: *mut JSObject) -> bool { unsafe { (js_IsObjectProxyClass(obj) || js_IsFunctionProxyClass(obj)) && @@ -74,6 +78,10 @@ pub fn is_dom_proxy(obj: *mut JSObject) -> bool { } } +/// Returns the index of the slot wherein a pointer to the reflected DOM object +/// is stored. +/// +/// Fails if `obj` is not a DOM object. pub unsafe fn dom_object_slot(obj: *mut JSObject) -> u32 { let clasp = JS_GetClass(obj); if is_dom_class(clasp) { @@ -84,12 +92,14 @@ pub unsafe fn dom_object_slot(obj: *mut JSObject) -> u32 { } } +/// Get the DOM object from the given reflector. pub unsafe fn unwrap<T>(obj: *mut JSObject) -> *T { let slot = dom_object_slot(obj); let val = JS_GetReservedSlot(obj, slot); val.to_private() as *T } +/// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object. pub unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> { let clasp = JS_GetClass(obj); if is_dom_class(clasp) { @@ -106,6 +116,12 @@ pub unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> { return Err(()); } +/// Get a `JS<T>` for the given DOM object, unwrapping any wrapper around it +/// first, and checking if the object is of the correct type. +/// +/// Returns Err(()) if `obj` is an opaque security wrapper or if the object is +/// not a reflector for a DOM object of the given type (as defined by the +/// proto_id and proto_depth). pub fn unwrap_jsmanaged<T: Reflectable>(mut obj: *mut JSObject, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<JS<T>, ()> { @@ -140,10 +156,13 @@ pub fn unwrap_jsmanaged<T: Reflectable>(mut obj: *mut JSObject, } } +/// Leak the given pointer. pub unsafe fn squirrel_away_unique<T>(x: Box<T>) -> *T { mem::transmute(x) } +/// Convert the given `JSString` to a `DOMString`. Fails if the string does not +/// contain valid UTF-16. pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString { unsafe { let mut length = 0; @@ -154,6 +173,8 @@ pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString { } } +/// Convert the given `jsid` to a `DOMString`. Fails if the `jsid` is not a +/// string, or if the string does not contain valid UTF-16. pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString { unsafe { assert!(RUST_JSID_IS_STRING(id) != 0); @@ -161,6 +182,8 @@ pub fn jsid_to_str(cx: *mut JSContext, id: jsid) -> DOMString { } } +/// The index of the slot wherein a pointer to the reflected DOM object is +/// stored for non-proxy bindings. // We use slot 0 for holding the raw object. This is safe for both // globals and non-globals. pub static DOM_OBJECT_SLOT: uint = 0; @@ -171,14 +194,17 @@ static DOM_PROXY_OBJECT_SLOT: uint = js::JSSLOT_PROXY_PRIVATE as uint; // changes. static DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0; +/// The index of the slot that contains a reference to the ProtoOrIfaceArray. // All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT; +/// The flag set on the `JSClass`es for DOM global objects. // NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and // LSetDOMProperty. Those constants need to be changed accordingly if this value // changes. pub static JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1; +/// Representation of an IDL constant value. #[deriving(Clone)] pub enum ConstantVal { IntVal(i32), @@ -189,23 +215,28 @@ pub enum ConstantVal { VoidVal } +/// Representation of an IDL constant. #[deriving(Clone)] pub struct ConstantSpec { pub name: &'static [u8], pub value: ConstantVal } +/// The struct that holds inheritance information for DOM object reflectors. pub struct DOMClass { - // A list of interfaces that this object implements, in order of decreasing - // derivedness. + /// A list of interfaces that this object implements, in order of decreasing + /// derivedness. pub interface_chain: [PrototypeList::id::ID, ..MAX_PROTO_CHAIN_LENGTH] } +/// The JSClass used for DOM object reflectors. pub struct DOMJSClass { pub base: js::Class, pub dom_class: DOMClass } +/// Returns the ProtoOrIfaceArray for the given global object. +/// Fails if `global` is not a DOM global object. pub fn GetProtoOrIfaceArray(global: *mut JSObject) -> *mut *mut JSObject { unsafe { assert!(((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0); @@ -213,6 +244,8 @@ pub fn GetProtoOrIfaceArray(global: *mut JSObject) -> *mut *mut JSObject { } } +/// Contains references to lists of methods, attributes, and constants for a +/// given interface. pub struct NativeProperties { pub methods: Option<&'static [JSFunctionSpec]>, pub attrs: Option<&'static [JSPropertySpec]>, @@ -221,9 +254,13 @@ pub struct NativeProperties { pub staticAttrs: Option<&'static [JSPropertySpec]>, } +/// A JSNative that cannot be null. pub type NonNullJSNative = unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool; +/// Creates the *interface prototype object* and the *interface object* (if +/// needed). +/// Fails on JSAPI failure. pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, protoProto: *mut JSObject, protoClass: &'static JSClass, @@ -252,6 +289,8 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv proto } +/// Creates the *interface object*. +/// Fails on JSAPI failure. fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, constructorNative: NonNullJSNative, ctorNargs: u32, proto: *mut JSObject, @@ -295,6 +334,8 @@ fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *m } } +/// Defines constants on `obj`. +/// Fails on JSAPI failure. fn DefineConstants(cx: *mut JSContext, obj: *mut JSObject, constants: &'static [ConstantSpec]) { for spec in constants.iter() { let jsval = match spec.value { @@ -314,18 +355,26 @@ fn DefineConstants(cx: *mut JSContext, obj: *mut JSObject, constants: &'static [ } } +/// Defines methods on `obj`. The last entry of `methods` must contain zeroed +/// memory. +/// Fails on JSAPI failure. fn DefineMethods(cx: *mut JSContext, obj: *mut JSObject, methods: &'static [JSFunctionSpec]) { unsafe { assert!(JS_DefineFunctions(cx, obj, methods.as_ptr()) != 0); } } +/// Defines attributes on `obj`. The last entry of `properties` must contain +/// zeroed memory. +/// Fails on JSAPI failure. fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static [JSPropertySpec]) { unsafe { assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0); } } +/// Creates the *interface prototype object*. +/// Fails on JSAPI failure. fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject, parentProto: *mut JSObject, protoClass: &'static JSClass, @@ -353,11 +402,14 @@ fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject, } } +/// A throwing constructor, for those interfaces that have neither +/// `NoInterfaceObject` nor `Constructor`. pub extern fn ThrowingConstructor(_cx: *mut JSContext, _argc: c_uint, _vp: *mut JSVal) -> JSBool { //XXX should trigger exception here return 0; } +/// Construct and cache the ProtoOrIfaceArray for the given global. pub fn initialize_global(global: *mut JSObject) { let protoArray = box () ([0 as *mut JSObject, ..PrototypeList::id::IDCount as uint]); unsafe { @@ -368,10 +420,13 @@ pub fn initialize_global(global: *mut JSObject) { } } +/// A trait to provide access to the `Reflector` for a DOM object. pub trait Reflectable { fn reflector<'a>(&'a self) -> &'a Reflector; } +/// Create the reflector for a new DOM object and yield ownership to the +/// reflector. pub fn reflect_dom_object<T: Reflectable> (obj: Box<T>, global: &GlobalRef, @@ -380,6 +435,7 @@ pub fn reflect_dom_object<T: Reflectable> wrap_fn(global.get_cx(), global, obj) } +/// A struct to store a reference to the reflector of a DOM object. #[allow(raw_pointer_deriving)] #[deriving(PartialEq)] pub struct Reflector { @@ -387,11 +443,13 @@ pub struct Reflector { } impl Reflector { + /// Get the reflector. #[inline] pub fn get_jsobject(&self) -> *mut JSObject { self.object.get() } + /// Initialize the reflector. (May be called only once.) pub fn set_jsobject(&self, object: *mut JSObject) { assert!(self.object.get().is_null()); assert!(object.is_not_null()); @@ -407,6 +465,7 @@ impl Reflector { as *mut *mut JSObject } + /// Create an uninitialized `Reflector`. pub fn new() -> Reflector { Reflector { object: Cell::new(ptr::mut_null()), @@ -437,6 +496,8 @@ pub fn GetPropertyOnPrototype(cx: *mut JSContext, proxy: *mut JSObject, id: jsid } } +/// Get an array index from the given `jsid`. Returns `None` if the given +/// `jsid` is not an integer. pub fn GetArrayIndexFromId(_cx: *mut JSContext, id: jsid) -> Option<u32> { unsafe { if RUST_JSID_IS_INT(id) != 0 { @@ -460,6 +521,9 @@ pub fn GetArrayIndexFromId(_cx: *mut JSContext, id: jsid) -> Option<u32> { }*/ } +/// Find the index of a string given by `v` in `values`. +/// Returns `Err(())` on JSAPI failure (there is a pending exception), and +/// `Ok(None)` if there was no matching string. pub fn FindEnumStringIndex(cx: *mut JSContext, v: JSVal, values: &[&'static str]) -> Result<Option<uint>, ()> { @@ -484,6 +548,9 @@ pub fn FindEnumStringIndex(cx: *mut JSContext, } } +/// Get the property with name `property` from `object`. +/// Returns `Err(())` on JSAPI failure (there is a pending exception), and +/// `Ok(None)` if there was no property with the given name. pub fn get_dictionary_property(cx: *mut JSContext, object: *mut JSObject, property: &str) -> Result<Option<JSVal>, ()> { @@ -533,12 +600,14 @@ pub fn HasPropertyOnPrototype(cx: *mut JSContext, proxy: *mut JSObject, id: jsid return !GetPropertyOnPrototype(cx, proxy, id, &mut found, ptr::mut_null()) || found; } +/// Returns whether `obj` can be converted to a callback interface per IDL. pub fn IsConvertibleToCallbackInterface(cx: *mut JSContext, obj: *mut JSObject) -> bool { unsafe { JS_ObjectIsDate(cx, obj) == 0 && JS_ObjectIsRegExp(cx, obj) == 0 } } +/// Create a DOM global object with the given class. pub fn CreateDOMGlobal(cx: *mut JSContext, class: *JSClass) -> *mut JSObject { unsafe { let obj = JS_NewGlobalObject(cx, class, ptr::mut_null()); @@ -553,12 +622,14 @@ pub fn CreateDOMGlobal(cx: *mut JSContext, class: *JSClass) -> *mut JSObject { } } +/// Callback to outerize windows when wrapping. pub extern fn wrap_for_same_compartment(cx: *mut JSContext, obj: *mut JSObject) -> *mut JSObject { unsafe { JS_ObjectToOuterObject(cx, obj) } } +/// Callback to outerize windows before wrapping. pub extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject, obj: *mut JSObject, _flags: c_uint) -> *mut JSObject { unsafe { @@ -566,6 +637,7 @@ pub extern fn pre_wrap(cx: *mut JSContext, _scope: *mut JSObject, } } +/// Callback to outerize windows. pub extern fn outerize_global(_cx: *mut JSContext, obj: JSHandleObject) -> *mut JSObject { unsafe { debug!("outerizing"); @@ -600,17 +672,20 @@ pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalField { } } +/// Get the `JSContext` for the `JSRuntime` associated with the thread +/// this object is on. fn cx_for_dom_reflector(obj: *mut JSObject) -> *mut JSContext { let global = global_object_for_js_object(obj).root(); global.root_ref().get_cx() } +/// Get the `JSContext` for the `JSRuntime` associated with the thread +/// this DOM object is on. pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *mut JSContext { cx_for_dom_reflector(obj.reflector().get_jsobject()) } -/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name -/// for details. +/// Results of `xml_name_type`. #[deriving(PartialEq)] pub enum XMLName { QName, @@ -618,6 +693,8 @@ pub enum XMLName { InvalidXMLName } +/// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name +/// for details. pub fn xml_name_type(name: &str) -> XMLName { fn is_valid_start(c: char) -> bool { match c { diff --git a/src/components/script/script.rs b/src/components/script/script.rs index 9019cfeb4dc..9d04b49fc40 100644 --- a/src/components/script/script.rs +++ b/src/components/script/script.rs @@ -14,6 +14,8 @@ #![feature(phase)] +#![doc="The script crate contains all matters DOM."] + #![allow(non_snake_case_functions)] #[phase(plugin, link)] @@ -43,9 +45,11 @@ extern crate sync; extern crate servo_msg = "msg"; extern crate url = "url_"; - pub mod cors; + +/// The implementation of the DOM. pub mod dom { + /// The code to expose the DOM to JavaScript through IDL bindings. pub mod bindings { pub mod global; pub mod js; @@ -53,9 +57,11 @@ pub mod dom { pub mod callback; pub mod error; pub mod conversions; - pub mod proxyhandler; + mod proxyhandler; pub mod str; pub mod trace; + + /// Generated JS-Rust bindings. pub mod codegen { pub mod Bindings; pub mod InterfaceTypes; @@ -190,6 +196,7 @@ pub mod dom { pub mod testbinding; } +/// Parsers for HTML and CSS. pub mod html { pub mod cssparse; pub mod hubbub_html_parser; |