Bug 825392 - Generate anonymous content reflectors in the XBL scope. r=bz

This commit is contained in:
Bobby Holley 2014-03-19 13:35:45 -03:00
parent 79c147b83d
commit 82090508be
9 changed files with 69 additions and 37 deletions

View File

@ -2650,4 +2650,10 @@ nsINode::OwnerDocAsNode() const
return OwnerDoc();
}
inline mozilla::dom::ParentObject
nsINode::GetParentObject() const
{
return GetParentObjectInternal(OwnerDoc());
}
#endif /* nsIDocument_h___ */

View File

@ -20,6 +20,7 @@
#include "mozilla/dom/EventTarget.h" // for base class
#include "js/TypeDecls.h" // for Handle, Value, JSObject, JSContext
#include "mozilla/dom/DOMString.h"
#include "mozilla/dom/BindingDeclarations.h"
// Including 'windows.h' will #define GetClassInfo to something else.
#ifdef XP_WIN
@ -392,18 +393,18 @@ protected:
return nullptr;
}
public:
nsIDocument* GetParentObject() const
{
// Make sure that we get the owner document of the content node, in case
// we're in document teardown. If we are, it's important to *not* use
// globalObj as the node's parent since that would give the node the
// principal of globalObj (i.e. the principal of the document that's being
// loaded) and not the principal of the document that's being unloaded.
// See http://bugzilla.mozilla.org/show_bug.cgi?id=227417
return OwnerDoc();
// Subclasses that wish to override the parent behavior should return the
// result of GetParentObjectIntenral, which handles the XBL scope stuff.
//
mozilla::dom::ParentObject GetParentObjectInternal(nsINode* aNativeParent) const {
mozilla::dom::ParentObject p(aNativeParent);
p.mUseXBLScope = ChromeOnlyAccess();
return p;
}
public:
mozilla::dom::ParentObject GetParentObject() const; // Implemented in nsIDocument.h
/**
* Return whether the node is an Element node
*/

View File

@ -2594,19 +2594,8 @@ nsINode::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aScope)
}
JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx, aScope));
if (obj && ChromeOnlyAccess() &&
!nsContentUtils::IsSystemPrincipal(NodePrincipal()) &&
xpc::AllowXBLScope(js::GetObjectCompartment(obj)))
{
// Create a new wrapper and cache it.
JSAutoCompartment ac(aCx, obj);
JSObject* wrapper = xpc::WrapperFactory::WrapSOWObject(aCx, obj);
if (!wrapper) {
ClearWrapper();
return nullptr;
}
dom::SetSystemOnlyWrapper(obj, this, *wrapper);
}
MOZ_ASSERT_IF(ChromeOnlyAccess(),
xpc::IsInXBLScope(obj) || !xpc::UseXBLScope(js::GetObjectCompartment(obj)));
return obj;
}

View File

@ -78,9 +78,9 @@ public:
SetHTMLAttr(nsGkAtoms::align, aAlign, aError);
}
nsINode* GetParentObject() {
ParentObject GetParentObject() {
Element* form = GetFormElement();
return form ? static_cast<nsINode*>(form)
return form ? GetParentObjectInternal(form)
: nsGenericHTMLElement::GetParentObject();
}

View File

@ -1927,12 +1927,14 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsGenericHTMLFormElement,
nsGenericHTMLElement,
nsIFormControl)
nsINode*
mozilla::dom::ParentObject
nsGenericHTMLFormElement::GetParentObject() const
{
// We use the parent chain to implement the scope for event handlers.
return mForm ? static_cast<nsINode*>(mForm)
: static_cast<nsINode*>(OwnerDoc());
if (mForm) {
return GetParentObjectInternal(mForm);
}
return nsGenericHTMLElement::GetParentObject();
}
bool

View File

@ -1280,7 +1280,7 @@ public:
NS_DECL_ISUPPORTS_INHERITED
nsINode* GetParentObject() const;
mozilla::dom::ParentObject GetParentObject() const;
virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
virtual void SaveSubtreeState() MOZ_OVERRIDE;

View File

@ -598,11 +598,11 @@ public:
void SwapFrameLoaders(nsXULElement& aOtherOwner, mozilla::ErrorResult& rv);
// For XUL, the parent is the parent element, if any
nsINode* GetParentObject() const
mozilla::dom::ParentObject GetParentObject() const
{
Element* parent = GetParentElement();
if (parent) {
return parent;
return GetParentObjectInternal(parent);
}
return nsStyledElement::GetParentObject();
}

View File

@ -467,22 +467,26 @@ struct ParentObject {
template<class T>
ParentObject(T* aObject) :
mObject(aObject),
mWrapperCache(GetWrapperCache(aObject))
mWrapperCache(GetWrapperCache(aObject)),
mUseXBLScope(false)
{}
template<class T, template<typename> class SmartPtr>
ParentObject(const SmartPtr<T>& aObject) :
mObject(aObject.get()),
mWrapperCache(GetWrapperCache(aObject.get()))
mWrapperCache(GetWrapperCache(aObject.get())),
mUseXBLScope(false)
{}
ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
mObject(aObject),
mWrapperCache(aCache)
mWrapperCache(aCache),
mUseXBLScope(false)
{}
nsISupports* const mObject;
nsWrapperCache* const mWrapperCache;
bool mUseXBLScope;
};
} // namespace dom

View File

@ -993,6 +993,19 @@ GetParentPointer(const ParentObject& aObject)
return aObject.mObject;
}
template <typename T>
inline bool
GetUseXBLScope(T* aParentObject)
{
return false;
}
inline bool
GetUseXBLScope(const ParentObject& aParentObject)
{
return aParentObject.mUseXBLScope;
}
template<class T>
inline void
ClearWrapper(T* p, nsWrapperCache* cache)
@ -1234,13 +1247,30 @@ struct WrapNativeParentHelper<T, false >
template<typename T>
static inline JSObject*
WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
nsWrapperCache* cache)
nsWrapperCache* cache, bool useXBLScope = false)
{
if (!p) {
return scope;
}
return WrapNativeParentHelper<T>::Wrap(cx, scope, p, cache);
JSObject* parent = WrapNativeParentHelper<T>::Wrap(cx, scope, p, cache);
if (!useXBLScope) {
return parent;
}
// If useXBLScope is true, it means that the canonical reflector for this
// native object should live in the XBL scope.
if (xpc::IsInXBLScope(parent)) {
return parent;
}
JS::Rooted<JSObject*> rootedParent(cx, parent);
JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScope(cx, rootedParent));
JSAutoCompartment ac(cx, xblScope);
if (NS_WARN_IF(!JS_WrapObject(cx, &rootedParent))) {
return nullptr;
}
return rootedParent;
}
// Wrapping of our native parent, when we don't want to explicitly pass in
@ -1249,7 +1279,7 @@ template<typename T>
static inline JSObject*
WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, const T& p)
{
return WrapNativeParent(cx, scope, GetParentPointer(p), GetWrapperCache(p));
return WrapNativeParent(cx, scope, GetParentPointer(p), GetWrapperCache(p), GetUseXBLScope(p));
}
// A way to differentiate between nodes, which use the parent object