mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
auto merge of #4594 : evilpie/servo/window-proxy, r=jdm
After this patch somebody just needs to implement the new IndexedGetter (and probably frames/length) on window to fix #4589.
This commit is contained in:
commit
a227faa416
5 changed files with 145 additions and 14 deletions
|
@ -2,14 +2,27 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* 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::{Reflectable, WindowProxyHandler};
|
||||||
|
use dom::bindings::utils::{GetArrayIndexFromId};
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
use dom::window::WindowHelpers;
|
||||||
|
|
||||||
use js::jsapi::JSObject;
|
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::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
|
||||||
use js::rust::with_compartment;
|
use js::rust::with_compartment;
|
||||||
|
use js::{JSRESOLVE_QUALIFIED, JSRESOLVE_ASSIGNING};
|
||||||
|
|
||||||
use std::ptr;
|
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 {
|
static PROXY_HANDLER: ProxyTraps = ProxyTraps {
|
||||||
getPropertyDescriptor: None,
|
getPropertyDescriptor: Some(getPropertyDescriptor),
|
||||||
getOwnPropertyDescriptor: None,
|
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
|
||||||
defineProperty: None,
|
defineProperty: Some(defineProperty),
|
||||||
getOwnPropertyNames: None,
|
getOwnPropertyNames: None,
|
||||||
delete_: None,
|
delete_: None,
|
||||||
enumerate: None,
|
enumerate: None,
|
||||||
|
|
||||||
has: None,
|
has: None,
|
||||||
hasOwn: None,
|
hasOwn: Some(hasOwn),
|
||||||
get: None,
|
get: Some(get),
|
||||||
set: None,
|
set: Some(set),
|
||||||
keys: None,
|
keys: None,
|
||||||
iterate: None,
|
iterate: None,
|
||||||
|
|
||||||
|
|
|
@ -311,12 +311,12 @@ impl<'a> WindowMethods for JSRef<'a, Window> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait WindowHelpers {
|
pub trait WindowHelpers {
|
||||||
fn flush_layout(self, goal: ReflowGoal, query: ReflowQueryType);
|
fn flush_layout(self, goal: ReflowGoal, query: ReflowQueryType);
|
||||||
fn init_browser_context(self, doc: JSRef<Document>);
|
fn init_browser_context(self, doc: JSRef<Document>);
|
||||||
fn load_url(self, href: DOMString);
|
fn load_url(self, href: DOMString);
|
||||||
fn handle_fire_timer(self, timer_id: TimerId);
|
fn handle_fire_timer(self, timer_id: TimerId);
|
||||||
|
fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ScriptHelpers {
|
pub trait ScriptHelpers {
|
||||||
|
@ -378,6 +378,11 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
self.timers.fire_timer(timer_id, self);
|
self.timers.fire_timer(timer_id, self);
|
||||||
self.flush_layout(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery);
|
self.flush_layout(ReflowGoal::ForDisplay, ReflowQueryType::NoQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/browsers.html#accessing-other-browsing-contexts
|
||||||
|
fn IndexedGetter(self, _index: u32, _found: &mut bool) -> Option<Temporary<Window>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
|
|
@ -62,7 +62,7 @@ pub mod dom {
|
||||||
pub mod callback;
|
pub mod callback;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
mod proxyhandler;
|
pub mod proxyhandler;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod structuredclone;
|
pub mod structuredclone;
|
||||||
pub mod trace;
|
pub mod trace;
|
||||||
|
|
23
tests/content/test_windowproxy.html
Normal file
23
tests/content/test_windowproxy.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<html>
|
||||||
|
<head id="foo">
|
||||||
|
<script src="harness.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div></div>
|
||||||
|
<script>
|
||||||
|
window.abcd = 15;
|
||||||
|
is(window.abcd, 15);
|
||||||
|
is(Object.getOwnPropertyDescriptor(window, 'abcd').value, 15);
|
||||||
|
is(window.hasOwnProperty('abcd'), true);
|
||||||
|
|
||||||
|
is('location' in window, true);
|
||||||
|
// FIXME: https://github.com/servo/servo/issues/4593
|
||||||
|
is(Object.hasOwnProperty('location'), false)
|
||||||
|
|
||||||
|
// Can't set indexed properties
|
||||||
|
window[100] = "abc";
|
||||||
|
is(window[100], undefined);
|
||||||
|
is(Object.getOwnPropertyDescriptor(window, 1000), undefined);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -2,7 +2,3 @@
|
||||||
type: testharness
|
type: testharness
|
||||||
[Indexed properties of the window object (non-strict mode) 1]
|
[Indexed properties of the window object (non-strict mode) 1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Indexed properties of the window object (non-strict mode) 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue