diff options
author | Tom Schuster <evilpies@gmail.com> | 2015-01-09 16:36:05 +0100 |
---|---|---|
committer | Tom Schuster <evilpies@gmail.com> | 2015-01-12 17:41:48 +0100 |
commit | d54a45a2b1e4fe5109d8292483e538252da240f1 (patch) | |
tree | df2227d6eeff585ba07a1e3276f0d729c1cda9ad /components/script/dom/browsercontext.rs | |
parent | b020a015d91a0e67f1a526927b91bb07da0f5140 (diff) | |
download | servo-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.rs | 125 |
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, |