mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1460691 - Support tooltips in top level non-XUL windows. r=enndeakin+6102,mats+6102
Add an anonymous XUL tooltip node to toplevel non-XUL windows. Setup a nsXULTooltipListener on non-XUL nsXULWindows. Make nsXULTooltipListener always use the default tooltip in the non-XUL case. MozReview-Commit-ID: Koe5m8PwMQM --HG-- extra : rebase_source : 242180e957758b51c589452e35deadac5ab06d9e
This commit is contained in:
parent
5935acc8f0
commit
afd85398a2
@ -130,7 +130,7 @@ nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
}
|
||||
|
||||
// Create a popupgroup element for chrome privileged top level non-XUL
|
||||
// documents to support context menus.
|
||||
// documents to support context menus and tooltips.
|
||||
if (PresContext()->IsChrome() && PresContext()->IsRoot() &&
|
||||
doc->AllowXULXBL() && !doc->IsXULDocument()) {
|
||||
nsNodeInfoManager* nodeInfoManager = doc->NodeInfoManager();
|
||||
@ -144,6 +144,23 @@ nsCanvasFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aElements.AppendElement(mPopupgroupContent);
|
||||
|
||||
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::tooltip, nullptr,
|
||||
kNameSpaceID_XUL,
|
||||
nsINode::ELEMENT_NODE);
|
||||
|
||||
rv = NS_NewXULElement(getter_AddRefs(mTooltipContent), nodeInfo.forget(),
|
||||
dom::NOT_FROM_PARSER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mTooltipContent->SetAttr(kNameSpaceID_None, nsGkAtoms::_default,
|
||||
NS_LITERAL_STRING("true"), false);
|
||||
// Set the page attribute so the XBL binding will find the text for the
|
||||
// tooltip from the currently hovered element.
|
||||
mTooltipContent->SetAttr(kNameSpaceID_None, nsGkAtoms::page,
|
||||
NS_LITERAL_STRING("true"), false);
|
||||
|
||||
aElements.AppendElement(mTooltipContent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -158,6 +175,9 @@ nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32
|
||||
if (mPopupgroupContent) {
|
||||
aElements.AppendElement(mPopupgroupContent);
|
||||
}
|
||||
if (mTooltipContent) {
|
||||
aElements.AppendElement(mTooltipContent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -188,6 +208,9 @@ nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestro
|
||||
if (mPopupgroupContent) {
|
||||
aPostDestroyData.AddAnonymousContent(mPopupgroupContent.forget());
|
||||
}
|
||||
if (mTooltipContent) {
|
||||
aPostDestroyData.AddAnonymousContent(mTooltipContent.forget());
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mPopupSetFrame ||
|
||||
nsLayoutUtils::IsProperAncestorFrame(this, mPopupSetFrame),
|
||||
@ -307,15 +330,15 @@ nsCanvasFrame::SetPopupSetFrame(nsPopupSetFrame* aPopupSet)
|
||||
Element*
|
||||
nsCanvasFrame::GetDefaultTooltip()
|
||||
{
|
||||
NS_WARNING("GetDefaultTooltip not implemented");
|
||||
return nullptr;
|
||||
return mTooltipContent;
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasFrame::SetDefaultTooltip(Element* aTooltip)
|
||||
{
|
||||
NS_WARNING("SetDefaultTooltip not implemented");
|
||||
return;
|
||||
MOZ_ASSERT(!aTooltip || aTooltip == mTooltipContent,
|
||||
"Default tooltip should be anonymous content tooltip.");
|
||||
mTooltipContent = aTooltip;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -135,6 +135,7 @@ protected:
|
||||
private:
|
||||
nsPopupSetFrame* mPopupSetFrame;
|
||||
nsCOMPtr<mozilla::dom::Element> mPopupgroupContent;
|
||||
nsCOMPtr<mozilla::dom::Element> mTooltipContent;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,7 @@ EXPORTS += [
|
||||
'nsPIBoxObject.h',
|
||||
'nsPIListBoxObject.h',
|
||||
'nsXULPopupManager.h',
|
||||
'nsXULTooltipListener.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
|
@ -400,7 +400,7 @@ nsXULTooltipListener::ShowTooltip()
|
||||
|
||||
// set the node in the document that triggered the tooltip and show it
|
||||
if (tooltipNode->GetComposedDoc() &&
|
||||
tooltipNode->GetComposedDoc()->IsXULDocument()) {
|
||||
nsContentUtils::IsChromeDoc(tooltipNode->GetComposedDoc())) {
|
||||
// Make sure the target node is still attached to some document.
|
||||
// It might have been deleted.
|
||||
if (sourceNode->IsInComposedDoc()) {
|
||||
@ -578,6 +578,18 @@ nsXULTooltipListener::FindTooltip(nsIContent* aTarget, nsIContent** aTooltip)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// non-XUL documents should just use the default tooltip
|
||||
if (!document->IsXULDocument()) {
|
||||
nsIPopupContainer* popupContainer =
|
||||
nsIPopupContainer::GetPopupContainer(document->GetShell());
|
||||
NS_ENSURE_STATE(popupContainer);
|
||||
if (RefPtr<Element> tooltip = popupContainer->GetDefaultTooltip()) {
|
||||
tooltip.forget(aTooltip);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString tooltipText;
|
||||
if (aTarget->IsElement()) {
|
||||
aTarget->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, tooltipText);
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsWebShellWindow.h" // get rid of this one, too...
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "XULDocument.h"
|
||||
#include "nsXULTooltipListener.h"
|
||||
|
||||
#include "prenv.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
@ -517,6 +518,8 @@ NS_IMETHODIMP nsXULWindow::Destroy()
|
||||
}
|
||||
#endif
|
||||
|
||||
RemoveTooltipSupport();
|
||||
|
||||
mDOMWindow = nullptr;
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mDocShell));
|
||||
@ -1127,6 +1130,7 @@ void nsXULWindow::OnChromeLoaded()
|
||||
if (mShowAfterLoad) {
|
||||
SetVisibility(true);
|
||||
}
|
||||
AddTooltipSupport();
|
||||
}
|
||||
// At this point the window may have been closed already during Show() or
|
||||
// SyncAttributesToWidget(), so nsXULWindow::Destroy may already have been
|
||||
@ -1135,6 +1139,50 @@ void nsXULWindow::OnChromeLoaded()
|
||||
mPersistentAttributesMask |= PAD_POSITION | PAD_SIZE | PAD_MISC;
|
||||
}
|
||||
|
||||
bool
|
||||
nsXULWindow::NeedsTooltipListener()
|
||||
{
|
||||
nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement();
|
||||
if (!docShellElement || docShellElement->IsXULElement()) {
|
||||
// Tooltips in XUL are handled by each element.
|
||||
return false;
|
||||
}
|
||||
// All other non-XUL document types need a tooltip listener.
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULWindow::AddTooltipSupport()
|
||||
{
|
||||
if (!NeedsTooltipListener()) {
|
||||
return;
|
||||
}
|
||||
nsXULTooltipListener* listener = nsXULTooltipListener::GetInstance();
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement();
|
||||
MOZ_ASSERT(docShellElement);
|
||||
listener->AddTooltipSupport(docShellElement);
|
||||
}
|
||||
|
||||
void
|
||||
nsXULWindow::RemoveTooltipSupport()
|
||||
{
|
||||
if (!NeedsTooltipListener()) {
|
||||
return;
|
||||
}
|
||||
nsXULTooltipListener* listener = nsXULTooltipListener::GetInstance();
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<dom::Element> docShellElement = GetWindowDOMElement();
|
||||
MOZ_ASSERT(docShellElement);
|
||||
listener->RemoveTooltipSupport(docShellElement);
|
||||
}
|
||||
|
||||
// If aSpecWidth and/or aSpecHeight are > 0, we will use these CSS px sizes
|
||||
// to fit to the screen when staggering windows; if they're negative,
|
||||
// we use the window's current size instead.
|
||||
|
@ -43,6 +43,7 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
class nsAtom;
|
||||
class nsXULTooltipListener;
|
||||
|
||||
// nsXULWindow
|
||||
|
||||
@ -108,6 +109,10 @@ protected:
|
||||
void SyncAttributesToWidget();
|
||||
NS_IMETHOD SavePersistentAttributes();
|
||||
|
||||
bool NeedsTooltipListener();
|
||||
void AddTooltipSupport();
|
||||
void RemoveTooltipSupport();
|
||||
|
||||
NS_IMETHOD GetWindowDOMWindow(mozIDOMWindowProxy** aDOMWindow);
|
||||
mozilla::dom::Element* GetWindowDOMElement() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user