зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1125325 - Store TabParents with their WindowRoot. r=smaug
nsContentUtils::CallOnAllRemoteChildren calls a callback on all tabs connected to a given window but it has only worked in Firefox e10s tabs. This patch adds a list of (weak) references to each top-level document's WindowRoot so that e.g. the nsPresContext can access them instead of using nsContentUtils. This provides a solution to the problem of finding remote PBrowsers generally.
This commit is contained in:
Родитель
c485e27130
Коммит
eff33f4052
|
@ -7806,3 +7806,16 @@ nsContentUtils::FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
|||
doc->OnPageShow(true, aChromeEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsPIWindowRoot>
|
||||
nsContentUtils::GetWindowRoot(nsIDocument* aDoc)
|
||||
{
|
||||
if (aDoc) {
|
||||
nsPIDOMWindow* win = aDoc->GetWindow();
|
||||
if (win) {
|
||||
return win->GetTopWindowRoot();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ class nsViewportInfo;
|
|||
class nsWrapperCache;
|
||||
class nsAttrValue;
|
||||
class nsITransferable;
|
||||
class nsPIWindowRoot;
|
||||
|
||||
struct JSPropertyDescriptor;
|
||||
struct JSRuntime;
|
||||
|
@ -2384,6 +2385,8 @@ public:
|
|||
static void FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
mozilla::dom::EventTarget* aChromeEventHandler);
|
||||
|
||||
static already_AddRefed<nsPIWindowRoot> GetWindowRoot(nsIDocument* aDoc);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
@ -9,14 +9,21 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
class nsIControllers;
|
||||
class nsIController;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class TabParent;
|
||||
}
|
||||
}
|
||||
|
||||
#define NS_IWINDOWROOT_IID \
|
||||
{ 0x728a2682, 0x55c0, 0x4860, \
|
||||
{ 0x82, 0x6b, 0x0c, 0x30, 0x0a, 0xac, 0xaa, 0x60 } }
|
||||
{ 0x238edca0, 0xb30d, 0x46d3, \
|
||||
{ 0xb2, 0x6a, 0x17, 0xb6, 0x21, 0x28, 0x89, 0x7e } }
|
||||
|
||||
class nsPIWindowRoot : public mozilla::dom::EventTarget
|
||||
{
|
||||
|
@ -38,6 +45,15 @@ public:
|
|||
|
||||
virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) = 0;
|
||||
virtual mozilla::dom::EventTarget* GetParentTarget() = 0;
|
||||
|
||||
// Stores a weak reference to the browser.
|
||||
virtual void AddBrowser(mozilla::dom::TabParent* aBrowser) = 0;
|
||||
virtual void RemoveBrowser(mozilla::dom::TabParent* aBrowser) = 0;
|
||||
|
||||
typedef void (*BrowserEnumerator)(mozilla::dom::TabParent* aTab, void* aArg);
|
||||
|
||||
// Enumerate all stored browsers that for which the weak reference is valid.
|
||||
virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIWindowRoot, NS_IWINDOWROOT_IID)
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "nsIController.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIDOMXULElement.h"
|
||||
|
@ -385,6 +386,46 @@ nsWindowRoot::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|||
return mozilla::dom::WindowRootBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowRoot::AddBrowser(mozilla::dom::TabParent* aBrowser)
|
||||
{
|
||||
nsWeakPtr weakBrowser = do_GetWeakReference(static_cast<nsITabParent*>(aBrowser));
|
||||
mWeakBrowsers.PutEntry(weakBrowser);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowRoot::RemoveBrowser(mozilla::dom::TabParent* aBrowser)
|
||||
{
|
||||
nsWeakPtr weakBrowser = do_GetWeakReference(static_cast<nsITabParent*>(aBrowser));
|
||||
mWeakBrowsers.RemoveEntry(weakBrowser);
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
WeakBrowserEnumFunc(nsRefPtrHashKey<nsIWeakReference>* aKey, void* aArg)
|
||||
{
|
||||
nsTArray<nsRefPtr<TabParent>>* tabParents =
|
||||
static_cast<nsTArray<nsRefPtr<TabParent>>*>(aArg);
|
||||
nsCOMPtr<nsITabParent> tabParent(do_QueryReferent((*aKey).GetKey()));
|
||||
TabParent* tab = TabParent::GetFrom(tabParent);
|
||||
if (tab) {
|
||||
tabParents->AppendElement(tab);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindowRoot::EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg)
|
||||
{
|
||||
// Collect strong references to all browsers in a separate array in
|
||||
// case aEnumFunc alters mWeakBrowsers.
|
||||
nsTArray<nsRefPtr<TabParent>> tabParents;
|
||||
mWeakBrowsers.EnumerateEntries(WeakBrowserEnumFunc, &tabParents);
|
||||
|
||||
for (uint32_t i = 0; i < tabParents.Length(); ++i) {
|
||||
aEnumFunc(tabParents[i], aArg);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
already_AddRefed<EventTarget>
|
||||
|
|
|
@ -69,6 +69,10 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
|
||||
nsIDOMEventTarget)
|
||||
|
||||
virtual void AddBrowser(mozilla::dom::TabParent* aBrowser);
|
||||
virtual void RemoveBrowser(mozilla::dom::TabParent* aBrowser);
|
||||
virtual void EnumerateBrowsers(BrowserEnumerator aEnumFunc, void *aArg);
|
||||
|
||||
protected:
|
||||
virtual ~nsWindowRoot();
|
||||
|
||||
|
@ -84,6 +88,10 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mPopupNode; // [OWNER]
|
||||
|
||||
nsCOMPtr<mozilla::dom::EventTarget> mParent;
|
||||
|
||||
// The TabParents that are currently registered with this top-level window.
|
||||
typedef nsTHashtable<nsRefPtrHashKey<nsIWeakReference>> WeakBrowserTable;
|
||||
WeakBrowserTable mWeakBrowsers;
|
||||
};
|
||||
|
||||
extern already_AddRefed<mozilla::dom::EventTarget>
|
||||
|
|
|
@ -334,9 +334,27 @@ TabParent::SetOwnerElement(Element* aElement)
|
|||
// If we held previous content then unregister for its events.
|
||||
RemoveWindowListeners();
|
||||
|
||||
// If we change top-level documents then we need to change our
|
||||
// registration with them.
|
||||
nsRefPtr<nsPIWindowRoot> curTopLevelWin, newTopLevelWin;
|
||||
if (mFrameElement) {
|
||||
curTopLevelWin = nsContentUtils::GetWindowRoot(mFrameElement->OwnerDoc());
|
||||
}
|
||||
if (aElement) {
|
||||
newTopLevelWin = nsContentUtils::GetWindowRoot(aElement->OwnerDoc());
|
||||
}
|
||||
bool isSameTopLevelWin = curTopLevelWin == newTopLevelWin;
|
||||
if (curTopLevelWin && !isSameTopLevelWin) {
|
||||
curTopLevelWin->RemoveBrowser(this);
|
||||
}
|
||||
|
||||
// Update to the new content, and register to listen for events from it.
|
||||
mFrameElement = aElement;
|
||||
|
||||
if (newTopLevelWin && !isSameTopLevelWin) {
|
||||
newTopLevelWin->AddBrowser(this);
|
||||
}
|
||||
|
||||
AddWindowListeners();
|
||||
TryCacheDPIAndScale();
|
||||
}
|
||||
|
@ -1001,6 +1019,7 @@ TabParent::UIResolutionChanged()
|
|||
// TryCacheDPIAndScale()'s cache is keyed off of
|
||||
// mDPI being greater than 0, so this invalidates it.
|
||||
mDPI = -1;
|
||||
TryCacheDPIAndScale();
|
||||
unused << SendUIResolutionChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1822,9 +1822,24 @@ nsPresContext::UIResolutionChangedSubdocumentCallback(nsIDocument* aDocument,
|
|||
}
|
||||
|
||||
static void
|
||||
NotifyUIResolutionChanged(TabParent* aTabParent, void* aArg)
|
||||
NotifyTabUIResolutionChanged(TabParent* aTab, void *aArg)
|
||||
{
|
||||
aTabParent->UIResolutionChanged();
|
||||
aTab->UIResolutionChanged();
|
||||
}
|
||||
|
||||
static void
|
||||
NotifyChildrenUIResolutionChanged(nsIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
||||
if (!piWin) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIDocument> doc = piWin->GetExtantDoc();
|
||||
nsRefPtr<nsPIWindowRoot> topLevelWin = nsContentUtils::GetWindowRoot(doc);
|
||||
if (!topLevelWin) {
|
||||
return;
|
||||
}
|
||||
topLevelWin->EnumerateBrowsers(NotifyTabUIResolutionChanged, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1837,10 +1852,8 @@ nsPresContext::UIResolutionChangedInternal()
|
|||
AppUnitsPerDevPixelChanged();
|
||||
}
|
||||
|
||||
// Recursively notify all remote leaf descendants that the
|
||||
// resolution of the user interface has changed.
|
||||
nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
|
||||
NotifyUIResolutionChanged, nullptr);
|
||||
// Recursively notify all remote leaf descendants of the change.
|
||||
NotifyChildrenUIResolutionChanged(mDocument->GetWindow());
|
||||
|
||||
mDocument->EnumerateSubDocuments(UIResolutionChangedSubdocumentCallback,
|
||||
nullptr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче