aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/script/dom/bindings/codegen/Bindings.conf8
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py110
-rw-r--r--src/components/script/dom/bindings/codegen/Configuration.py1
-rw-r--r--src/components/script/dom/bindings/trace.rs26
-rw-r--r--src/components/script/dom/bindings/utils.rs74
-rw-r--r--src/components/script/dom/browsercontext.rs118
-rw-r--r--src/components/script/dom/eventtarget.rs3
-rw-r--r--src/components/script/dom/htmlframeelement.rs4
-rw-r--r--src/components/script/dom/htmliframeelement.rs4
-rw-r--r--src/components/script/dom/htmlobjectelement.rs4
-rw-r--r--src/components/script/dom/mouseevent.rs3
-rw-r--r--src/components/script/dom/testbinding.rs5
-rw-r--r--src/components/script/dom/uievent.rs9
-rw-r--r--src/components/script/dom/webidls/HTMLFrameElement.webidl2
-rw-r--r--src/components/script/dom/webidls/HTMLIFrameElement.webidl2
-rw-r--r--src/components/script/dom/webidls/HTMLObjectElement.webidl2
-rw-r--r--src/components/script/dom/webidls/MouseEvent.webidl4
-rw-r--r--src/components/script/dom/webidls/UIEvent.webidl10
-rw-r--r--src/components/script/dom/webidls/Window.webidl16
-rw-r--r--src/components/script/dom/window.rs40
-rw-r--r--src/components/script/dom/windowproxy.rs32
-rw-r--r--src/components/script/script.rs2
-rw-r--r--src/components/script/script_task.rs28
m---------src/support/spidermonkey/rust-mozjs0
24 files changed, 353 insertions, 154 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf
index 2e94db0f874..56469cfafb8 100644
--- a/src/components/script/dom/bindings/codegen/Bindings.conf
+++ b/src/components/script/dom/bindings/codegen/Bindings.conf
@@ -12,6 +12,8 @@
# * needsAbstract: a list of members that require a JS<>-wrapped version of
# self to be passed to the native code.
# * createGlobal: True for global objects.
+# * outerObjectHook: string to use in place of default value for outerObject and thisObject
+# JS class hooks
DOMInterfaces = {
@@ -112,15 +114,16 @@ DOMInterfaces = {
'ValidityState': {},
'Window': {
'createGlobal': True,
+ 'outerObjectHook': 'Some(bindings::utils::outerize_global)',
'needsAbstract': [
'console',
'location',
'navigator',
+ 'self',
+ 'window',
],
},
-'WindowProxy': {},
-
'TestBinding': {},
}
@@ -129,7 +132,6 @@ DOMInterfaces = {
def addHTMLElement(element, concrete=None, needsAbstract=[]):
DOMInterfaces[element] = {
'nativeType': 'JS<%s>' % element,
- 'pointerType': '',
'concreteType': concrete if concrete else element,
'needsAbstract': needsAbstract
}
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 22523568719..cba5bd0b333 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1496,7 +1496,8 @@ class CGDOMJSClass(CGThing):
return """
static Class_name: [u8, ..%i] = %s;
static Class: DOMJSClass = DOMJSClass {
- base: JSClass { name: &Class_name as *u8 as *libc::c_char,
+ base: js::Class {
+ name: &Class_name as *u8 as *libc::c_char,
flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s),
addProperty: Some(JS_PropertyStub),
delProperty: Some(JS_PropertyStub),
@@ -1511,14 +1512,51 @@ static Class: DOMJSClass = DOMJSClass {
hasInstance: None,
construct: None,
trace: %s,
- reserved: (0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 05
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 10
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 15
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 20
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 25
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 30
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, // 35
- 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void, 0 as *libc::c_void) // 40
+
+ ext: js::ClassExtension {
+ equality: 0 as *u8,
+ outerObject: %s,
+ innerObject: None,
+ iteratorObject: 0 as *u8,
+ unused: 0 as *u8,
+ isWrappedNative: 0 as *u8,
+ },
+
+ ops: js::ObjectOps {
+ lookupGeneric: 0 as *u8,
+ lookupProperty: 0 as *u8,
+ lookupElement: 0 as *u8,
+ lookupSpecial: 0 as *u8,
+ defineGeneric: 0 as *u8,
+ defineProperty: 0 as *u8,
+ defineElement: 0 as *u8,
+ defineSpecial: 0 as *u8,
+ getGeneric: 0 as *u8,
+ getProperty: 0 as *u8,
+ getElement: 0 as *u8,
+ getElementIfPresent: 0 as *u8,
+ getSpecial: 0 as *u8,
+ setGeneric: 0 as *u8,
+ setProperty: 0 as *u8,
+ setElement: 0 as *u8,
+ setSpecial: 0 as *u8,
+ getGenericAttributes: 0 as *u8,
+ getPropertyAttributes: 0 as *u8,
+ getElementAttributes: 0 as *u8,
+ getSpecialAttributes: 0 as *u8,
+ setGenericAttributes: 0 as *u8,
+ setPropertyAttributes: 0 as *u8,
+ setElementAttributes: 0 as *u8,
+ setSpecialAttributes: 0 as *u8,
+ deleteProperty: 0 as *u8,
+ deleteElement: 0 as *u8,
+ deleteSpecial: 0 as *u8,
+
+ enumerate: 0 as *u8,
+ typeOf: 0 as *u8,
+ thisObject: %s,
+ clear: 0 as *u8,
+ },
},
dom_class: %s
};
@@ -1526,6 +1564,8 @@ static Class: DOMJSClass = DOMJSClass {
str_to_const_array(self.descriptor.interface.identifier.name),
flags, slots, slots,
FINALIZE_HOOK_NAME, traceHook,
+ self.descriptor.outerObjectHook,
+ self.descriptor.outerObjectHook,
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
def str_to_const_array(s):
@@ -1844,9 +1884,9 @@ def CreateBindingJSObject(descriptor, parent=None):
""" % (parent)
else:
if descriptor.createGlobal:
- create += " let obj = CreateDOMGlobal(aCx, &Class.base);\n"
+ create += " let obj = CreateDOMGlobal(aCx, &Class.base as *js::Class as *JSClass);\n"
else:
- create += " let obj = JS_NewObject(aCx, &Class.base, proto, %s);\n" % parent
+ create += " let obj = JS_NewObject(aCx, &Class.base as *js::Class as *JSClass, proto, %s);\n" % parent
create += """ assert!(obj.is_not_null());
JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32,
@@ -2139,41 +2179,41 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
#XXXjdm This self.descriptor.concrete check shouldn't be necessary
if not self.descriptor.concrete or self.descriptor.proxy:
body += """ let traps = ProxyTraps {
- getPropertyDescriptor: getPropertyDescriptor,
- getOwnPropertyDescriptor: getOwnPropertyDescriptor,
- defineProperty: defineProperty,
+ getPropertyDescriptor: Some(getPropertyDescriptor),
+ getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
+ defineProperty: Some(defineProperty),
getOwnPropertyNames: ptr::null(),
- delete_: ptr::null(),
+ delete_: None,
enumerate: ptr::null(),
- has: ptr::null(),
- hasOwn: hasOwn,
- get: get,
- set: ptr::null(),
+ has: None,
+ hasOwn: Some(hasOwn),
+ get: Some(get),
+ set: None,
keys: ptr::null(),
- iterate: ptr::null(),
+ iterate: None,
- call: ptr::null(),
- construct: ptr::null(),
+ call: None,
+ construct: None,
nativeCall: ptr::null(),
- hasInstance: ptr::null(),
- typeOf: ptr::null(),
- objectClassIs: ptr::null(),
- obj_toString: obj_toString,
- fun_toString: ptr::null(),
+ hasInstance: None,
+ typeOf: None,
+ objectClassIs: None,
+ obj_toString: Some(obj_toString),
+ fun_toString: None,
//regexp_toShared: ptr::null(),
- defaultValue: ptr::null(),
- iteratorNext: ptr::null(),
- finalize: %s,
- getElementIfPresent: ptr::null(),
- getPrototypeOf: ptr::null(),
- trace: %s
+ defaultValue: None,
+ iteratorNext: None,
+ finalize: Some(%s),
+ getElementIfPresent: None,
+ getPrototypeOf: None,
+ trace: Some(%s)
};
js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint,
CreateProxyHandler(&traps, cast::transmute(&Class)));
""" % (FINALIZE_HOOK_NAME,
- ('Some(%s)' % TRACE_HOOK_NAME),
+ TRACE_HOOK_NAME,
self.descriptor.name)
return (body + """ let cx = (**js_info.js_context).ptr;
@@ -4390,6 +4430,7 @@ class CGBindingRoot(CGThing):
#XXXjdm This should only import the namespace for the current binding,
# not every binding ever.
curr = CGImports(curr, [
+ 'js',
'js::{JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}',
'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}',
'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}',
@@ -4415,6 +4456,7 @@ class CGBindingRoot(CGThing):
'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'dom::types::*',
+ 'dom::bindings',
'dom::bindings::js::JS',
'dom::bindings::utils::{CreateDOMGlobal, CreateInterfaceObjects2}',
'dom::bindings::utils::{ConstantSpec, cx_for_dom_object, Default}',
diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py
index 4c78a14ff67..a1ccb460ee2 100644
--- a/src/components/script/dom/bindings/codegen/Configuration.py
+++ b/src/components/script/dom/bindings/codegen/Configuration.py
@@ -138,6 +138,7 @@ class Descriptor(DescriptorProvider):
self.needsAbstract = desc.get('needsAbstract', [])
self.createGlobal = desc.get('createGlobal', False)
self.register = desc.get('register', True)
+ self.outerObjectHook = desc.get('outerObjectHook', 'None')
# If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant.
diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs
index 4e32bacec68..29d774b7985 100644
--- a/src/components/script/dom/bindings/trace.rs
+++ b/src/components/script/dom/bindings/trace.rs
@@ -5,7 +5,7 @@
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector};
-use js::jsapi::{JSTracer, JS_CallTracer, JSTRACE_OBJECT};
+use js::jsapi::{JSObject, JSTracer, JS_CallTracer, JSTRACE_OBJECT};
use std::cast;
use std::cell::RefCell;
@@ -19,10 +19,15 @@ use serialize::{Encodable, Encoder};
// we are unfortunately required to use generic types everywhere and
// unsafely cast to the concrete JSTracer we actually require.
+fn get_jstracer<'a, S: Encoder>(s: &'a mut S) -> &'a mut JSTracer {
+ unsafe {
+ cast::transmute(s)
+ }
+}
+
impl<T: Reflectable+Encodable<S>, S: Encoder> Encodable<S> for JS<T> {
fn encode(&self, s: &mut S) {
- let s: &mut JSTracer = unsafe { cast::transmute(s) };
- trace_reflector(s, "", self.reflector());
+ trace_reflector(get_jstracer(s), "", self.reflector());
}
}
@@ -36,14 +41,17 @@ pub trait JSTraceable {
}
pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) {
+ trace_object(tracer, description, reflector.get_jsobject())
+}
+
+pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *JSObject) {
unsafe {
description.to_c_str().with_ref(|name| {
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
(*tracer).debugPrintArg = name as *libc::c_void;
debug!("tracing {:s}", description);
- JS_CallTracer(tracer as *JSTracer, reflector.get_jsobject(),
- JSTRACE_OBJECT as u32);
+ JS_CallTracer(tracer as *JSTracer, obj, JSTRACE_OBJECT as u32);
});
}
}
@@ -112,4 +120,10 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Traceable<RefCell<T>> {
fn encode(&self, s: &mut S) {
self.borrow().encode(s)
}
-} \ No newline at end of file
+}
+
+impl<S: Encoder> Encodable<S> for Traceable<*JSObject> {
+ fn encode(&self, s: &mut S) {
+ trace_object(get_jstracer(s), "object", **self)
+ }
+}
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 8aa26381e6f..c43c7f81193 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -4,9 +4,10 @@
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
-use dom::bindings::conversions::FromJSValConvertible;
+use dom::bindings::conversions::{FromJSValConvertible, IDLInterface};
use dom::bindings::js::JS;
use dom::bindings::trace::Untraceable;
+use dom::browsercontext;
use dom::window;
use servo_util::str::DOMString;
@@ -19,12 +20,14 @@ use std::ptr;
use std::ptr::null;
use std::slice;
use std::str;
-use js::glue::*;
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
+use js::glue::{GetGlobalForObjectCrossCompartment, UnwrapObject, GetProxyHandlerExtra};
+use js::glue::{IsWrapper, RUST_JSID_TO_STRING, RUST_JSID_IS_INT, RUST_INTERNED_STRING_TO_JSID};
+use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_INT};
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
use js::jsapi::{JS_DefineProperties, JS_ForwardGetPropertyTo};
use js::jsapi::{JS_GetClass, JS_LinkConstructorAndPrototype, JS_GetStringCharsAndLength};
-use js::jsapi::{JS_ObjectIsRegExp, JS_ObjectIsDate};
+use js::jsapi::{JS_ObjectIsRegExp, JS_ObjectIsDate, JSHandleObject};
use js::jsapi::{JS_InternString, JS_GetFunctionObject};
use js::jsapi::{JS_HasPropertyById, JS_GetPrototype};
use js::jsapi::{JS_GetProperty, JS_HasProperty};
@@ -46,12 +49,14 @@ use js;
#[deriving(Encodable)]
pub struct GlobalStaticData {
- proxy_handlers: Untraceable<HashMap<uint, *libc::c_void>>
+ proxy_handlers: Untraceable<HashMap<uint, *libc::c_void>>,
+ windowproxy_handler: Untraceable<*libc::c_void>,
}
pub fn GlobalStaticData() -> GlobalStaticData {
GlobalStaticData {
- proxy_handlers: Untraceable::new(HashMap::new())
+ proxy_handlers: Untraceable::new(HashMap::new()),
+ windowproxy_handler: Untraceable::new(browsercontext::new_window_proxy_handler()),
}
}
@@ -100,11 +105,29 @@ pub unsafe fn get_dom_class(obj: *JSObject) -> Result<DOMClass, ()> {
return Err(());
}
-pub fn unwrap_jsmanaged<T: Reflectable>(obj: *JSObject,
+pub fn unwrap_jsmanaged<T: Reflectable>(mut obj: *JSObject,
proto_id: PrototypeList::id::ID,
proto_depth: uint) -> Result<JS<T>, ()> {
unsafe {
- get_dom_class(obj).and_then(|dom_class| {
+ let dom_class = get_dom_class(obj).or_else(|_| {
+ if IsWrapper(obj) == 1 {
+ debug!("found wrapper");
+ obj = UnwrapObject(obj, /* stopAtOuter = */ 0, ptr::null());
+ if obj.is_null() {
+ debug!("unwrapping security wrapper failed");
+ Err(())
+ } else {
+ assert!(IsWrapper(obj) == 0);
+ debug!("unwrapped successfully");
+ get_dom_class(obj)
+ }
+ } else {
+ debug!("not a dom wrapper");
+ Err(())
+ }
+ });
+
+ dom_class.and_then(|dom_class| {
if dom_class.interface_chain[proto_depth] == proto_id {
debug!("good prototype");
Ok(JS::from_raw(unwrap(obj)))
@@ -178,7 +201,7 @@ pub struct DOMClass {
}
pub struct DOMJSClass {
- base: JSClass,
+ base: js::Class,
dom_class: DOMClass
}
@@ -560,6 +583,36 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject {
}
}
+pub extern fn wrap_for_same_compartment(cx: *JSContext, obj: *JSObject) -> *JSObject {
+ unsafe {
+ let clasp = JS_GetClass(obj);
+ let clasp = clasp as *js::Class;
+ match (*clasp).ext.outerObject {
+ Some(outerize) => {
+ debug!("found an outerize hook");
+ let obj = JSHandleObject { unnamed: &obj };
+ outerize(cx, obj)
+ }
+ None => {
+ debug!("no outerize hook found");
+ obj
+ }
+ }
+ }
+}
+
+pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject {
+ unsafe {
+ debug!("outerizing");
+ let obj = *obj.unnamed;
+ let win: JS<window::Window> =
+ unwrap_jsmanaged(obj,
+ IDLInterface::get_prototype_id(None::<window::Window>),
+ IDLInterface::get_prototype_depth(None::<window::Window>)).unwrap();
+ win.get().browser_context.get_ref().window_proxy()
+ }
+}
+
/// Returns the global object of the realm that the given JS object was created in.
pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
unsafe {
@@ -580,11 +633,6 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
}
}
-/// Returns the global object of the realm that the given DOM object was created in.
-pub fn global_object_for_dom_object<T: Reflectable>(obj: &T) -> JS<window::Window> {
- global_object_for_js_object(obj.reflector().get_jsobject())
-}
-
pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext {
cx_for_dom_reflector(obj.reflector().get_jsobject())
}
diff --git a/src/components/script/dom/browsercontext.rs b/src/components/script/dom/browsercontext.rs
new file mode 100644
index 00000000000..907a26f99e3
--- /dev/null
+++ b/src/components/script/dom/browsercontext.rs
@@ -0,0 +1,118 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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;
+use dom::bindings::trace::Traceable;
+use dom::bindings::utils::Reflectable;
+use dom::document::Document;
+use dom::window::Window;
+
+use js::jsapi::JSObject;
+use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
+
+use std::libc::c_void;
+use std::ptr;
+
+#[deriving(Encodable)]
+pub struct BrowserContext {
+ priv history: Vec<SessionHistoryEntry>,
+ priv active_index: uint,
+ priv window_proxy: Traceable<*JSObject>,
+}
+
+impl BrowserContext {
+ pub fn new(document: &JS<Document>) -> BrowserContext {
+ let mut context = BrowserContext {
+ history: vec!(SessionHistoryEntry::new(document)),
+ active_index: 0,
+ window_proxy: Traceable::new(ptr::null()),
+ };
+ context.window_proxy = Traceable::new(context.create_window_proxy());
+ context
+ }
+
+ pub fn active_document(&self) -> JS<Document> {
+ self.history.get(self.active_index).document.clone()
+ }
+
+ pub fn active_window(&self) -> JS<Window> {
+ let doc = self.active_document();
+ doc.get().window.clone()
+ }
+
+ pub fn window_proxy(&self) -> *JSObject {
+ assert!(self.window_proxy.deref().is_not_null());
+ *self.window_proxy
+ }
+
+ pub fn create_window_proxy(&self) -> *JSObject {
+ let win = self.active_window();
+ let page = win.get().page();
+ let js_info = page.js_info();
+
+ let handler = js_info.get_ref().dom_static.windowproxy_handler;
+ assert!(handler.deref().is_not_null());
+
+ let parent = win.get().reflector().get_jsobject();
+ let cx = js_info.get_ref().js_context.deref().deref().ptr;
+ let wrapper = unsafe {
+ WrapperNew(cx, parent, *handler.deref())
+ };
+ assert!(wrapper.is_not_null());
+ wrapper
+ }
+}
+
+#[deriving(Encodable)]
+pub struct SessionHistoryEntry {
+ priv document: JS<Document>,
+ priv children: Vec<BrowserContext>
+}
+
+impl SessionHistoryEntry {
+ fn new(document: &JS<Document>) -> SessionHistoryEntry {
+ SessionHistoryEntry {
+ document: document.clone(),
+ children: vec!()
+ }
+ }
+}
+
+static proxy_handler: ProxyTraps = ProxyTraps {
+ getPropertyDescriptor: None,
+ getOwnPropertyDescriptor: None,
+ defineProperty: None,
+ getOwnPropertyNames: 0 as *u8,
+ delete_: None,
+ enumerate: 0 as *u8,
+
+ has: None,
+ hasOwn: None,
+ get: None,
+ set: None,
+ keys: 0 as *u8,
+ iterate: None,
+
+ call: None,
+ construct: None,
+ nativeCall: 0 as *u8,
+ hasInstance: None,
+ typeOf: None,
+ objectClassIs: None,
+ obj_toString: None,
+ fun_toString: None,
+ //regexp_toShared: 0 as *u8,
+ defaultValue: None,
+ iteratorNext: None,
+ finalize: None,
+ getElementIfPresent: None,
+ getPrototypeOf: None,
+ trace: None
+};
+
+pub fn new_window_proxy_handler() -> *c_void {
+ unsafe {
+ CreateWrapperProxyHandler(&proxy_handler)
+ }
+}
diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs
index f953774bb5d..1a3346db360 100644
--- a/src/components/script/dom/eventtarget.rs
+++ b/src/components/script/dom/eventtarget.rs
@@ -5,7 +5,8 @@
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::bindings::error::{Fallible, InvalidState};
-use dom::bindings::codegen::EventListenerBinding::EventListener;
+use dom::bindings::codegen::EventListenerBinding;
+use self::EventListenerBinding::EventListener;
use dom::event::Event;
use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId;
diff --git a/src/components/script/dom/htmlframeelement.rs b/src/components/script/dom/htmlframeelement.rs
index 2d534ac6b44..f1cae62ca67 100644
--- a/src/components/script/dom/htmlframeelement.rs
+++ b/src/components/script/dom/htmlframeelement.rs
@@ -11,7 +11,7 @@ use dom::element::HTMLFrameElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
-use dom::windowproxy::WindowProxy;
+use dom::window::Window;
use servo_util::str::DOMString;
#[deriving(Encodable)]
@@ -94,7 +94,7 @@ impl HTMLFrameElement {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
+ pub fn GetContentWindow(&self) -> Option<JS<Window>> {
None
}
diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs
index d0f127fbc94..0b54fe3e3bb 100644
--- a/src/components/script/dom/htmliframeelement.rs
+++ b/src/components/script/dom/htmliframeelement.rs
@@ -14,7 +14,7 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use dom::virtualmethods::VirtualMethods;
-use dom::windowproxy::WindowProxy;
+use dom::window::Window;
use servo_util::str::DOMString;
use servo_msg::constellation_msg::{PipelineId, SubpageId};
@@ -143,7 +143,7 @@ impl HTMLIFrameElement {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
+ pub fn GetContentWindow(&self) -> Option<JS<Window>> {
None
}
diff --git a/src/components/script/dom/htmlobjectelement.rs b/src/components/script/dom/htmlobjectelement.rs
index 6288dcfc33d..c98432b99a0 100644
--- a/src/components/script/dom/htmlobjectelement.rs
+++ b/src/components/script/dom/htmlobjectelement.rs
@@ -16,7 +16,7 @@ use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
-use dom::windowproxy::WindowProxy;
+use dom::window::Window;
use servo_util::str::DOMString;
use servo_net::image_cache_task;
@@ -135,7 +135,7 @@ impl HTMLObjectElement {
None
}
- pub fn GetContentWindow(&self) -> Option<JS<WindowProxy>> {
+ pub fn GetContentWindow(&self) -> Option<JS<Window>> {
None
}
diff --git a/src/components/script/dom/mouseevent.rs b/src/components/script/dom/mouseevent.rs
index a261de252d7..ff3c261684c 100644
--- a/src/components/script/dom/mouseevent.rs
+++ b/src/components/script/dom/mouseevent.rs
@@ -11,7 +11,6 @@ use dom::event::{Event, MouseEventTypeId};
use dom::eventtarget::EventTarget;
use dom::uievent::UIEvent;
use dom::window::Window;
-use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString;
#[deriving(Encodable)]
@@ -124,7 +123,7 @@ impl MouseEvent {
typeArg: DOMString,
canBubbleArg: bool,
cancelableArg: bool,
- viewArg: Option<JS<WindowProxy>>,
+ viewArg: Option<JS<Window>>,
detailArg: i32,
screenXArg: i32,
screenYArg: i32,
diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs
index 363db6e0ee0..6a2b2bba8a7 100644
--- a/src/components/script/dom/testbinding.rs
+++ b/src/components/script/dom/testbinding.rs
@@ -4,8 +4,9 @@
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflector, Reflectable};
-use dom::bindings::codegen::TestBindingBinding::TestEnum;
-use dom::bindings::codegen::TestBindingBinding::TestEnumValues::_empty;
+use dom::bindings::codegen::TestBindingBinding;
+use self::TestBindingBinding::TestEnum;
+use self::TestBindingBinding::TestEnumValues::_empty;
use dom::blob::Blob;
use dom::window::Window;
use servo_util::str::DOMString;
diff --git a/src/components/script/dom/uievent.rs b/src/components/script/dom/uievent.rs
index 46ca3736fc3..7411c678e55 100644
--- a/src/components/script/dom/uievent.rs
+++ b/src/components/script/dom/uievent.rs
@@ -10,13 +10,14 @@ use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, EventTypeId, UIEventTypeId};
use dom::node::Node;
use dom::window::Window;
-use dom::windowproxy::WindowProxy;
use servo_util::str::DOMString;
+use serialize::{Encoder, Encodable};
+
#[deriving(Encodable)]
pub struct UIEvent {
event: Event,
- view: Option<JS<WindowProxy>>,
+ view: Option<JS<Window>>,
detail: i32
}
@@ -50,7 +51,7 @@ impl UIEvent {
Ok(ev)
}
- pub fn GetView(&self) -> Option<JS<WindowProxy>> {
+ pub fn GetView(&self) -> Option<JS<Window>> {
self.view.clone()
}
@@ -62,7 +63,7 @@ impl UIEvent {
type_: DOMString,
can_bubble: bool,
cancelable: bool,
- view: Option<JS<WindowProxy>>,
+ view: Option<JS<Window>>,
detail: i32) {
self.event.InitEvent(type_, can_bubble, cancelable);
self.view = view;
diff --git a/src/components/script/dom/webidls/HTMLFrameElement.webidl b/src/components/script/dom/webidls/HTMLFrameElement.webidl
index 845fbe3bf2e..f1c78606b02 100644
--- a/src/components/script/dom/webidls/HTMLFrameElement.webidl
+++ b/src/components/script/dom/webidls/HTMLFrameElement.webidl
@@ -25,7 +25,7 @@ interface HTMLFrameElement : HTMLElement {
[SetterThrows]
attribute boolean noResize;
readonly attribute Document? contentDocument;
- readonly attribute WindowProxy? contentWindow;
+ readonly attribute Window? contentWindow;
[TreatNullAs=EmptyString, SetterThrows] attribute DOMString marginHeight;
[TreatNullAs=EmptyString, SetterThrows] attribute DOMString marginWidth;
diff --git a/src/components/script/dom/webidls/HTMLIFrameElement.webidl b/src/components/script/dom/webidls/HTMLIFrameElement.webidl
index 873563e139a..09d81a27102 100644
--- a/src/components/script/dom/webidls/HTMLIFrameElement.webidl
+++ b/src/components/script/dom/webidls/HTMLIFrameElement.webidl
@@ -27,7 +27,7 @@ interface HTMLIFrameElement : HTMLElement {
[SetterThrows, Pure]
attribute DOMString height;
readonly attribute Document? contentDocument;
- readonly attribute WindowProxy? contentWindow;
+ readonly attribute Window? contentWindow;
};
// http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis
diff --git a/src/components/script/dom/webidls/HTMLObjectElement.webidl b/src/components/script/dom/webidls/HTMLObjectElement.webidl
index ab38d47dd3f..97b25b9cfc3 100644
--- a/src/components/script/dom/webidls/HTMLObjectElement.webidl
+++ b/src/components/script/dom/webidls/HTMLObjectElement.webidl
@@ -32,7 +32,7 @@ interface HTMLObjectElement : HTMLElement {
// Not pure: can trigger about:blank instantiation
readonly attribute Document? contentDocument;
// Not pure: can trigger about:blank instantiation
- readonly attribute WindowProxy? contentWindow;
+ readonly attribute Window? contentWindow;
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
diff --git a/src/components/script/dom/webidls/MouseEvent.webidl b/src/components/script/dom/webidls/MouseEvent.webidl
index 5bb4a84a90a..1886b7b02c5 100644
--- a/src/components/script/dom/webidls/MouseEvent.webidl
+++ b/src/components/script/dom/webidls/MouseEvent.webidl
@@ -26,7 +26,7 @@ interface MouseEvent : UIEvent {
void initMouseEvent(DOMString typeArg,
boolean canBubbleArg,
boolean cancelableArg,
- WindowProxy? viewArg,
+ Window? viewArg,
long detailArg,
long screenXArg,
long screenYArg,
@@ -56,7 +56,7 @@ dictionary MouseEventInit {
boolean cancelable = false;
// Attributes from UIEvent:
- WindowProxy? view = null;
+ Window? view = null;
long detail = 0;
// Attributes for MouseEvent:
diff --git a/src/components/script/dom/webidls/UIEvent.webidl b/src/components/script/dom/webidls/UIEvent.webidl
index c6e2dc02c6d..16da6448724 100644
--- a/src/components/script/dom/webidls/UIEvent.webidl
+++ b/src/components/script/dom/webidls/UIEvent.webidl
@@ -13,12 +13,12 @@
[Constructor(DOMString type, optional UIEventInit eventInitDict)]
interface UIEvent : Event
{
- readonly attribute WindowProxy? view;
- readonly attribute long detail;
+ readonly attribute Window? view;
+ readonly attribute long detail;
void initUIEvent(DOMString aType,
boolean aCanBubble,
boolean aCancelable,
- WindowProxy? aView,
+ Window? aView,
long aDetail);
};
@@ -40,6 +40,6 @@ partial interface UIEvent {
dictionary UIEventInit : EventInit
{
- WindowProxy? view = null;
- long detail = 0;
+ Window? view = null;
+ long detail = 0;
};
diff --git a/src/components/script/dom/webidls/Window.webidl b/src/components/script/dom/webidls/Window.webidl
index 2405055c15c..1a9a2d60440 100644
--- a/src/components/script/dom/webidls/Window.webidl
+++ b/src/components/script/dom/webidls/Window.webidl
@@ -10,8 +10,8 @@
[NamedPropertiesObject]
/*sealed*/ interface Window : EventTarget {
// the current browsing context
- /*[Unforgeable] readonly attribute WindowProxy window;
- [Replaceable] readonly attribute WindowProxy self;*/
+ [Unforgeable] readonly attribute Window window;
+ [Replaceable] readonly attribute Window self;
[Unforgeable] readonly attribute Document document;
attribute DOMString name;
/* [PutForwards=href, Unforgeable] */ readonly attribute Location location;
@@ -30,14 +30,14 @@
void blur();
// other browsing contexts
- /*[Replaceable] readonly attribute WindowProxy frames;
+ /*[Replaceable] readonly attribute Window frames;
[Replaceable] readonly attribute unsigned long length;
- [Unforgeable] readonly attribute WindowProxy top;
- attribute WindowProxy? opener;
- readonly attribute WindowProxy parent;*/
+ [Unforgeable] readonly attribute Window top;
+ attribute Window? opener;
+ readonly attribute Window parent;*/
readonly attribute Element? frameElement;
- /*WindowProxy open(optional DOMString url = "about:blank", optional DOMString target = "_blank", optional DOMString features = "", optional boolean replace = false);
- getter WindowProxy (unsigned long index);*/
+ /*Window open(optional DOMString url = "about:blank", optional DOMString target = "_blank", optional DOMString features = "", optional boolean replace = false);
+ getter Window (unsigned long index);*/
//getter object (DOMString name);
// the user agent
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index 04a117650d1..54575882ed3 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -6,6 +6,7 @@ use dom::bindings::codegen::WindowBinding;
use dom::bindings::js::JS;
use dom::bindings::trace::Untraceable;
use dom::bindings::utils::{Reflectable, Reflector};
+use dom::browsercontext::BrowserContext;
use dom::document::Document;
use dom::element::Element;
use dom::eventtarget::{EventTarget, WindowTypeId};
@@ -20,9 +21,8 @@ use servo_net::image_cache_task::ImageCacheTask;
use servo_util::str::DOMString;
use servo_util::task::{spawn_named};
-use js::jsapi::{JSContext, JS_DefineProperty, JS_PropertyStub, JS_StrictPropertyStub};
-use js::jsval::{NullValue, ObjectValue, JSVal};
-use js::JSPROP_ENUMERATE;
+use js::jsapi::JSContext;
+use js::jsval::{NullValue, JSVal};
use collections::hashmap::HashMap;
use std::cmp;
@@ -87,6 +87,7 @@ pub struct Window {
next_timer_handle: i32,
compositor: Untraceable<~ScriptListener>,
timer_chan: Untraceable<Sender<TimerControlMsg>>,
+ browser_context: Option<BrowserContext>,
page: Rc<Page>,
}
@@ -290,6 +291,14 @@ impl Window {
self.ClearTimeout(handle);
}
+ pub fn Window(&self, abstract_self: &JS<Window>) -> JS<Window> {
+ abstract_self.clone()
+ }
+
+ pub fn Self(&self, abstract_self: &JS<Window>) -> JS<Window> {
+ self.Window(abstract_self)
+ }
+
pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) {
// FIXME This should probably be ReflowForQuery, not Display. All queries currently
// currently rely on the display list, which means we can't destroy it by
@@ -304,6 +313,10 @@ impl Window {
self.page().join_layout();
}
+ pub fn init_browser_context(&mut self, doc: &JS<Document>) {
+ self.browser_context = Some(BrowserContext::new(doc));
+ }
+
pub fn new(cx: *JSContext,
page: Rc<Page>,
script_chan: ScriptChan,
@@ -335,25 +348,10 @@ impl Window {
navigator: None,
image_cache_task: image_cache_task,
active_timers: ~HashMap::new(),
- next_timer_handle: 0
+ next_timer_handle: 0,
+ browser_context: None,
};
- let global = WindowBinding::Wrap(cx, win);
- let fn_names = ["window", "self"];
- for str in fn_names.iter() {
- (*str).to_c_str().with_ref(|name| {
- let object = global.reflector().get_jsobject();
- assert!(object.is_not_null());
- unsafe {
- JS_DefineProperty(cx, object, name,
- ObjectValue(&*object),
- Some(JS_PropertyStub),
- Some(JS_StrictPropertyStub),
- JSPROP_ENUMERATE);
- }
- })
-
- }
- global
+ WindowBinding::Wrap(cx, win)
}
}
diff --git a/src/components/script/dom/windowproxy.rs b/src/components/script/dom/windowproxy.rs
deleted file mode 100644
index dc1e0092f36..00000000000
--- a/src/components/script/dom/windowproxy.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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::codegen::WindowProxyBinding;
-use dom::bindings::js::JS;
-use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
-use dom::window::Window;
-
-#[deriving(Encodable)]
-pub struct WindowProxy {
- reflector_: Reflector
-}
-
-impl WindowProxy {
- pub fn new(owner: &JS<Window>) -> JS<WindowProxy> {
- let proxy = ~WindowProxy {
- reflector_: Reflector::new()
- };
- reflect_dom_object(proxy, owner, WindowProxyBinding::Wrap)
- }
-}
-
-impl Reflectable for WindowProxy {
- fn reflector<'a>(&'a self) -> &'a Reflector {
- &self.reflector_
- }
-
- fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
- &mut self.reflector_
- }
-}
diff --git a/src/components/script/script.rs b/src/components/script/script.rs
index 7b9f63c4dc4..7cbb2c28d1f 100644
--- a/src/components/script/script.rs
+++ b/src/components/script/script.rs
@@ -59,6 +59,7 @@ pub mod dom {
pub mod attr;
pub mod attrlist;
pub mod blob;
+ pub mod browsercontext;
pub mod characterdata;
pub mod clientrect;
pub mod clientrectlist;
@@ -157,7 +158,6 @@ pub mod dom {
pub mod validitystate;
pub mod virtualmethods;
pub mod window;
- pub mod windowproxy;
pub mod testbinding;
}
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index 4e7a30705b0..159a9e57a37 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -9,7 +9,7 @@ use dom::bindings::codegen::RegisterBindings;
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, ElementCast, EventCast};
use dom::bindings::js::JS;
use dom::bindings::trace::{Traceable, Untraceable};
-use dom::bindings::utils::{Reflectable, GlobalStaticData, with_gc_enabled};
+use dom::bindings::utils::{Reflectable, GlobalStaticData, with_gc_enabled, wrap_for_same_compartment};
use dom::document::{Document, HTMLDocument};
use dom::element::{Element, AttributeHandlers};
use dom::event::{Event_, ResizeEvent, ReflowEvent, ClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent};
@@ -18,7 +18,6 @@ use dom::uievent::UIEvent;
use dom::eventtarget::EventTarget;
use dom::node::{Node, NodeHelpers};
use dom::window::{TimerData, Window};
-use dom::windowproxy::WindowProxy;
use html::hubbub_html_parser::HtmlParserResult;
use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript};
use html::hubbub_html_parser;
@@ -34,6 +33,7 @@ use geom::point::Point2D;
use geom::size::Size2D;
use js::global::DEBUG_FNS;
use js::jsapi::{JSObject, JS_InhibitGC, JS_AllowGC, JS_CallFunctionValue, JS_DefineFunctions};
+use js::jsapi::JS_SetWrapObjectCallbacks;
use js::jsval::NullValue;
use js::rust::{Cx, RtUtils};
use js;
@@ -499,6 +499,13 @@ impl ScriptTask {
-> Rc<ScriptTask> {
let js_runtime = js::rust::rt();
+ unsafe {
+ JS_SetWrapObjectCallbacks(js_runtime.deref().ptr,
+ ptr::null(),
+ wrap_for_same_compartment,
+ ptr::null());
+ }
+
Rc::new(ScriptTask {
page_tree: RefCell::new(PageTree::new(id, layout_chan, window_size)),
@@ -785,12 +792,14 @@ impl ScriptTask {
let cx = self.js_runtime.cx();
// Create the window and document objects.
- let window = Window::new(cx.deref().ptr,
- page_tree.page.clone(),
- self.chan.clone(),
- self.compositor.dup(),
- self.image_cache_task.clone());
+ let mut window = Window::new(cx.deref().ptr,
+ page_tree.page.clone(),
+ self.chan.clone(),
+ self.compositor.dup(),
+ self.image_cache_task.clone());
page.initialize_js_info(cx.clone(), window.reflector().get_jsobject());
+ let mut document = Document::new(&window, Some(url.clone()), HTMLDocument, None);
+ window.get_mut().init_browser_context(&document);
{
let mut js_info = page.mut_js_info();
@@ -801,7 +810,6 @@ impl ScriptTask {
// Parse HTML.
//
// Note: We can parse the next document in parallel with any previous documents.
- let mut document = Document::new(&window, Some(url.clone()), HTMLDocument, None);
let html_parsing_result = hubbub_html_parser::parse_html(page,
&mut document,
url.clone(),
@@ -958,12 +966,10 @@ impl ScriptTask {
Some(ref frame) => {
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
- let window_proxy: JS<WindowProxy> = WindowProxy::new(&frame.window);
let mut uievent = UIEvent::new(&frame.window);
- uievent.get_mut().InitUIEvent(~"resize", false, false, Some(window_proxy), 0i32);
+ uievent.get_mut().InitUIEvent(~"resize", false, false, Some(frame.window.clone()), 0i32);
let event: &mut JS<Event> = &mut EventCast::from(&uievent);
- // FIXME: this event should be dispatch on WindowProxy. See #1715
let mut wintarget: JS<EventTarget> = EventTargetCast::from(&frame.window);
let winclone = wintarget.clone();
let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, None, event);
diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs
-Subproject 9f0ae0ab33f786c9d2d5e1a9fdfdc6c07fa9803
+Subproject 70d3c9c7071053a8c497ef4d4fdc24bf95ec9f1