mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 16:55:40 +00:00
Bug 1145017. Use the new proto setup for custom element prototypes when possible. r=wchen,bholley
Note that with this patch I'm also changing the priority order of the given proto and the custom proto; the former takes priority. This makes sense to me: if the caller is doing |new Foo| they really should get something with Foo.prototype as its proto. This should not be a problem for custom elements in general so far, because nodes/elements are mostly not constructible anyway. For now. When they become that way, I think this is the behavior we'll want.
This commit is contained in:
parent
9fb24e2658
commit
17e46d2f65
@ -408,30 +408,45 @@ Element::GetBindingURL(nsIDocument *aDocument, css::URLValue **aResult)
|
|||||||
JSObject*
|
JSObject*
|
||||||
Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
|
||||||
{
|
{
|
||||||
JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
|
JS::Rooted<JSObject*> givenProto(aCx, aGivenProto);
|
||||||
|
JS::Rooted<JSObject*> customProto(aCx);
|
||||||
|
|
||||||
|
if (!givenProto) {
|
||||||
|
// Custom element prototype swizzling.
|
||||||
|
CustomElementData* data = GetCustomElementData();
|
||||||
|
if (data) {
|
||||||
|
// If this is a registered custom element then fix the prototype.
|
||||||
|
nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
|
||||||
|
document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &customProto);
|
||||||
|
if (customProto &&
|
||||||
|
NodePrincipal()->SubsumesConsideringDomain(nsContentUtils::ObjectPrincipal(customProto))) {
|
||||||
|
// Just go ahead and create with the right proto up front. Set
|
||||||
|
// customProto to null to flag that we don't need to do any post-facto
|
||||||
|
// proto fixups here.
|
||||||
|
givenProto = customProto;
|
||||||
|
customProto = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, givenProto));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom element prototype swizzling.
|
if (customProto) {
|
||||||
CustomElementData* data = GetCustomElementData();
|
|
||||||
if (obj && data) {
|
|
||||||
// If this is a registered custom element then fix the prototype.
|
|
||||||
nsDocument* document = static_cast<nsDocument*>(OwnerDoc());
|
|
||||||
JS::Rooted<JSObject*> prototype(aCx);
|
|
||||||
document->GetCustomPrototype(NodeInfo()->NamespaceID(), data->mType, &prototype);
|
|
||||||
if (prototype) {
|
|
||||||
// We want to set the custom prototype in the compartment where it was
|
// We want to set the custom prototype in the compartment where it was
|
||||||
// registered. In the case that |obj| and |prototype| are in different
|
// registered. In the case that |obj| and |prototype| are in different
|
||||||
// compartments, this will set the prototype on the |obj|'s wrapper and
|
// compartments, this will set the prototype on the |obj|'s wrapper and
|
||||||
// thus only visible in the wrapper's compartment.
|
// thus only visible in the wrapper's compartment, since we know obj's
|
||||||
JSAutoCompartment ac(aCx, prototype);
|
// principal does not subsume customProto's in this case.
|
||||||
if (!JS_WrapObject(aCx, &obj) || !JS_SetPrototype(aCx, obj, prototype)) {
|
JSAutoCompartment ac(aCx, customProto);
|
||||||
dom::Throw(aCx, NS_ERROR_FAILURE);
|
JS::Rooted<JSObject*> wrappedObj(aCx, obj);
|
||||||
|
if (!JS_WrapObject(aCx, &wrappedObj) ||
|
||||||
|
!JS_SetPrototype(aCx, wrappedObj, customProto)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nsIDocument* doc;
|
nsIDocument* doc;
|
||||||
if (HasFlag(NODE_FORCE_XBL_BINDINGS)) {
|
if (HasFlag(NODE_FORCE_XBL_BINDINGS)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user