Bug 787070 - Expandos on the xray of DOM prototypes should have effect on xrays of DOM nodes, create the named properties object from the binding code. r=bz.

--HG--
extra : rebase_source : 9147c989b0f6b5791d3e98041029e730036c3892
This commit is contained in:
Peter Van der Beken 2014-09-05 22:36:36 +02:00
parent df682c483d
commit 92f9247d53
5 changed files with 62 additions and 32 deletions

View File

@ -227,15 +227,10 @@ static const DOMIfaceAndProtoJSClass WindowNamedPropertiesClass = {
};
// static
void
WindowNamedPropertiesHandler::Install(JSContext* aCx,
JS::Handle<JSObject*> aProto)
JSObject*
WindowNamedPropertiesHandler::Create(JSContext* aCx,
JS::Handle<JSObject*> aProto)
{
JS::Rooted<JSObject*> protoProto(aCx);
if (!::JS_GetPrototype(aCx, aProto, &protoProto)) {
return;
}
// Note: since the scope polluter proxy lives on the window's prototype
// chain, it needs a singleton type to avoid polluting type information
// for properties on the window.
@ -243,17 +238,10 @@ WindowNamedPropertiesHandler::Install(JSContext* aCx,
js::ProxyOptions options;
options.setSingleton(true);
options.setClass(&WindowNamedPropertiesClass.mBase);
gsp = js::NewProxyObject(aCx, WindowNamedPropertiesHandler::getInstance(),
JS::NullHandleValue, protoProto,
js::GetGlobalForObjectCrossCompartment(aProto),
options);
if (!gsp) {
return;
}
// And then set the prototype of the interface prototype object to be the
// global scope polluter.
::JS_SplicePrototype(aCx, aProto, gsp);
return js::NewProxyObject(aCx, WindowNamedPropertiesHandler::getInstance(),
JS::NullHandleValue, aProto,
js::GetGlobalForObjectCrossCompartment(aProto),
options);
}
} // namespace dom

View File

@ -63,9 +63,10 @@ public:
return &instance;
}
// For Install, aProto is the proto of the Window we're associated with.
static void
Install(JSContext *aCx, JS::Handle<JSObject*> aProto);
// For Create, aProto is the parent of the interface prototype object of the
// Window we're associated with.
static JSObject*
Create(JSContext *aCx, JS::Handle<JSObject*> aProto);
};
} // namespace dom

View File

@ -2590,15 +2590,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
bool allow = GetDocShell()->GetCanExecuteScripts();
xpc::Scriptability::Get(GetWrapperPreserveColor()).SetDocShellAllowsScript(allow);
// If we created a new inner window above, we need to do the last little bit
// of initialization now that the dust has settled.
if (createdInnerWindow) {
JS::Rooted<JSObject*> global(cx, newInnerGlobal);
JS::Rooted<JSObject*> proto(cx);
JS_GetPrototype(cx, global, &proto);
WindowNamedPropertiesHandler::Install(cx, proto);
}
if (!aState) {
JS::Rooted<JSObject*> rootedWrapper(cx, GetWrapperPreserveColor());
if (!JS_DefineProperty(cx, newInnerGlobal, "window", rootedWrapper,
@ -13975,6 +13966,14 @@ nsGlobalWindow::ClearDocumentDependentSlots(JSContext* aCx)
WindowBinding::ClearCachedPerformanceValue(aCx, this);
}
/* static */
JSObject*
nsGlobalWindow::CreateNamedPropertiesObject(JSContext *aCx,
JS::Handle<JSObject*> aProto)
{
return WindowNamedPropertiesHandler::Create(aCx, aProto);
}
#ifdef MOZ_B2G
void
nsGlobalWindow::EnableNetworkEvent(uint32_t aType)

View File

@ -785,6 +785,9 @@ public:
return nullptr;
}
static JSObject*
CreateNamedPropertiesObject(JSContext *aCx, JS::Handle<JSObject*> aProto);
nsIDOMWindow* GetWindow(mozilla::ErrorResult& aError);
nsIDOMWindow* GetSelf(mozilla::ErrorResult& aError);
nsIDocument* GetDocument()

View File

@ -2580,7 +2580,10 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
def definition_body(self):
parentProtoName = self.descriptor.parentPrototypeName
if parentProtoName is None:
if self.descriptor.hasNamedPropertiesObject:
parentProtoType = "Rooted"
getParentProto = "aCx, GetNamedPropertiesObject(aCx, aGlobal)"
elif parentProtoName is None:
parentProtoType = "Rooted"
if self.descriptor.interface.getExtendedAttribute("ArrayClass"):
getParentProto = "aCx, JS_GetArrayPrototype(aCx, aGlobal)"
@ -2847,6 +2850,39 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
""") + CGGetPerInterfaceObject.definition_body(self)
class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
def __init__(self, descriptor):
args = [Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aGlobal')]
CGAbstractStaticMethod.__init__(self, descriptor,
'GetNamedPropertiesObject',
'JSObject*', args)
def definition_body(self):
parentProtoName = self.descriptor.parentPrototypeName
if parentProtoName is None:
getParentProto = ""
parentProto = "nullptr"
else:
getParentProto = fill(
"""
JS::Rooted<JSObject*> parentProto(aCx, ${parent}::GetProtoObject(aCx, aGlobal));
if (!parentProto) {
return nullptr;
}
""",
parent=toBindingNamespace(parentProtoName))
parentProto = "parentProto"
return fill(
"""
$*{getParentProto}
return ${nativeType}::CreateNamedPropertiesObject(aCx, ${parentProto});
""",
getParentProto=getParentProto,
parentProto=parentProto,
nativeType=self.descriptor.nativeType)
class CGDefineDOMInterfaceMethod(CGAbstractMethod):
"""
A method for resolve hooks to try to lazily define the interface object for
@ -11014,6 +11050,9 @@ class CGDescriptor(CGThing):
cgThings.append(CGNewResolveHook(descriptor))
cgThings.append(CGEnumerateHook(descriptor))
if descriptor.hasNamedPropertiesObject:
cgThings.append(CGGetNamedPropertiesObjectMethod(descriptor))
if descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGPrototypeJSClass(descriptor, properties))