Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WindowProxy support and basic browsing context concept. #1818

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Prev

Make a singleton proxy handler per script task. Make use of the new o…

…uterization hook.
  • Loading branch information
jdm committed Apr 15, 2014
commit d4e519d2e08d6f98da3bb7296797b60d65fb13e4
@@ -112,6 +112,10 @@ DOMInterfaces = {
'ValidityState': {},
'Window': {
'createGlobal': True,
'classHooks': {
'outerObject': 'Some(bindings::utils::outerize_global)',
'thisObject': 'Some(bindings::utils::outerize_global)',
},
'needsAbstract': [
'console',
'location',
@@ -1545,7 +1545,8 @@ def define(self):
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),
@@ -1560,21 +1561,60 @@ def define(self):
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
};
""" % (len(self.descriptor.interface.identifier.name) + 1,
str_to_const_array(self.descriptor.interface.identifier.name),
flags, slots, slots,
FINALIZE_HOOK_NAME, traceHook,
self.descriptor.classHooks['outerObject'],
self.descriptor.classHooks['thisObject'],
CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())

def str_to_const_array(s):
@@ -1893,9 +1933,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,
@@ -2162,31 +2202,31 @@ def definition_body(self):
getPropertyDescriptor: Some(getPropertyDescriptor),
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
defineProperty: Some(defineProperty),
getOwnPropertyNames: ptr::null(),
delete_: ptr::null(),
enumerate: ptr::null(),
getOwnPropertyNames: 0 as *u8,
delete_: None,
enumerate: 0 as *u8,
has: None,
hasOwn: Some(hasOwn),
get: Some(get),
set: ptr::null(),
keys: ptr::null(),
iterate: ptr::null(),
set: None,
keys: 0 as *u8,
iterate: None,
call: ptr::null(),
construct: ptr::null(),
call: None,
construct: None,
nativeCall: ptr::null(),
hasInstance: ptr::null(),
typeOf: ptr::null(),
objectClassIs: ptr::null(),
hasInstance: None,
typeOf: None,
objectClassIs: None,
obj_toString: Some(obj_toString),
fun_toString: ptr::null(),
fun_toString: None,
//regexp_toShared: ptr::null(),
defaultValue: ptr::null(),
iteratorNext: ptr::null(),
defaultValue: None,
iteratorNext: None,
finalize: Some(%s),
getElementIfPresent: ptr::null(),
getPrototypeOf: ptr::null(),
getElementIfPresent: None,
getPrototypeOf: None,
trace: Some(%s)
};
js_info.dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint,
@@ -4472,6 +4512,7 @@ def __init__(self, config, prefix, webIDLFile):
#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}',
@@ -4497,6 +4538,7 @@ def __init__(self, config, prefix, webIDLFile):
'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}',
@@ -2,6 +2,8 @@
# 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/.

from collections import defaultdict

autogenerated_comment = "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n"

class Configuration:
@@ -139,6 +141,7 @@ def __init__(self, config, interface, desc):
self.needsAbstract = desc.get('needsAbstract', [])
self.createGlobal = desc.get('createGlobal', False)
self.register = desc.get('register', True)
self.classHooks = desc.get('classHooks', defaultdict(lambda: 'None'))

# If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant.
@@ -5,6 +5,7 @@
use dom::bindings::codegen::PrototypeList;
use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
use dom::bindings::js::JS;
use dom::browsercontext;
use dom::window;
use servo_util::str::DOMString;

@@ -44,12 +45,14 @@ use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY};
use js;

pub struct GlobalStaticData {
proxy_handlers: HashMap<uint, *libc::c_void>
proxy_handlers: HashMap<uint, *libc::c_void>,
windowproxy_handler: *libc::c_void,
}

pub fn GlobalStaticData() -> GlobalStaticData {
GlobalStaticData {
proxy_handlers: HashMap::new()
proxy_handlers: HashMap::new(),
windowproxy_handler: browsercontext::new_window_proxy_handler()
}
}

@@ -205,7 +208,7 @@ pub struct DOMClass {
}

pub struct DOMJSClass {
base: JSClass,
base: js::Class,
dom_class: DOMClass
}

@@ -558,7 +561,10 @@ pub extern fn wrap_for_same_compartment(cx: *JSContext, obj: *JSObject) -> *JSOb
let obj = JSHandleObject { unnamed: &obj };
outerize(cx, obj)
}
None => obj
None => {
debug!("no outerize hook found");
obj
}
}
}
}
@@ -3,14 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::js::JS;
use dom::bindings::proxyhandler::_obj_toString;
use dom::bindings::trace::trace_object;
use dom::bindings::utils::Reflectable;
use dom::document::Document;
use dom::window::Window;
use dom::windowproxy::WindowProxy;

use js::jsapi::{JSContext, JSObject, JSString, JSTracer};
use js::jsapi::{JSObject, JSTracer};
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};

use std::cast;
@@ -26,7 +25,6 @@ pub struct BrowserContext {
}

struct Untraceable {
proxy_handler: *c_void,
window_proxy: *JSObject,
}

@@ -38,12 +36,11 @@ impl<S: Encoder> Encodable<S> for Untraceable {
}

impl BrowserContext {
pub fn new(document: JS<Document>) -> BrowserContext {
pub fn new(document: &JS<Document>) -> BrowserContext {
let mut context = BrowserContext {
history: ~[SessionHistoryEntry::new(document)],
active_index: 0,
extra: Untraceable {
proxy_handler: new_window_proxy_handler(),
window_proxy: ptr::null(),
},
};
@@ -66,16 +63,17 @@ impl BrowserContext {
}

pub fn create_window_proxy(&self) -> WindowProxy {
assert!(self.extra.proxy_handler.is_not_null());

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.is_not_null());

let parent = win.get().reflector().get_jsobject();
let cx = js_info.get_ref().js_context.deref().ptr;
unsafe {
WrapperNew(cx, parent, self.extra.proxy_handler)
WrapperNew(cx, parent, handler)
}
}
}
@@ -87,53 +85,48 @@ pub struct SessionHistoryEntry {
}

impl SessionHistoryEntry {
fn new(document: JS<Document>) -> SessionHistoryEntry {
fn new(document: &JS<Document>) -> SessionHistoryEntry {
SessionHistoryEntry {
document: document,
document: document.clone(),
children: ~[]
}
}
}

extern fn obj_toString(cx: *JSContext, _proxy: *JSObject) -> *JSString {
"Window".to_c_str().with_ref(|s| {
_obj_toString(cx, s)
})
}

fn new_window_proxy_handler() -> *c_void {
let traps = ProxyTraps {
getPropertyDescriptor: None,
getOwnPropertyDescriptor: None,
defineProperty: None,
getOwnPropertyNames: ptr::null(),
delete_: ptr::null(),
enumerate: ptr::null(),

has: None,
hasOwn: None,
get: None,
set: ptr::null(),
keys: ptr::null(),
iterate: ptr::null(),

call: ptr::null(),
construct: ptr::null(),
nativeCall: ptr::null(),
hasInstance: ptr::null(),
typeOf: ptr::null(),
objectClassIs: ptr::null(),
obj_toString: Some(obj_toString),
fun_toString: ptr::null(),
//regexp_toShared: ptr::null(),
defaultValue: ptr::null(),
iteratorNext: ptr::null(),
finalize: None,
getElementIfPresent: ptr::null(),
getPrototypeOf: ptr::null(),
trace: None
};
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(&traps)
CreateWrapperProxyHandler(&proxy_handler)
}
}
@@ -270,7 +270,7 @@ impl Window {
}

pub fn Window(&mut self) -> WindowProxy {
self.browser_context.get_mut_ref().window_proxy()
self.browser_context.get_ref().window_proxy()
}

pub fn Self(&mut self) -> WindowProxy {
@@ -291,7 +291,7 @@ impl Window {
self.page().join_layout();
}

pub fn init_browser_context(&mut self, doc: JS<Document>) {
pub fn init_browser_context(&mut self, doc: &JS<Document>) {
self.browser_context = Some(BrowserContext::new(doc));
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.