Bug 1451913 P1 Allow subclasses to override DOMEventTargetHelper::BindToOwner(nsIGlobalObject*). r=smaug

This commit is contained in:
Ben Kelly 2018-04-16 06:08:51 -07:00
Родитель 968dd21f15
Коммит 4763ab4066
2 изменённых файлов: 60 добавлений и 22 удалений

Просмотреть файл

@ -99,34 +99,25 @@ DOMEventTargetHelper::~DOMEventTargetHelper()
void
DOMEventTargetHelper::BindToOwner(nsPIDOMWindowInner* aOwner)
{
BindToOwner(aOwner ? aOwner->AsGlobal() : nullptr);
// Make sure to bind via BindToOwner(nsIGlobalObject*) so
// subclasses can override the method to perform additional
// actions.
nsIGlobalObject* global = aOwner ? aOwner->AsGlobal() : nullptr;
BindToOwner(global);
}
void
DOMEventTargetHelper::BindToOwner(nsIGlobalObject* aOwner)
{
if (mParentObject) {
mParentObject->RemoveEventTargetObject(this);
if (mOwnerWindow) {
mOwnerWindow = nullptr;
}
mParentObject = nullptr;
mHasOrHasHadOwnerWindow = false;
}
if (aOwner) {
mParentObject = aOwner;
aOwner->AddEventTargetObject(this);
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindowInner>(do_QueryInterface(aOwner)).get();
if (mOwnerWindow) {
mHasOrHasHadOwnerWindow = true;
}
}
BindToOwnerInternal(aOwner);
}
void
DOMEventTargetHelper::BindToOwner(DOMEventTargetHelper* aOther)
{
// Make sure to bind via BindToOwner(nsIGlobalObject*) so
// subclasses can override the method to perform additional
// actions.
if (!aOther) {
BindToOwner(static_cast<nsIGlobalObject*>(nullptr));
return;
@ -355,4 +346,26 @@ DOMEventTargetHelper::MaybeDontKeepAlive()
}
}
void
DOMEventTargetHelper::BindToOwnerInternal(nsIGlobalObject* aOwner)
{
if (mParentObject) {
mParentObject->RemoveEventTargetObject(this);
if (mOwnerWindow) {
mOwnerWindow = nullptr;
}
mParentObject = nullptr;
mHasOrHasHadOwnerWindow = false;
}
if (aOwner) {
mParentObject = aOwner;
aOwner->AddEventTargetObject(this);
// Let's cache the result of this QI for fast access and off main thread usage
mOwnerWindow = nsCOMPtr<nsPIDOMWindowInner>(do_QueryInterface(aOwner)).get();
if (mOwnerWindow) {
mHasOrHasHadOwnerWindow = true;
}
}
}
} // namespace mozilla

Просмотреть файл

@ -46,7 +46,10 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aWindow);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
nsIGlobalObject* global = aWindow ? aWindow->AsGlobal() : nullptr;
BindToOwnerInternal(global);
}
explicit DOMEventTargetHelper(nsIGlobalObject* aGlobalObject)
: mParentObject(nullptr)
@ -54,7 +57,9 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aGlobalObject);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
BindToOwnerInternal(aGlobalObject);
}
explicit DOMEventTargetHelper(DOMEventTargetHelper* aOther)
: mParentObject(nullptr)
@ -62,7 +67,14 @@ public:
, mHasOrHasHadOwnerWindow(false)
, mIsKeptAlive(false)
{
BindToOwner(aOther);
// Be careful not to call the virtual BindToOwner() in a
// constructor.
if (!aOther) {
BindToOwnerInternal(static_cast<nsIGlobalObject*>(nullptr));
return;
}
BindToOwnerInternal(aOther->GetParentObject());
mHasOrHasHadOwnerWindow = aOther->HasOrHasHadOwner();
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -142,9 +154,20 @@ public:
// Returns the document associated with this event target, if that document is
// the current document of its browsing context. Will return null otherwise.
nsIDocument* GetDocumentIfCurrent() const;
void BindToOwner(nsIGlobalObject* aOwner);
// DETH subclasses may override the BindToOwner(nsIGlobalObject*) method
// to take action when dynamically binding to a new global. This is only
// called on rebind since virtual methods cannot be called from the
// constructor. The other BindToOwner() methods will call into this
// method.
//
// NOTE: Any overrides of BindToOwner() *must* invoke
// DOMEventTargetHelper::BindToOwner(aOwner).
virtual void BindToOwner(nsIGlobalObject* aOwner);
void BindToOwner(nsPIDOMWindowInner* aOwner);
void BindToOwner(DOMEventTargetHelper* aOther);
virtual void DisconnectFromOwner();
using EventTarget::GetParentObject;
virtual nsIGlobalObject* GetOwnerGlobal() const override
@ -189,6 +212,8 @@ protected:
void IgnoreKeepAliveIfHasListenersFor(const nsAString& aType);
void IgnoreKeepAliveIfHasListenersFor(nsAtom* aType);
void BindToOwnerInternal(nsIGlobalObject* aOwner);
private:
// The parent global object. The global will clear this when
// it is destroyed by calling DisconnectFromOwner().