mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1550637 - hide tooltip when the docshell navigate, don't show tooltips if the docshell is no longer active, r=nika,dao
Differential Revision: https://phabricator.services.mozilla.com/D35503 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
fc05893051
commit
5ae6f00741
@ -5557,26 +5557,6 @@ var XULBrowserWindow = {
|
||||
onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags, aIsSimulated) {
|
||||
var location = aLocationURI ? aLocationURI.spec : "";
|
||||
|
||||
let pageTooltip = document.getElementById("aHTMLTooltip");
|
||||
let tooltipNode = pageTooltip.triggerNode;
|
||||
if (tooltipNode) {
|
||||
// Optimise for the common case
|
||||
if (aWebProgress.isTopLevel) {
|
||||
pageTooltip.hidePopup();
|
||||
} else {
|
||||
for (
|
||||
let tooltipWindow = tooltipNode.ownerGlobal;
|
||||
tooltipWindow != tooltipWindow.parent;
|
||||
tooltipWindow = tooltipWindow.parent
|
||||
) {
|
||||
if (tooltipWindow == aWebProgress.DOMWindow) {
|
||||
pageTooltip.hidePopup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.hideOverLinkImmediately = true;
|
||||
this.setOverLink("", null);
|
||||
this.hideOverLinkImmediately = false;
|
||||
@ -5800,6 +5780,13 @@ var XULBrowserWindow = {
|
||||
|
||||
CombinedStopReload.onTabSwitch();
|
||||
|
||||
// Docshell should normally take care of hiding the tooltip, but we need to do it
|
||||
// ourselves for tabswitches.
|
||||
this.hideTooltip();
|
||||
|
||||
// Also hide tooltips for content loaded in the parent process:
|
||||
document.getElementById("aHTMLTooltip").hidePopup();
|
||||
|
||||
var nsIWebProgressListener = Ci.nsIWebProgressListener;
|
||||
var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
|
||||
// use a pseudo-object instead of a (potentially nonexistent) channel for getting
|
||||
|
@ -683,6 +683,11 @@ NS_IMETHODIMP
|
||||
nsDocShellTreeOwner::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, nsIURI* aURI,
|
||||
uint32_t aFlags) {
|
||||
if (mChromeTooltipListener && aWebProgress &&
|
||||
!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT) &&
|
||||
mChromeTooltipListener->WebProgressShowedTooltip(aWebProgress)) {
|
||||
mChromeTooltipListener->HideTooltip();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1186,6 +1191,7 @@ ChromeTooltipListener::HideTooltip() {
|
||||
mTooltipTimer = nullptr;
|
||||
// release tooltip target
|
||||
mPossibleTooltipNode = nullptr;
|
||||
mLastDocshell = nullptr;
|
||||
}
|
||||
|
||||
// if we're showing the tip, tell the chrome to hide it
|
||||
@ -1203,6 +1209,30 @@ ChromeTooltipListener::HideTooltip() {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool ChromeTooltipListener::WebProgressShowedTooltip(
|
||||
nsIWebProgress* aWebProgress) {
|
||||
nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(aWebProgress);
|
||||
nsCOMPtr<nsIDocShell> lastUsed = do_QueryReferent(mLastDocshell);
|
||||
while (lastUsed) {
|
||||
if (lastUsed == docshell) {
|
||||
return true;
|
||||
}
|
||||
// We can't use the docshell hierarchy here, because when the parent
|
||||
// docshell is navigated, the child docshell is disconnected (ie its
|
||||
// references to the parent are nulled out) despite it still being
|
||||
// alive here. So we use the document hierarchy instead:
|
||||
Document* document = lastUsed->GetDocument();
|
||||
if (document) {
|
||||
document = document->GetParentDocument();
|
||||
}
|
||||
if (!document) {
|
||||
break;
|
||||
}
|
||||
lastUsed = document->GetDocShell();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// A timer callback, fired when the mouse has hovered inside of a frame for the
|
||||
// appropriate amount of time. Getting to this point means that we should show
|
||||
// the tooltip, but only after we determine there is an appropriate TITLE
|
||||
@ -1244,7 +1274,7 @@ void ChromeTooltipListener::sTooltipCallback(nsITimer* aTimer,
|
||||
}
|
||||
}
|
||||
|
||||
if (!widget) {
|
||||
if (!widget || !docShell || !docShell->GetIsActive()) {
|
||||
// release tooltip target if there is one, NO MATTER WHAT
|
||||
self->mPossibleTooltipNode = nullptr;
|
||||
return;
|
||||
@ -1275,6 +1305,10 @@ void ChromeTooltipListener::sTooltipCallback(nsITimer* aTimer,
|
||||
self->mMouseScreenY - screenDot.y / scaleFactor,
|
||||
tooltipText, directionText);
|
||||
self->mLastShownTooltipText = std::move(tooltipText);
|
||||
if (self->mPossibleTooltipNode->OwnerDoc()) {
|
||||
self->mLastDocshell = do_GetWeakReference(
|
||||
self->mPossibleTooltipNode->OwnerDoc()->GetDocShell());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,10 @@ class ChromeTooltipListener final : public nsIDOMEventListener {
|
||||
NS_IMETHOD AddChromeListeners();
|
||||
NS_IMETHOD RemoveChromeListeners();
|
||||
|
||||
NS_IMETHOD HideTooltip();
|
||||
|
||||
bool WebProgressShowedTooltip(nsIWebProgress* aWebProgress);
|
||||
|
||||
private:
|
||||
// various delays for tooltips
|
||||
enum {
|
||||
@ -144,7 +148,6 @@ class ChromeTooltipListener final : public nsIDOMEventListener {
|
||||
NS_IMETHOD ShowTooltip(int32_t aInXCoords, int32_t aInYCoords,
|
||||
const nsAString& aInTipText,
|
||||
const nsAString& aDirText);
|
||||
NS_IMETHOD HideTooltip();
|
||||
nsITooltipTextProvider* GetTooltipTextProvider();
|
||||
|
||||
nsWebBrowser* mWebBrowser;
|
||||
@ -177,6 +180,8 @@ class ChromeTooltipListener final : public nsIDOMEventListener {
|
||||
// The string of text that we last displayed.
|
||||
nsString mLastShownTooltipText;
|
||||
|
||||
nsWeakPtr mLastDocshell;
|
||||
|
||||
// The node hovered over that fired the timer. This may turn into the node
|
||||
// that triggered the tooltip, but only if the timer ever gets around to
|
||||
// firing. This is a strong reference, because the tooltip content can be
|
||||
|
@ -589,7 +589,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
* visible, and thus is not a good candidate for certain optimizations
|
||||
* like image frame discarding. Docshells are active unless told otherwise.
|
||||
*/
|
||||
attribute boolean isActive;
|
||||
[infallible] attribute boolean isActive;
|
||||
|
||||
/**
|
||||
* The ID of the docshell in the session history.
|
||||
|
Loading…
Reference in New Issue
Block a user