diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 96780f90bc8..29d35dcbc50 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1550,3 +1550,12 @@ nsDOMWindowUtils::GetCursorType(PRInt16 *aCursor) return NS_OK; } + +NS_IMETHODIMP +nsDOMWindowUtils::GetOuterWindowWithId(PRUint64 aWindowID, + nsIDOMWindow** aWindow) +{ + *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID); + NS_IF_ADDREF(*aWindow); + return NS_OK; +} diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 53935410895..a446862b70e 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -242,6 +242,7 @@ using mozilla::TimeStamp; using mozilla::TimeDuration; nsIDOMStorageList *nsGlobalWindow::sGlobalStorageList = nsnull; +nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sOuterWindowsById = nsnull; static nsIEntropyCollector *gEntropyCollector = nsnull; static PRInt32 gRefCnt = 0; @@ -773,6 +774,18 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mObserver = nsnull; SetIsProxy(); + + if (!sOuterWindowsById) { + sOuterWindowsById = new WindowByIdTable(); + if (!sOuterWindowsById->Init()) { + delete sOuterWindowsById; + sOuterWindowsById = nsnull; + } + } + + if (sOuterWindowsById) { + sOuterWindowsById->Put(mWindowID, this); + } } // We could have failed the first time through trying @@ -825,8 +838,13 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) nsGlobalWindow::~nsGlobalWindow() { + if (sOuterWindowsById) { + sOuterWindowsById->Remove(mWindowID); + } if (!--gRefCnt) { NS_IF_RELEASE(gEntropyCollector); + delete sOuterWindowsById; + sOuterWindowsById = nsnull; } #ifdef DEBUG nsCAutoString url; diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 6ff563f9701..7e818d0adb4 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -562,6 +562,10 @@ public: return mSerial; } + static nsGlobalWindow* GetOuterWindowWithId(PRUint64 aWindowID) { + return sOuterWindowsById ? sOuterWindowsById->Get(aWindowID) : nsnull; + } + protected: // Object Management virtual ~nsGlobalWindow(); @@ -946,6 +950,9 @@ protected: friend class nsDOMWindowUtils; friend class PostMessageEvent; static nsIDOMStorageList* sGlobalStorageList; + + typedef nsDataHashtable WindowByIdTable; + static WindowByIdTable* sOuterWindowsById; }; /* diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 3663922fda1..be32608809c 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -59,8 +59,9 @@ interface nsIDOMHTMLCanvasElement; interface nsIDOMEvent; interface nsITransferable; interface nsIQueryContentEventResult; +interface nsIDOMWindow; -[scriptable, uuid(43fd9eb5-9e08-4d60-a305-3f87b1d5c398)] +[scriptable, uuid(33cbae2d-2361-4f3d-b589-cc55af07a434)] interface nsIDOMWindowUtils : nsISupports { /** @@ -789,6 +790,11 @@ interface nsIDOMWindowUtils : nsISupports { */ readonly attribute AString layerManagerType; + /** + * Return the outer window with the given ID, if any. Can return null. + */ + nsIDOMWindow getOuterWindowWithId(in unsigned long long aOuterWindowID); + %{C++ virtual nsresult RenderDocument(const nsRect& aRect, PRUint32 aFlags, diff --git a/xpcom/glue/nsHashKeys.h b/xpcom/glue/nsHashKeys.h index 4c199b54b8d..09a955576bf 100644 --- a/xpcom/glue/nsHashKeys.h +++ b/xpcom/glue/nsHashKeys.h @@ -59,6 +59,7 @@ * nsStringHashKey * nsCStringHashKey * nsUint32HashKey + * nsUint64HashKey * nsPtrHashkey * nsClearingPtrHashKey * nsVoidPtrHashKey @@ -164,6 +165,32 @@ private: const PRUint32 mValue; }; +/** + * hashkey wrapper using PRUint64 KeyType + * + * @see nsTHashtable::EntryType for specification + */ +class nsUint64HashKey : public PLDHashEntryHdr +{ +public: + typedef const PRUint64& KeyType; + typedef const PRUint64* KeyTypePointer; + + nsUint64HashKey(KeyTypePointer aKey) : mValue(*aKey) { } + nsUint64HashKey(const nsUint64HashKey& toCopy) : mValue(toCopy.mValue) { } + ~nsUint64HashKey() { } + + KeyType GetKey() const { return mValue; } + PRBool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } + static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } + enum { ALLOW_MEMMOVE = PR_TRUE }; + +private: + const PRUint64 mValue; +}; + /** * hashkey wrapper using nsISupports* KeyType *