diff options
author | Josh Matthews <josh@joshmatthews.net> | 2013-10-21 08:11:18 +0100 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-04-22 10:57:25 -0400 |
commit | 94dffca1e165eb5504feda42e89015648b484b78 (patch) | |
tree | 333bc6894ead07d5b7d6c222ae4d050e174f4c7a | |
parent | c760577aee3ca31e58b4dd2b7f919d14fcaa2d2f (diff) | |
download | servo-94dffca1e165eb5504feda42e89015648b484b78.tar.gz servo-94dffca1e165eb5504feda42e89015648b484b78.zip |
Remove all traces of WindowProxy. Implement basic browser context concept and outerizing of inner windows.
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 |