Bug 1440949 - Allow plain JS objects to request addon interposition;r=kmag
This is needed to allow interposition for gBrowser, which will change from a DOM node
into a plain JS object in
Bug 1392352. An object can set the `requiresAddonInterpositions`
property to enable this feature.
MozReview-Commit-ID: 4Uw5xzgZtXO
--- a/js/xpconnect/wrappers/AddonWrapper.cpp
+++ b/js/xpconnect/wrappers/AddonWrapper.cpp
@@ -34,29 +34,45 @@ ReportASCIIErrorWithId(JSContext* cx, co
return;
JSAutoByteString bytes;
if (!bytes.encodeUtf8(cx, idstr))
return;
JS_ReportErrorUTF8(cx, msg, bytes.ptr());
}
bool
+RequiresInterpositions(JSContext* cx, HandleObject unwrapped)
+{
+ Rooted<PropertyDescriptor> desc(cx);
+ JSAutoCompartment ac(cx, unwrapped);
+
+ if (!JS_GetOwnPropertyDescriptor(cx, unwrapped, "requiresAddonInterpositions", &desc)) {
+ JS_ClearPendingException(cx);
+ return false;
+ }
+
+ return desc.hasValue() && desc.value().isTrue();
+}
+
+bool
InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
MutableHandle<PropertyDescriptor> descriptor)
{
- // We only want to do interpostion on DOM instances and
- // wrapped natives.
+ // We only want to do interpostion on DOM instances,
+ // wrapped natives, or if the object explicitly requests it.
RootedObject unwrapped(cx, UncheckedUnwrap(target));
const js::Class* clasp = js::GetObjectClass(unwrapped);
bool isCPOW = jsipc::IsWrappedCPOW(unwrapped);
+
if (!mozilla::dom::IsDOMClass(clasp) &&
!IS_WN_CLASS(clasp) &&
!IS_PROTO_CLASS(clasp) &&
clasp != &OuterWindowProxyClass &&
- !isCPOW) {
+ !isCPOW &&
+ !RequiresInterpositions(cx, unwrapped)) {
return true;
}
XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
MOZ_ASSERT(scope->HasInterposition());
nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp);