From 068f758b053a5792f4fe3553066cefe73d4438bc Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 12 May 2015 15:56:39 -0400 Subject: [PATCH] Bug 1163898 part 1. Give DOMEventTargetHelper a sane accessor for getting its nsIGlobalObject. r=smaug --- dom/base/nsGlobalWindow.h | 11 ++++++++++- dom/base/nsINode.cpp | 9 ++++++++- dom/base/nsINode.h | 3 ++- dom/base/nsPIWindowRoot.h | 1 - dom/base/nsWindowRoot.cpp | 11 ++++++++++- dom/base/nsWindowRoot.h | 3 ++- dom/events/DOMEventTargetHelper.h | 9 +++++++-- dom/events/EventTarget.h | 12 +++++++++--- dom/events/Touch.cpp | 11 +++-------- dom/events/Touch.h | 2 +- dom/indexedDB/IndexedDatabaseManager.cpp | 3 ++- dom/webidl/EventTarget.webidl | 2 +- 12 files changed, 55 insertions(+), 22 deletions(-) diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 5ef8a39d4152..88a367ebc600 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -408,7 +408,7 @@ public: bool aUseCapture, const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) override; - virtual nsIDOMWindow* GetOwnerGlobal() override + virtual nsIDOMWindow* GetOwnerGlobalForBindings() override { if (IsOuterWindow()) { return this; @@ -417,6 +417,15 @@ public: return GetOuterFromCurrentInner(this); } + virtual nsIGlobalObject* GetOwnerGlobal() const override + { + if (IsOuterWindow()) { + return GetCurrentInnerWindowInternal(); + } + + return const_cast(this); + } + // nsPIDOMWindow virtual nsPIDOMWindow* GetPrivateRoot() override; diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index af9f7207b01d..bc6a4deaf5c9 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -1296,13 +1296,20 @@ nsINode::GetContextForEventHandlers(nsresult* aRv) } nsIDOMWindow* -nsINode::GetOwnerGlobal() +nsINode::GetOwnerGlobalForBindings() { bool dummy; return nsPIDOMWindow::GetOuterFromCurrentInner( static_cast(OwnerDoc()->GetScriptHandlingObject(dummy))); } +nsIGlobalObject* +nsINode::GetOwnerGlobal() const +{ + bool dummy; + return OwnerDoc()->GetScriptHandlingObject(dummy); +} + bool nsINode::UnoptimizableCCNode() const { diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h index f46705ff2695..ab8512376331 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h @@ -988,7 +988,8 @@ public: const mozilla::dom::Nullable& aWantsUntrusted, mozilla::ErrorResult& aRv) override; using nsIDOMEventTarget::AddSystemEventListener; - virtual nsIDOMWindow* GetOwnerGlobal() override; + virtual nsIDOMWindow* GetOwnerGlobalForBindings() override; + virtual nsIGlobalObject* GetOwnerGlobal() const override; /** * Adds a mutation observer to be notified when this node, or any of its diff --git a/dom/base/nsPIWindowRoot.h b/dom/base/nsPIWindowRoot.h index 293f5f70719b..e37802f67f09 100644 --- a/dom/base/nsPIWindowRoot.h +++ b/dom/base/nsPIWindowRoot.h @@ -38,7 +38,6 @@ public: virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) = 0; virtual mozilla::dom::EventTarget* GetParentTarget() = 0; - virtual nsIDOMWindow* GetOwnerGlobal() override = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsPIWindowRoot, NS_IWINDOWROOT_IID) diff --git a/dom/base/nsWindowRoot.cpp b/dom/base/nsWindowRoot.cpp index c8957abb9513..7b85a089a74b 100644 --- a/dom/base/nsWindowRoot.cpp +++ b/dom/base/nsWindowRoot.cpp @@ -188,11 +188,20 @@ nsWindowRoot::PostHandleEvent(EventChainPostVisitor& aVisitor) } nsIDOMWindow* -nsWindowRoot::GetOwnerGlobal() +nsWindowRoot::GetOwnerGlobalForBindings() { return GetWindow(); } +nsIGlobalObject* +nsWindowRoot::GetOwnerGlobal() const +{ + nsCOMPtr global = + do_QueryInterface(mWindow->GetCurrentInnerWindow()); + // We're still holding a ref to it, so returning the raw pointer is ok... + return global; +} + nsPIDOMWindow* nsWindowRoot::GetWindow() { diff --git a/dom/base/nsWindowRoot.h b/dom/base/nsWindowRoot.h index e3ef14019f32..49686ad3ee60 100644 --- a/dom/base/nsWindowRoot.h +++ b/dom/base/nsWindowRoot.h @@ -59,7 +59,8 @@ public: mParent = aTarget; } virtual mozilla::dom::EventTarget* GetParentTarget() override { return mParent; } - virtual nsIDOMWindow* GetOwnerGlobal() override; + virtual nsIDOMWindow* GetOwnerGlobalForBindings() override; + virtual nsIGlobalObject* GetOwnerGlobal() const override; nsIGlobalObject* GetParentObject(); diff --git a/dom/events/DOMEventTargetHelper.h b/dom/events/DOMEventTargetHelper.h index fb7920106348..60e1f7d405a4 100644 --- a/dom/events/DOMEventTargetHelper.h +++ b/dom/events/DOMEventTargetHelper.h @@ -121,7 +121,7 @@ public: JSContext* aCx, JS::Value* aValue); using dom::EventTarget::GetEventHandler; - virtual nsIDOMWindow* GetOwnerGlobal() override + virtual nsIDOMWindow* GetOwnerGlobalForBindings() override { return nsPIDOMWindow::GetOuterFromCurrentInner(GetOwner()); } @@ -140,7 +140,12 @@ public: void BindToOwner(nsPIDOMWindow* aOwner); void BindToOwner(DOMEventTargetHelper* aOther); virtual void DisconnectFromOwner(); - nsIGlobalObject* GetParentObject() const { + nsIGlobalObject* GetParentObject() const + { + return GetOwnerGlobal(); + } + virtual nsIGlobalObject* GetOwnerGlobal() const override + { nsCOMPtr parentObject = do_QueryReferent(mParentObject); return parentObject; } diff --git a/dom/events/EventTarget.h b/dom/events/EventTarget.h index 12ac3c875177..b007cc9a039b 100644 --- a/dom/events/EventTarget.h +++ b/dom/events/EventTarget.h @@ -12,6 +12,7 @@ #include "nsIAtom.h" class nsIDOMWindow; +class nsIGlobalObject; namespace mozilla { @@ -27,8 +28,8 @@ template struct Nullable; // IID for the dom::EventTarget interface #define NS_EVENTTARGET_IID \ -{ 0xce3817d0, 0x177b, 0x402f, \ - { 0xae, 0x75, 0xf8, 0x4e, 0xbe, 0x5a, 0x07, 0xc3 } } +{ 0x605158a9, 0xe229, 0x45b1, \ + { 0xbc, 0x12, 0x02, 0x9f, 0xa3, 0xa9, 0x3f, 0xcb } } class EventTarget : public nsIDOMEventTarget, public nsWrapperCache @@ -69,7 +70,12 @@ public: // Returns an outer window that corresponds to the inner window this event // target is associated with. Will return null if the inner window is not the // current inner or if there is no window around at all. - virtual nsIDOMWindow* GetOwnerGlobal() = 0; + virtual nsIDOMWindow* GetOwnerGlobalForBindings() = 0; + + // The global object this event target is associated with, if any. + // This may be an inner window or some other global object. This + // will never be an outer window. + virtual nsIGlobalObject* GetOwnerGlobal() const = 0; /** * Get the event listener manager, creating it if it does not already exist. diff --git a/dom/events/Touch.cpp b/dom/events/Touch.cpp index c8e8fb72b914..c326a9ea7b47 100644 --- a/dom/events/Touch.cpp +++ b/dom/events/Touch.cpp @@ -136,21 +136,16 @@ Touch::WrapObject(JSContext* aCx, JS::Handle aGivenProto) return TouchBinding::Wrap(aCx, this, aGivenProto); } -// Parent ourselves to the window of the target. This achieves the desirable +// Parent ourselves to the global of the target. This achieves the desirable // effects of parenting to the target, but avoids making the touch inaccessible // when the target happens to be NAC and therefore reflected into the XBL scope. -EventTarget* +nsIGlobalObject* Touch::GetParentObject() { if (!mTarget) { return nullptr; } - nsCOMPtr outer = do_QueryInterface(mTarget->GetOwnerGlobal()); - if (!outer) { - return nullptr; - } - MOZ_ASSERT(outer->IsOuterWindow()); - return static_cast(outer->GetCurrentInnerWindow()); + return mTarget->GetOwnerGlobal(); } } // namespace dom diff --git a/dom/events/Touch.h b/dom/events/Touch.h index 4789095cbeac..f22aabe2124b 100644 --- a/dom/events/Touch.h +++ b/dom/events/Touch.h @@ -57,7 +57,7 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - EventTarget* GetParentObject(); + nsIGlobalObject* GetParentObject(); // WebIDL int32_t Identifier() const { return mIdentifier; } diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 5693112cca49..d8298b1f4b8e 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -428,7 +428,8 @@ IndexedDatabaseManager::CommonPostHandleEvent(EventChainPostVisitor& aVisitor, nsEventStatus status = nsEventStatus_eIgnore; if (NS_IsMainThread()) { - if (nsIDOMWindow* window = eventTarget->GetOwnerGlobal()) { + nsCOMPtr window = do_QueryInterface(eventTarget->GetOwnerGlobal()); + if (window) { nsCOMPtr sgo = do_QueryInterface(window); MOZ_ASSERT(sgo); diff --git a/dom/webidl/EventTarget.webidl b/dom/webidl/EventTarget.webidl index a20c386446ca..0fc5e7bd005e 100644 --- a/dom/webidl/EventTarget.webidl +++ b/dom/webidl/EventTarget.webidl @@ -43,6 +43,6 @@ partial interface EventTarget { // chrome easier. This returns the window which can be used to create // events to fire at this EventTarget, or null if there isn't one. partial interface EventTarget { - [ChromeOnly, Exposed=Window] + [ChromeOnly, Exposed=Window, BinaryName="ownerGlobalForBindings"] readonly attribute WindowProxy? ownerGlobal; };