mirror of
https://github.com/servo/servo.git
synced 2025-06-13 10:54:29 +00:00
Remove all traces of WindowProxy. Implement basic browser context concept and outerizing of inner windows.
This commit is contained in:
parent
c760577aee
commit
94dffca1e1
24 changed files with 354 additions and 155 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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}',
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -113,3 +121,9 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Traceable<RefCell<T>> {
|
|||
self.borrow().encode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for Traceable<*JSObject> {
|
||||
fn encode(&self, s: &mut S) {
|
||||
trace_object(get_jstracer(s), "object", **self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
118
src/components/script/dom/browsercontext.rs
Normal file
118
src/components/script/dom/browsercontext.rs
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
[Constructor(DOMString type, optional UIEventInit eventInitDict)]
|
||||
interface UIEvent : Event
|
||||
{
|
||||
readonly attribute WindowProxy? view;
|
||||
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;
|
||||
Window? view = null;
|
||||
long detail = 0;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
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);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9f0ae0ab33f786c9d2d5e1a9fdfdc6c07fa98033
|
||||
Subproject commit 70d3c9c7071053a8c497ef4d4fdc24bf95ec9f10
|
Loading…
Add table
Add a link
Reference in a new issue