aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script')
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py290
-rw-r--r--src/components/script/dom/bindings/codegen/Configuration.py1
-rw-r--r--src/components/script/dom/bindings/proxyhandler.rs89
-rw-r--r--src/components/script/dom/bindings/utils.rs8
-rw-r--r--src/components/script/dom/document.rs16
-rw-r--r--src/components/script/dom/htmlcollection.rs4
-rw-r--r--src/components/script/dom/htmldocument.rs4
-rw-r--r--src/components/script/dom/window.rs4
8 files changed, 370 insertions, 46 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 1c177e2e8ea..5666e177d14 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1435,8 +1435,8 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
if not callWrapValue:
tail = successCode
elif haveSuccessCode:
- tail = ("if (!JS_WrapValue(cx, ${jsvalPtr})) {\n" +
- " return false;\n" +
+ tail = ("if JS_WrapValue(cx, ${jsvalPtr}) == 0 {\n" +
+ " return 0;\n" +
"}\n" +
successCode)
else:
@@ -1527,7 +1527,7 @@ for (uint32_t i = 0; i < length; ++i) {
properResult = result + ".as_cacheable_wrapper()"
else:
properResult += " as @mut CacheableWrapper"
- wrap = "%s(cx, ${obj}, %s, ${jsvalPtr})" % (wrapMethod, properResult)
+ wrap = "%s(cx, ${obj}, %s, ${jsvalPtr} as *mut JSVal)" % (wrapMethod, properResult)
# We don't support prefable stuff in workers.
assert(not descriptor.prefable or not descriptor.workers)
if not descriptor.prefable:
@@ -1547,7 +1547,7 @@ for (uint32_t i = 0; i < length; ++i) {
else:
#wrap = "WrapObject(cx, ${obj}, %s, %s${jsvalPtr})" % (result, getIID)
if descriptor.pointerType == '':
- wrap = "%s.wrap(cx, ${obj}, ${jsvalPtr})" % result
+ wrap = "(%s.wrap(cx, ${obj}, ${jsvalPtr}) as bool)" % result
else:
wrap = "if WrapNewBindingObject(cx, ${obj}, %s as @mut CacheableWrapper, ${jsvalPtr}) { 1 } else { 0 };" % result
wrappingCode += wrapAndSetPtr(wrap)
@@ -2815,13 +2815,13 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
body += """ let traps = ProxyTraps {
getPropertyDescriptor: getPropertyDescriptor,
getOwnPropertyDescriptor: getOwnPropertyDescriptor,
- defineProperty: ptr::null(),
+ defineProperty: defineProperty,
getOwnPropertyNames: ptr::null(),
delete_: ptr::null(),
enumerate: ptr::null(),
has: ptr::null(),
- hasOwn: ptr::null(),
+ hasOwn: hasOwn,
get: get,
set: ptr::null(),
keys: ptr::null(),
@@ -3233,8 +3233,8 @@ class CGGenericGetter(CGAbstractBindingMethod):
def generate_code(self):
return CGIndenter(CGGeneric(
- "let _info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "return CallJitPropertyOp(_info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, vp);"))
+ "let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
+ "return CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, vp);"))
class CGSpecializedGetter(CGAbstractExternMethod):
"""
@@ -3289,7 +3289,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
"let undef = JSVAL_VOID;\n"
"let argv: *JSVal = if argc != 0 { JS_ARGV(cx, cast::transmute(vp)) } else { &undef as *JSVal };\n"
"let info: *JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, cast::transmute(vp)));\n"
- "if CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, cast::transmute(vp)) == 0 {"
+ "if CallJitPropertyOp(info, cx, obj, ptr::to_unsafe_ptr(&(*this).payload) as *libc::c_void, argv) == 0 {"
" return 0;\n"
"}\n"
"*vp = JSVAL_VOID;\n"
@@ -3555,10 +3555,33 @@ class CGProxyIndexedGetter(CGProxySpecialOperation):
self.templateValues = templateValues
CGProxySpecialOperation.__init__(self, descriptor, 'IndexedGetter')
+class CGProxyIndexedSetter(CGProxySpecialOperation):
+ """
+ Class to generate a call to an indexed setter.
+ """
+ def __init__(self, descriptor):
+ CGProxySpecialOperation.__init__(self, descriptor, 'IndexedSetter')
+
+class CGProxyNamedGetter(CGProxySpecialOperation):
+ """
+ Class to generate a call to an named getter. If templateValues is not None
+ the returned value will be wrapped with wrapForType using templateValues.
+ """
+ def __init__(self, descriptor, templateValues=None):
+ self.templateValues = templateValues
+ CGProxySpecialOperation.__init__(self, descriptor, 'NamedGetter')
+
+class CGProxyNamedSetter(CGProxySpecialOperation):
+ """
+ Class to generate a call to a named setter.
+ """
+ def __init__(self, descriptor):
+ CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter')
+
class CGProxyUnwrap(CGAbstractMethod):
def __init__(self, descriptor):
args = [Argument('*JSObject', 'obj')]
- CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*' + descriptor.nativeType, args, alwaysInline=True)
+ CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*' + descriptor.concreteType, args, alwaysInline=True)
def declare(self):
return ""
def definition_body(self):
@@ -3567,7 +3590,241 @@ class CGProxyUnwrap(CGAbstractMethod):
}*/
//MOZ_ASSERT(IsProxy(obj));
let box: *rust_box<%s> = cast::transmute(RUST_JSVAL_TO_PRIVATE(GetProxyPrivate(obj)));
- return ptr::to_unsafe_ptr(&(*box).payload);""" % (self.descriptor.nativeType)
+ return ptr::to_unsafe_ptr(&(*box).payload);""" % (self.descriptor.concreteType)
+
+class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
+ def __init__(self, descriptor):
+ args = [Argument('*JSContext', 'cx'), Argument('*JSObject', 'proxy'),
+ Argument('jsid', 'id'), Argument('JSBool', 'set'),
+ Argument('*mut JSPropertyDescriptor', 'desc')]
+ CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
+ "JSBool", args)
+ self.descriptor = descriptor
+ def getBody(self):
+ indexedGetter = self.descriptor.operations['IndexedGetter']
+ indexedSetter = self.descriptor.operations['IndexedSetter']
+
+ setOrIndexedGet = ""
+ if indexedGetter or indexedSetter:
+ setOrIndexedGet += "let index = GetArrayIndexFromId(cx, id);\n"
+
+ if indexedGetter:
+ readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
+ fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
+ templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_mut_unsafe_ptr(&mut (*desc).value)',
+ 'obj': 'proxy', 'successCode': fillDescriptor}
+ get = ("if index.is_some() {\n" +
+ " let index = index.get();\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
+ "}\n") % (self.descriptor.concreteType)
+
+ if indexedSetter or self.descriptor.operations['NamedSetter']:
+ setOrIndexedGet += "if set != 0 {\n"
+ if indexedSetter:
+ setOrIndexedGet += (" if index.is_some() {\n" +
+ " let index = index.get();\n")
+ if not 'IndexedCreator' in self.descriptor.operations:
+ # FIXME need to check that this is a 'supported property index'
+ assert False
+ setOrIndexedGet += (" FillPropertyDescriptor(&mut *desc, proxy, JSVAL_VOID, false);\n" +
+ " return 1;\n" +
+ " }\n")
+ if self.descriptor.operations['NamedSetter']:
+ setOrIndexedGet += " if RUST_JSID_IS_STRING(id) {\n"
+ if not 'NamedCreator' in self.descriptor.operations:
+ # FIXME need to check that this is a 'supported property name'
+ assert False
+ setOrIndexedGet += (" FillPropertyDescriptor(&mut *desc, proxy, JSVAL_VOID, false);\n" +
+ " return 1;\n" +
+ " }\n")
+ setOrIndexedGet += "}"
+ if indexedGetter:
+ setOrIndexedGet += (" else {\n" +
+ CGIndenter(CGGeneric(get)).define() +
+ "}")
+ setOrIndexedGet += "\n\n"
+ elif indexedGetter:
+ setOrIndexedGet += ("if set == 0 {\n" +
+ CGIndenter(CGGeneric(get)).define() +
+ "}\n\n")
+
+ namedGetter = self.descriptor.operations['NamedGetter']
+ if namedGetter:
+ readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
+ fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
+ templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': 'ptr::to_unsafe_ptr(&(*desc).value)',
+ 'obj': 'proxy', 'successCode': fillDescriptor}
+ # Once we start supporting OverrideBuiltins we need to make
+ # ResolveOwnProperty or EnumerateOwnProperties filter out named
+ # properties that shadow prototype properties.
+ namedGet = ("\n" +
+ "if set == 0 && RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" +
+ " let nameVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" +
+ " //FakeDependentString name;\n"
+ " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
+ " // eStringify, eStringify, name)) {\n" +
+ " let strval = jsval_to_str(cx, nameVal);\n" +
+ " if strval.is_err() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " let name = str(strval.get());\n" +
+ "\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
+ "}\n") % (self.descriptor.concreteType)
+ else:
+ namedGet = ""
+
+ return setOrIndexedGet + """let expando: *JSObject = GetExpandoObject(proxy);
+//if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
+if expando.is_not_null() {
+ let flags = if set != 0 { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED;
+ if JS_GetPropertyDescriptorById(cx, expando, id, flags, desc as *JSPropertyDescriptor) == 0 {
+ return 0;
+ }
+ if (*desc).obj.is_not_null() {
+ // Pretend the property lives on the wrapper.
+ (*desc).obj = proxy;
+ return 1;
+ }
+}
+""" + namedGet + """
+(*desc).obj = ptr::null();
+return 1;"""
+
+ def definition_body(self):
+ return self.getBody()
+
+class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
+ def __init__(self, descriptor):
+ args = [Argument('*JSContext', 'cx'), Argument('*JSObject', 'proxy'),
+ Argument('jsid', 'id'),
+ Argument('*JSPropertyDescriptor', 'desc')]
+ CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "bool", args)
+ self.descriptor = descriptor
+ def getBody(self):
+ set = ""
+
+ indexedSetter = self.descriptor.operations['IndexedSetter']
+ if indexedSetter:
+ if not (self.descriptor.operations['IndexedCreator'] is indexedSetter):
+ raise TypeError("Can't handle creator that's different from the setter")
+ set += ("let index = GetArrayIndexFromId(cx, id);\n" +
+ "if index.is_some() {\n" +
+ " let index = index.get();\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
+ " return 1;\n" +
+ "}\n") % (self.descriptor.concreteType)
+ elif self.descriptor.operations['IndexedGetter']:
+ set += ("if GetArrayIndexFromId(cx, id).is_some() {\n" +
+ " return 0;\n" +
+ " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
+ "}\n") % self.descriptor.name
+
+ namedSetter = self.descriptor.operations['NamedSetter']
+ if namedSetter:
+ if not self.descriptor.operations['NamedCreator'] is namedSetter:
+ raise TypeError("Can't handle creator that's different from the setter")
+ #XXXjdm need to properly support eStringify
+ set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
+ " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" +
+ " let strval = jsval_to_str(cx, nameVal);\n" +
+ " //FakeDependentString name;\n" +
+ " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
+ " // eStringify, eStringify, name)) {\n" +
+ " if strval.is_err() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " let name = str(strval.get());\n" +
+ "\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyNamedSetter(self.descriptor)).define() + "\n" +
+ "}\n") % (self.descriptor.concreteType)
+ elif self.descriptor.operations['NamedGetter']:
+ set += ("if RUST_JSID_IS_STRING(id) {\n" +
+ " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" +
+ " let strval = jsval_to_str(cx, nameVal);\n" +
+ " //FakeDependentString name;\n"
+ " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
+ " // eStringify, eStringify, name)) {\n" +
+ " let strval = jsval_to_str(cx, nameVal);\n" +
+ " if strval.is_err() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " let name = str(strval.get());\n" +
+ " let this: %%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
+ " if (found) {\n"
+ " return 0;\n" +
+ " //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
+ " }\n" +
+ " return 1;\n"
+ "}\n") % (self.descriptor.concreteType, self.descriptor.name)
+ return set + """return proxyhandler::defineProperty(%s);""" % ", ".join(a.name for a in self.args)
+
+ def definition_body(self):
+ return self.getBody()
+
+class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
+ def __init__(self, descriptor):
+ args = [Argument('*JSContext', 'cx'), Argument('*JSObject', 'proxy'),
+ Argument('jsid', 'id'), Argument('*mut JSBool', 'bp')]
+ CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "JSBool", args)
+ self.descriptor = descriptor
+ def getBody(self):
+ indexedGetter = self.descriptor.operations['IndexedGetter']
+ if indexedGetter:
+ indexed = ("let index = GetArrayIndexFromId(cx, id);\n" +
+ "if index.is_some() {\n" +
+ " let index = index.get();\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
+ " *bp = found as JSBool;\n" +
+ " return 1;\n" +
+ "}\n\n") % (self.descriptor.concreteType)
+ else:
+ indexed = ""
+
+ namedGetter = self.descriptor.operations['NamedGetter']
+ if namedGetter:
+ #XXXjdm support eStringify
+ named = ("if RUST_JSID_IS_STRING(id) != 0 && !HasPropertyOnPrototype(cx, proxy, id) {\n" +
+ " let nameVal: JSVal = RUST_STRING_TO_JSVAL(RUST_JSID_TO_STRING(id));\n" +
+ " let strval = jsval_to_str(cx, nameVal);\n" +
+ " //FakeDependentString name;\n"
+ " //if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" +
+ " // eStringify, eStringify, name)) {\n" +
+ " if strval.is_err() {\n" +
+ " return 0;\n" +
+ " }\n" +
+ " let name = str(strval.get());\n" +
+ "\n" +
+ " let this: *%s = UnwrapProxy(proxy);\n" +
+ CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
+ " *bp = found as JSBool;\n"
+ " return 1;\n"
+ "}\n" +
+ "\n") % (self.descriptor.concreteType)
+ else:
+ named = ""
+
+ return indexed + """let expando: *JSObject = GetExpandoObject(proxy);
+if expando.is_not_null() {
+ let b: JSBool = 1;
+ let ok: JSBool = JS_HasPropertyById(cx, expando, id, &b);
+ *bp = !!b;
+ if ok == 0 || *bp != 0 {
+ return ok;
+ }
+}
+
+""" + named + """*bp = 0;
+return 1;"""
+
+ def definition_body(self):
+ return self.getBody()
class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
def __init__(self, descriptor):
@@ -3620,7 +3877,7 @@ if expando.is_not_null() {
"\n" +
" let this = UnwrapProxy(proxy);\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
- "}\n") % (self.descriptor.nativeType)
+ "}\n") % (self.descriptor.concreteType)
else:
getNamed = ""
@@ -3773,8 +4030,8 @@ class CGClassHasInstanceHook(CGAbstractStaticMethod):
def generate_code(self):
return """ if (!vp.isObject()) {
- *bp = false;
- return true;
+ *bp = 0;
+ return 1;
}
jsval protov;
@@ -3931,8 +4188,13 @@ class CGDescriptor(CGThing):
#cgThings.append(CGProxyIsProxy(descriptor))
cgThings.append(CGProxyUnwrap(descriptor))
cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
+ cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor))
cgThings.append(CGDOMJSProxyHandler_obj_toString(descriptor))
cgThings.append(CGDOMJSProxyHandler_get(descriptor))
+ cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor))
+ if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']:
+ cgThings.append(CGDOMJSProxyHandler_defineProperty(descriptor))
+
#cgThings.append(CGDOMJSProxyHandler(descriptor))
#cgThings.append(CGIsMethod(descriptor))
pass
diff --git a/src/components/script/dom/bindings/codegen/Configuration.py b/src/components/script/dom/bindings/codegen/Configuration.py
index 46e16fdc37c..cf2c13b504e 100644
--- a/src/components/script/dom/bindings/codegen/Configuration.py
+++ b/src/components/script/dom/bindings/codegen/Configuration.py
@@ -140,6 +140,7 @@ class Descriptor(DescriptorProvider):
self.nativeType = desc.get('nativeType', nativeTypeDefault)
self.pointerType = desc.get('pointerType', '@mut ')
+ self.concreteType = desc.get('concreteType', ifaceName)
self.hasInstanceInterface = desc.get('hasInstanceInterface', None)
# Do something sane for JSObject
diff --git a/src/components/script/dom/bindings/proxyhandler.rs b/src/components/script/dom/bindings/proxyhandler.rs
index cbbc4f1525d..fef04d6fee9 100644
--- a/src/components/script/dom/bindings/proxyhandler.rs
+++ b/src/components/script/dom/bindings/proxyhandler.rs
@@ -2,10 +2,15 @@
* 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::utils::is_dom_proxy;
use js::jsapi::{JSContext, jsid, JSPropertyDescriptor, JSObject, JSString, jschar};
use js::jsapi::{JS_GetPropertyDescriptorById, JS_NewUCString, JS_malloc, JS_free};
-use js::glue::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra};
-use js::glue::{GetObjectProto};
+use js::jsapi::{JSBool, JS_DefinePropertyById, JS_NewObjectWithGivenProto};
+use js::glue::{RUST_JSVAL_IS_VOID, RUST_JSVAL_TO_OBJECT, GetProxyExtra, RUST_OBJECT_TO_JSVAL};
+use js::glue::{GetObjectProto, GetObjectParent, SetProxyExtra, GetProxyHandler};
+use js::glue::InvokeGetOwnPropertyDescriptor;
+use js::crust::{JS_StrictPropertyStub};
+use js::{JSPROP_GETTER, JSPROP_ENUMERATE, JSPROP_READONLY, JSRESOLVE_QUALIFIED};
use std::cast;
use std::libc;
@@ -15,10 +20,13 @@ use std::sys::size_of;
type c_bool = libc::c_int;
+static JSPROXYSLOT_EXPANDO: u32 = 0;
+
pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool {
unsafe {
- if _getOwnPropertyDescriptor(cx, proxy, id, set, desc) == 0 {
+ let handler = GetProxyHandler(proxy);
+ if InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, set, desc) == 0 {
return 0;
}
if (*desc).obj.is_not_null() {
@@ -32,34 +40,30 @@ pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
return 1;
}
- JS_GetPropertyDescriptorById(cx, proto, id, 0x01 /*JSRESOLVE_QUALIFIED*/,
- cast::transmute(desc))
+ JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, cast::transmute(desc))
}
}
-fn _getOwnPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
- _set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool {
- unsafe {
- let v = GetProxyExtra(proxy, 0 /*JSPROXYSLOT_EXPANDO*/);
- if RUST_JSVAL_IS_VOID(v) == 0 {
- let expando = RUST_JSVAL_TO_OBJECT(v);
- if JS_GetPropertyDescriptorById(cx, expando, id, 0x01 /*JSRESOLVE_QUALIFIED*/,
- cast::transmute(desc)) == 0 {
+pub extern fn defineProperty(cx: *JSContext, proxy: *JSObject, id: jsid,
+ desc: *JSPropertyDescriptor) -> JSBool {
+ unsafe {
+ if ((*desc).attrs & JSPROP_GETTER) != 0 && (*desc).setter == JS_StrictPropertyStub {
+ /*return JS_ReportErrorFlagsAndNumber(cx,
+ JSREPORT_WARNING | JSREPORT_STRICT |
+ JSREPORT_STRICT_MODE_ERROR,
+ js_GetErrorMessage, NULL,
+ JSMSG_GETTER_ONLY);*/
return 0;
}
- if (*desc).obj.is_not_null() {
- (*desc).obj = proxy;
- return 1;
+
+ let expando = EnsureExpandoObject(cx, proxy);
+ if expando.is_null() {
+ return 0;
}
- }
- (*desc).obj = ptr::null();
- 1
- }
-}
-pub extern fn getOwnPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
- set: c_bool, desc: *mut JSPropertyDescriptor) -> c_bool {
- _getOwnPropertyDescriptor(cx, proxy, id, set, desc)
+ return JS_DefinePropertyById(cx, expando, id, (*desc).value, (*desc).getter,
+ (*desc).setter, (*desc).attrs);
+ }
}
pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
@@ -84,6 +88,39 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
}
}
-pub fn GetExpandoObject(_proxy: *JSObject) -> *JSObject {
- ptr::null()
+pub fn GetExpandoObject(obj: *JSObject) -> *JSObject {
+ unsafe {
+ assert!(is_dom_proxy(obj));
+ let val = GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
+ if RUST_JSVAL_IS_VOID(val) == 1 {
+ ptr::null()
+ } else {
+ RUST_JSVAL_TO_OBJECT(val)
+ }
+ }
+}
+
+pub fn EnsureExpandoObject(cx: *JSContext, obj: *JSObject) -> *JSObject {
+ unsafe {
+ assert!(is_dom_proxy(obj));
+ let mut expando = GetExpandoObject(obj);
+ if expando.is_null() {
+ expando = JS_NewObjectWithGivenProto(cx, ptr::null(), ptr::null(),
+ GetObjectParent(obj));
+ if expando.is_null() {
+ return ptr::null();
+ }
+
+ SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, RUST_OBJECT_TO_JSVAL(expando));
+ }
+ return expando;
+ }
+}
+
+pub fn FillPropertyDescriptor(desc: &mut JSPropertyDescriptor, obj: *JSObject, readonly: bool) {
+ desc.obj = obj;
+ desc.attrs = if readonly { JSPROP_READONLY } else { 0 } | JSPROP_ENUMERATE;
+ desc.getter = ptr::null();
+ desc.setter = ptr::null();
+ desc.shortid = 0;
}
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 40f0f89ee4d..d55eb9869e4 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -120,7 +120,7 @@ fn is_dom_class(clasp: *JSClass) -> bool {
}
}
-fn is_dom_proxy(obj: *JSObject) -> bool {
+pub fn is_dom_proxy(obj: *JSObject) -> bool {
unsafe {
(js_IsObjectProxyClass(obj) || js_IsFunctionProxyClass(obj)) &&
IsProxyHandlerFamily(obj)
@@ -888,3 +888,9 @@ pub fn FindEnumStringIndex(cx: *JSContext,
return Err(()); //XXX pass in behaviour for value not found
}
}
+
+pub fn HasPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid) -> bool {
+ // MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
+ let mut found = false;
+ return !GetPropertyOnPrototype(cx, proxy, id, &mut found, ptr::null()) || found;
+}
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index 69a02deec71..06012ba7502 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::DocumentBinding;
-use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string};
+use dom::bindings::utils::{DOMString, WrapperCache, ErrorResult, null_string, str};
use dom::bindings::utils::{BindingObject, CacheableWrapper, rust_box, DerivedWrapper};
use dom::element::{HTMLHtmlElement, HTMLHtmlElementTypeId, Element};
use dom::event::Event;
@@ -89,7 +89,8 @@ pub struct Document {
root: AbstractNode<ScriptView>,
wrapper: WrapperCache,
window: Option<@mut Window>,
- doctype: DocumentType
+ doctype: DocumentType,
+ title: ~str
}
impl Document {
@@ -106,7 +107,8 @@ impl Document {
root: root,
wrapper: WrapperCache::new(),
window: window,
- doctype: doctype
+ doctype: doctype,
+ title: ~""
}
}
@@ -283,10 +285,14 @@ impl Document {
}
pub fn Title(&self) -> DOMString {
- null_string
+ str(self.title.clone())
}
- pub fn SetTitle(&self, _title: &DOMString, _rv: &mut ErrorResult) {
+ pub fn SetTitle(&mut self, title: &DOMString, _rv: &mut ErrorResult) {
+ self.title = match title {
+ &str(ref s) => s.clone(),
+ &null_string => ~""
+ };
}
pub fn Dir(&self) -> DOMString {
diff --git a/src/components/script/dom/htmlcollection.rs b/src/components/script/dom/htmlcollection.rs
index ac0b66291d3..db668d70e64 100644
--- a/src/components/script/dom/htmlcollection.rs
+++ b/src/components/script/dom/htmlcollection.rs
@@ -53,6 +53,10 @@ impl HTMLCollection {
*found = true;
self.Item(index)
}
+
+ pub fn NamedGetter(&self, _cx: *JSContext, _name: &DOMString, _found: &mut bool, _rv: &mut ErrorResult) -> *JSObject {
+ ptr::null()
+ }
}
impl BindingObject for HTMLCollection {
diff --git a/src/components/script/dom/htmldocument.rs b/src/components/script/dom/htmldocument.rs
index 5cbb02b4b9b..619390352f8 100644
--- a/src/components/script/dom/htmldocument.rs
+++ b/src/components/script/dom/htmldocument.rs
@@ -49,6 +49,10 @@ impl WrappableDocument for HTMLDocument {
}
impl HTMLDocument {
+ pub fn NamedGetter(&self, _cx: *JSContext, _name: &DOMString, _found: &mut bool, _rv: &mut ErrorResult) -> *JSObject {
+ ptr::null()
+ }
+
pub fn GetDomain(&self, _rv: &mut ErrorResult) -> DOMString {
null_string
}
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index dc5665eb79a..3f8339f913d 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -117,6 +117,10 @@ impl Window {
pub fn ShowModalDialog(&self, _cx: *JSContext, _url: &DOMString, _argument: JSVal) -> JSVal {
JSVAL_NULL
}
+
+ pub fn NamedGetter(&self, _cx: *JSContext, _name: &DOMString, _found: &mut bool) -> *JSObject {
+ ptr::null()
+ }
}
impl CacheableWrapper for Window {