mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 1483664: Part 0 - Dispatch pagehide/pageshow to all system group listeners on frameloader swap. r=smaug,mconley
Having to add pagehide/pageshow listeners to the chrome event target is a serious inconvience for the use cases of this bug. Dispatching to system group listeners has approximately the same effect as the old code, but is much easier for window-bound code to handle. --HG-- extra : rebase_source : d67c14e9ba91772d8a9dd82481120b34bdb551e0
This commit is contained in:
parent
dcee870651
commit
0c6cd02ae1
@ -42,8 +42,8 @@ class PluginChild extends ActorChild {
|
||||
// Cache of plugin crash information sent from the parent
|
||||
this.pluginCrashData = new Map();
|
||||
|
||||
this.mm.addEventListener("pagehide", this, true);
|
||||
this.mm.addEventListener("pageshow", this, true);
|
||||
this.mm.addEventListener("pagehide", this, {capture: true, mozSystemGroup: true});
|
||||
this.mm.addEventListener("pageshow", this, {capture: true, mozSystemGroup: true});
|
||||
}
|
||||
|
||||
receiveMessage(msg) {
|
||||
|
@ -19,8 +19,8 @@ let ACTORS = {
|
||||
events: {
|
||||
"AboutReaderContentLoaded": {wantUntrusted: true},
|
||||
"DOMContentLoaded": {},
|
||||
"pageshow": {},
|
||||
"pagehide": {},
|
||||
"pageshow": {mozSystemGroup: true},
|
||||
"pagehide": {mozSystemGroup: true},
|
||||
},
|
||||
messages: [
|
||||
"Reader:ToggleReaderMode",
|
||||
|
@ -8503,11 +8503,12 @@ nsContentUtils::SendMouseEvent(const nsCOMPtr<nsIPresShell>& aPresShell,
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
EventTarget* aChromeEventHandler)
|
||||
EventTarget* aChromeEventHandler,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
|
||||
NS_ASSERTION(doc, "What happened here?");
|
||||
doc->OnPageHide(true, aChromeEventHandler);
|
||||
doc->OnPageHide(true, aChromeEventHandler, aOnlySystemGroup);
|
||||
|
||||
int32_t childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
@ -8519,7 +8520,7 @@ nsContentUtils::FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
|
||||
for (uint32_t i = 0; i < kids.Length(); ++i) {
|
||||
if (kids[i]) {
|
||||
FirePageHideEvent(kids[i], aChromeEventHandler);
|
||||
FirePageHideEvent(kids[i], aChromeEventHandler, aOnlySystemGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8532,7 +8533,8 @@ nsContentUtils::FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
void
|
||||
nsContentUtils::FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
||||
EventTarget* aChromeEventHandler,
|
||||
bool aFireIfShowing)
|
||||
bool aFireIfShowing,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
int32_t childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
@ -8544,14 +8546,15 @@ nsContentUtils::FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
||||
|
||||
for (uint32_t i = 0; i < kids.Length(); ++i) {
|
||||
if (kids[i]) {
|
||||
FirePageShowEvent(kids[i], aChromeEventHandler, aFireIfShowing);
|
||||
FirePageShowEvent(kids[i], aChromeEventHandler, aFireIfShowing,
|
||||
aOnlySystemGroup);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = aItem->GetDocument();
|
||||
NS_ASSERTION(doc, "What happened here?");
|
||||
if (doc->IsShowing() == aFireIfShowing) {
|
||||
doc->OnPageShow(true, aChromeEventHandler);
|
||||
doc->OnPageShow(true, aChromeEventHandler, aOnlySystemGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2850,10 +2850,12 @@ public:
|
||||
|
||||
static void FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
||||
mozilla::dom::EventTarget* aChromeEventHandler,
|
||||
bool aFireIfShowing);
|
||||
bool aFireIfShowing,
|
||||
bool aOnlySystemGroup = false);
|
||||
|
||||
static void FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
mozilla::dom::EventTarget* aChromeEventHandler);
|
||||
mozilla::dom::EventTarget* aChromeEventHandler,
|
||||
bool aOnlySystemGroup = false);
|
||||
|
||||
static already_AddRefed<nsPIWindowRoot> GetWindowRoot(nsIDocument* aDoc);
|
||||
|
||||
|
@ -8328,7 +8328,8 @@ nsIDocument::GetContentInThisDocument(nsIFrame* aFrame) const
|
||||
void
|
||||
nsIDocument::DispatchPageTransition(EventTarget* aDispatchTarget,
|
||||
const nsAString& aType,
|
||||
bool aPersisted)
|
||||
bool aPersisted,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
if (!aDispatchTarget) {
|
||||
return;
|
||||
@ -8347,6 +8348,9 @@ nsIDocument::DispatchPageTransition(EventTarget* aDispatchTarget,
|
||||
|
||||
event->SetTrusted(true);
|
||||
event->SetTarget(this);
|
||||
if (aOnlySystemGroup) {
|
||||
event->WidgetEventPtr()->mFlags.mOnlySystemGroupDispatchInContent = true;
|
||||
}
|
||||
EventDispatcher::DispatchDOMEvent(aDispatchTarget, nullptr, event,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
@ -8360,7 +8364,8 @@ NotifyPageShow(nsIDocument* aDocument, void* aData)
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget)
|
||||
nsIDocument::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
mVisible = true;
|
||||
|
||||
@ -8413,7 +8418,8 @@ nsIDocument::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget)
|
||||
if (!target) {
|
||||
target = do_QueryInterface(GetWindow());
|
||||
}
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted);
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted,
|
||||
aOnlySystemGroup);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8460,7 +8466,8 @@ HasHttpScheme(nsIURI* aURI)
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget)
|
||||
nsIDocument::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
if (IsTopLevelContentDocument() && GetDocGroup() &&
|
||||
Telemetry::CanRecordExtended()) {
|
||||
@ -8532,7 +8539,8 @@ nsIDocument::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget)
|
||||
}
|
||||
{
|
||||
PageUnloadingEventTimeStamp timeStamp(this);
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted,
|
||||
aOnlySystemGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1341,7 +1341,8 @@ protected:
|
||||
|
||||
void DispatchPageTransition(mozilla::dom::EventTarget* aDispatchTarget,
|
||||
const nsAString& aType,
|
||||
bool aPersisted);
|
||||
bool aPersisted,
|
||||
bool aOnlySystemGroup = false);
|
||||
|
||||
// Call this before the document does something that will unbind all content.
|
||||
// That will stop us from doing a lot of work as each element is removed.
|
||||
@ -2197,12 +2198,14 @@ public:
|
||||
* PageTransitionEvent.webidl for a description of the |aPersisted|
|
||||
* parameter. If aDispatchStartTarget is null, the pageshow event is
|
||||
* dispatched on the ScriptGlobalObject for this document, otherwise it's
|
||||
* dispatched on aDispatchStartTarget.
|
||||
* dispatched on aDispatchStartTarget. If |aOnlySystemGroup| is true, the
|
||||
* event is only dispatched to listeners in the system group.
|
||||
* Note: if aDispatchStartTarget isn't null, the showing state of the
|
||||
* document won't be altered.
|
||||
*/
|
||||
virtual void OnPageShow(bool aPersisted,
|
||||
mozilla::dom::EventTarget* aDispatchStartTarget);
|
||||
mozilla::dom::EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup = false);
|
||||
|
||||
/**
|
||||
* Notification that the page has been hidden, for documents which are loaded
|
||||
@ -2212,12 +2215,14 @@ public:
|
||||
* window. See PageTransitionEvent.webidl for a description of the
|
||||
* |aPersisted| parameter. If aDispatchStartTarget is null, the pagehide
|
||||
* event is dispatched on the ScriptGlobalObject for this document,
|
||||
* otherwise it's dispatched on aDispatchStartTarget.
|
||||
* otherwise it's dispatched on aDispatchStartTarget. If |aOnlySystemGroup| is
|
||||
* true, the event is only dispatched to listeners in the system group.
|
||||
* Note: if aDispatchStartTarget isn't null, the showing state of the
|
||||
* document won't be altered.
|
||||
*/
|
||||
void OnPageHide(bool aPersisted,
|
||||
mozilla::dom::EventTarget* aDispatchStartTarget);
|
||||
mozilla::dom::EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup = false);
|
||||
|
||||
/*
|
||||
* We record the set of links in the document that are relevant to
|
||||
|
@ -51,10 +51,12 @@ function prepareForVisibilityEvents(browser, expectedOrder) {
|
||||
|
||||
rmvHide = BrowserTestUtils.addContentEventListener(browser, "pagehide",
|
||||
() => eventListener("pagehide"),
|
||||
false, checkFn, false, false);
|
||||
{mozSystemGroup: true}, checkFn,
|
||||
false, false);
|
||||
rmvShow = BrowserTestUtils.addContentEventListener(browser, "pageshow",
|
||||
() => eventListener("pageshow"),
|
||||
false, checkFn, false, false);
|
||||
{mozSystemGroup: true}, checkFn,
|
||||
false, false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -93,7 +95,7 @@ add_task(async function test_swap_frameloader_pagevisibility_events() {
|
||||
await ContentTask.spawn(emptyBrowser, {}, async() => {
|
||||
if (content.document.visibilityState === "hidden") {
|
||||
info("waiting for hidden emptyBrowser to pageshow");
|
||||
await ContentTaskUtils.waitForEvent(content, "pageshow");
|
||||
await ContentTaskUtils.waitForEvent(content, "pageshow", {mozSystemGroup: true});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -129,7 +129,7 @@ Test swapFrameLoaders with different frame types and remoteness
|
||||
});
|
||||
addEventListener("pagehide", function({ inFrameSwap }) {
|
||||
sendAsyncMessage("pagehide", inFrameSwap);
|
||||
});
|
||||
}, {mozSystemGroup: true});
|
||||
}`;
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,8 @@ ImageDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
|
||||
|
||||
void
|
||||
ImageDocument::OnPageShow(bool aPersisted,
|
||||
EventTarget* aDispatchStartTarget)
|
||||
EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup)
|
||||
{
|
||||
if (aPersisted) {
|
||||
mOriginalZoomLevel = IsSiteSpecific() ? 1.0 : GetZoomLevel();
|
||||
@ -315,7 +316,8 @@ ImageDocument::OnPageShow(bool aPersisted,
|
||||
RefPtr<ImageDocument> kungFuDeathGrip(this);
|
||||
UpdateSizeFromLayout();
|
||||
|
||||
MediaDocument::OnPageShow(aPersisted, aDispatchStartTarget);
|
||||
MediaDocument::OnPageShow(aPersisted, aDispatchStartTarget,
|
||||
aOnlySystemGroup);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject) override;
|
||||
virtual void Destroy() override;
|
||||
virtual void OnPageShow(bool aPersisted,
|
||||
EventTarget* aDispatchStartTarget) override;
|
||||
EventTarget* aDispatchStartTarget,
|
||||
bool aOnlySystemGroup = false) override;
|
||||
|
||||
NS_DECL_NSIIMAGEDOCUMENT
|
||||
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||
|
@ -2377,12 +2377,12 @@ TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
|
||||
|
||||
RefPtr<nsDocShell> docShell = static_cast<nsDocShell*>(ourDocShell.get());
|
||||
|
||||
nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
|
||||
nsCOMPtr<EventTarget> ourEventTarget = nsGlobalWindowOuter::Cast(ourWindow);
|
||||
|
||||
docShell->SetInFrameSwap(true);
|
||||
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, false);
|
||||
nsContentUtils::FirePageHideEvent(ourDocShell, ourEventTarget);
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, false, true);
|
||||
nsContentUtils::FirePageHideEvent(ourDocShell, ourEventTarget, true);
|
||||
|
||||
// Owner content type may have changed, so store the possibly updated context
|
||||
// and notify others.
|
||||
@ -2410,7 +2410,7 @@ TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
|
||||
RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
|
||||
}
|
||||
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, true);
|
||||
nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, true, true);
|
||||
|
||||
docShell->SetInFrameSwap(false);
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ var BrowserTestUtils = {
|
||||
/* eslint-enable no-eval */
|
||||
|
||||
let frameScriptSource =
|
||||
`data:,(${frameScript.toString()})(${id}, "${eventName}", ${useCapture}, "${checkFnSource}", ${wantsUntrusted})`;
|
||||
`data:,(${frameScript.toString()})(${id}, "${eventName}", ${uneval(useCapture)}, "${checkFnSource}", ${wantsUntrusted})`;
|
||||
|
||||
let mm = Services.mm;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user