aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/browsercontext.rs
diff options
context:
space:
mode:
authorTom Schuster <evilpies@gmail.com>2015-01-09 16:36:05 +0100
committerTom Schuster <evilpies@gmail.com>2015-01-12 17:41:48 +0100
commitd54a45a2b1e4fe5109d8292483e538252da240f1 (patch)
treedf2227d6eeff585ba07a1e3276f0d729c1cda9ad /components/script/dom/browsercontext.rs
parentb020a015d91a0e67f1a526927b91bb07da0f5140 (diff)
downloadservo-d54a45a2b1e4fe5109d8292483e538252da240f1.tar.gz
servo-d54a45a2b1e4fe5109d8292483e538252da240f1.zip
Implement most of the important WindowProxy traps
Diffstat (limited to 'components/script/dom/browsercontext.rs')
-rw-r--r--components/script/dom/browsercontext.rs125
1 files changed, 116 insertions, 9 deletions
diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs
index 9cc2a94fdb9..959c021b4bc 100644
--- a/components/script/dom/browsercontext.rs
+++ b/components/script/dom/browsercontext.rs
@@ -2,14 +2,27 @@
* 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::js::{JS, JSRef, Temporary};
+use dom::bindings::conversions::unwrap_jsmanaged;
+use dom::bindings::conversions::{ToJSValConvertible};
+use dom::bindings::js::{JS, JSRef, Temporary, Root};
+use dom::bindings::js::{OptionalRootable, OptionalRootedRootable, ResultRootable};
+use dom::bindings::js::{OptionalRootedReference, OptionalOptionalRootedRootable};
+use dom::bindings::proxyhandler::{getPropertyDescriptor, FillPropertyDescriptor};
use dom::bindings::utils::{Reflectable, WindowProxyHandler};
+use dom::bindings::utils::{GetArrayIndexFromId};
use dom::document::{Document, DocumentHelpers};
use dom::window::Window;
-
-use js::jsapi::JSObject;
+use dom::window::WindowHelpers;
+
+use js::jsapi::{JSContext, JSObject, jsid, JSPropertyDescriptor};
+use js::jsapi::{JS_AlreadyHasOwnPropertyById, JS_ForwardGetPropertyTo};
+use js::jsapi::{JS_GetPropertyDescriptorById, JS_DefinePropertyById};
+use js::jsapi::{JS_SetPropertyById};
+use js::jsval::JSVal;
+use js::glue::{GetProxyPrivate};
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
use js::rust::with_compartment;
+use js::{JSRESOLVE_QUALIFIED, JSRESOLVE_ASSIGNING};
use std::ptr;
@@ -86,18 +99,112 @@ impl SessionHistoryEntry {
}
}
+unsafe fn GetSubframeWindow(cx: *mut JSContext, proxy: *mut JSObject, id: jsid) -> Option<Temporary<Window>> {
+ let index = GetArrayIndexFromId(cx, id);
+ if let Some(index) = index {
+ let target = GetProxyPrivate(proxy).to_object();
+ let win: Root<Window> = unwrap_jsmanaged(target).unwrap().root();
+ let mut found = false;
+ return win.r().IndexedGetter(index, &mut found);
+ }
+
+ None
+}
+
+unsafe extern fn getOwnPropertyDescriptor(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, set: bool, desc: *mut JSPropertyDescriptor) -> bool {
+ let window = GetSubframeWindow(cx, proxy, id);
+ if let Some(window) = window {
+ let window = window.root();
+ (*desc).value = window.to_jsval(cx);
+ FillPropertyDescriptor(&mut *desc, proxy, true);
+ return true;
+ }
+
+ let target = GetProxyPrivate(proxy).to_object();
+ let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED;
+ // XXX This should be JS_GetOwnPropertyDescriptorById
+ if JS_GetPropertyDescriptorById(cx, target, id, flags, desc) == 0 {
+ return false;
+ }
+
+ if (*desc).obj != target {
+ // Not an own property
+ (*desc).obj = ptr::null_mut();
+ } else {
+ (*desc).obj = proxy;
+ }
+
+ true
+}
+
+
+unsafe extern fn defineProperty(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, desc: *mut JSPropertyDescriptor) -> bool {
+ if GetArrayIndexFromId(cx, id).is_some() {
+ // Spec says to Reject whether this is a supported index or not,
+ // since we have no indexed setter or indexed creator. That means
+ // throwing in strict mode (FIXME: Bug 828137), doing nothing in
+ // non-strict mode.
+ return true;
+ }
+
+ let target = GetProxyPrivate(proxy).to_object();
+ JS_DefinePropertyById(cx, target, id, (*desc).value, (*desc).getter,
+ (*desc).setter, (*desc).attrs) != 0
+}
+
+unsafe extern fn hasOwn(cx: *mut JSContext, proxy: *mut JSObject, id: jsid, bp: *mut bool) -> bool {
+ let window = GetSubframeWindow(cx, proxy, id);
+ if window.is_some() {
+ *bp = true;
+ return true;
+ }
+
+ let target = GetProxyPrivate(proxy).to_object();
+ let mut found = 0;
+ if JS_AlreadyHasOwnPropertyById(cx, target, id, &mut found) == 0 {
+ return false;
+ }
+
+ *bp = found != 0;
+ return true;
+}
+
+unsafe extern fn get(cx: *mut JSContext, proxy: *mut JSObject, receiver: *mut JSObject, id: jsid, vp: *mut JSVal) -> bool {
+ let window = GetSubframeWindow(cx, proxy, id);
+ if let Some(window) = window {
+ let window = window.root();
+ *vp = window.to_jsval(cx);
+ return true;
+ }
+
+ let target = GetProxyPrivate(proxy).to_object();
+ JS_ForwardGetPropertyTo(cx, target, id, receiver, vp) != 0
+}
+
+unsafe extern fn set(cx: *mut JSContext, proxy: *mut JSObject, _receiver: *mut JSObject, id: jsid, _strict: bool, vp: *mut JSVal) -> bool {
+ if GetArrayIndexFromId(cx, id).is_some() {
+ // Reject (which means throw if and only if strict) the set.
+ // FIXME: Throw
+ return true;
+ }
+
+ // FIXME: The receiver should be used, we need something like JS_ForwardSetPropertyTo.
+ let target = GetProxyPrivate(proxy).to_object();
+ JS_SetPropertyById(cx, target, id, vp) != 0
+}
+
static PROXY_HANDLER: ProxyTraps = ProxyTraps {
- getPropertyDescriptor: None,
- getOwnPropertyDescriptor: None,
- defineProperty: None,
+ getPropertyDescriptor: Some(getPropertyDescriptor),
+ getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
+ defineProperty: Some(defineProperty),
getOwnPropertyNames: None,
delete_: None,
enumerate: None,
has: None,
- hasOwn: None,
- get: None,
- set: None,
+ hasOwn: Some(hasOwn),
+ get: Some(get),
+ set: Some(set),
keys: None,
iterate: None,