1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsDocShellTreeOwner_h__
8 #define nsDocShellTreeOwner_h__
9 
10 // Helper Classes
11 #include "nsCOMPtr.h"
12 #include "nsString.h"
13 
14 // Interfaces Needed
15 #include "nsIBaseWindow.h"
16 #include "nsIDocShellTreeOwner.h"
17 #include "nsIInterfaceRequestor.h"
18 #include "nsIInterfaceRequestorUtils.h"
19 #include "nsIWebBrowserChrome.h"
20 #include "nsIDOMEventListener.h"
21 #include "nsIEmbeddingSiteWindow.h"
22 #include "nsIWebProgressListener.h"
23 #include "nsWeakReference.h"
24 #include "nsITimer.h"
25 #include "nsIPrompt.h"
26 #include "nsIAuthPrompt.h"
27 #include "nsITooltipTextProvider.h"
28 #include "nsCTooltipTextProvider.h"
29 
30 namespace mozilla {
31 namespace dom {
32 class Event;
33 class EventTarget;
34 }  // namespace dom
35 }  // namespace mozilla
36 
37 class nsIDocShellTreeItem;
38 class nsWebBrowser;
39 class ChromeTooltipListener;
40 
41 class nsDocShellTreeOwner final : public nsIDocShellTreeOwner,
42                                   public nsIBaseWindow,
43                                   public nsIInterfaceRequestor,
44                                   public nsIWebProgressListener,
45                                   public nsIDOMEventListener,
46                                   public nsSupportsWeakReference {
47   friend class nsWebBrowser;
48 
49  public:
50   NS_DECL_ISUPPORTS
51 
52   NS_DECL_NSIBASEWINDOW
53   NS_DECL_NSIDOCSHELLTREEOWNER
54   NS_DECL_NSIDOMEVENTLISTENER
55   NS_DECL_NSIINTERFACEREQUESTOR
56   NS_DECL_NSIWEBPROGRESSLISTENER
57 
58  protected:
59   nsDocShellTreeOwner();
60   virtual ~nsDocShellTreeOwner();
61 
62   void WebBrowser(nsWebBrowser* aWebBrowser);
63 
64   nsWebBrowser* WebBrowser();
65   NS_IMETHOD SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner);
66   NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome);
67 
68   NS_IMETHOD AddChromeListeners();
69   NS_IMETHOD RemoveChromeListeners();
70 
71   void EnsurePrompter();
72   void EnsureAuthPrompter();
73 
74   void AddToWatcher();
75   void RemoveFromWatcher();
76 
77   void EnsureContentTreeOwner();
78 
79   // These helper functions return the correct instances of the requested
80   // interfaces.  If the object passed to SetWebBrowserChrome() implements
81   // nsISupportsWeakReference, then these functions call QueryReferent on
82   // that object.  Otherwise, they return an addrefed pointer.  If the
83   // WebBrowserChrome object doesn't exist, they return nullptr.
84   already_AddRefed<nsIWebBrowserChrome> GetWebBrowserChrome();
85   already_AddRefed<nsIEmbeddingSiteWindow> GetOwnerWin();
86   already_AddRefed<nsIInterfaceRequestor> GetOwnerRequestor();
87 
88  protected:
89   // Weak References
90   nsWebBrowser* mWebBrowser;
91   nsIDocShellTreeOwner* mTreeOwner;
92   nsIDocShellTreeItem* mPrimaryContentShell;
93 
94   nsIWebBrowserChrome* mWebBrowserChrome;
95   nsIEmbeddingSiteWindow* mOwnerWin;
96   nsIInterfaceRequestor* mOwnerRequestor;
97 
98   nsWeakPtr mWebBrowserChromeWeak;  // nsIWebBrowserChrome
99 
100   // the objects that listen for chrome events like context menus and tooltips.
101   // They are separate objects to avoid circular references between |this|
102   // and the DOM.
103   RefPtr<ChromeTooltipListener> mChromeTooltipListener;
104 
105   RefPtr<nsDocShellTreeOwner> mContentTreeOwner;
106 
107   nsCOMPtr<nsIPrompt> mPrompter;
108   nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
109   nsCOMPtr<nsIRemoteTab> mPrimaryRemoteTab;
110 };
111 
112 // The class that listens to the chrome events and tells the embedding chrome to
113 // show tooltips, as appropriate. Handles registering itself with the DOM with
114 // AddChromeListeners() and removing itself with RemoveChromeListeners().
115 class ChromeTooltipListener final : public nsIDOMEventListener {
116  protected:
117   virtual ~ChromeTooltipListener();
118 
119  public:
120   NS_DECL_ISUPPORTS
121 
122   ChromeTooltipListener(nsWebBrowser* aInBrowser,
123                         nsIWebBrowserChrome* aInChrome);
124 
125   NS_DECL_NSIDOMEVENTLISTENER
126   NS_IMETHOD MouseMove(mozilla::dom::Event* aMouseEvent);
127 
128   // Add/remove the relevant listeners, based on what interfaces the embedding
129   // chrome implements.
130   NS_IMETHOD AddChromeListeners();
131   NS_IMETHOD RemoveChromeListeners();
132 
133   NS_IMETHOD HideTooltip();
134 
135   bool WebProgressShowedTooltip(nsIWebProgress* aWebProgress);
136 
137  private:
138   // various delays for tooltips
139   enum {
140     kTooltipAutoHideTime = 5000,    // ms
141     kTooltipMouseMoveTolerance = 7  // pixel tolerance for mousemove event
142   };
143 
144   NS_IMETHOD AddTooltipListener();
145   NS_IMETHOD RemoveTooltipListener();
146 
147   NS_IMETHOD ShowTooltip(int32_t aInXCoords, int32_t aInYCoords,
148                          const nsAString& aInTipText,
149                          const nsAString& aDirText);
150   nsITooltipTextProvider* GetTooltipTextProvider();
151 
152   nsWebBrowser* mWebBrowser;
153   nsCOMPtr<mozilla::dom::EventTarget> mEventTarget;
154   nsCOMPtr<nsITooltipTextProvider> mTooltipTextProvider;
155 
156   // This must be a strong ref in order to make sure we can hide the tooltip if
157   // the window goes away while we're displaying one. If we don't hold a strong
158   // ref, the chrome might have been disposed of before we get a chance to tell
159   // it, and no one would ever tell us of that fact.
160   nsCOMPtr<nsIWebBrowserChrome> mWebBrowserChrome;
161 
162   bool mTooltipListenerInstalled;
163 
164   nsCOMPtr<nsITimer> mTooltipTimer;
165   static void sTooltipCallback(nsITimer* aTimer, void* aListener);
166 
167   // Mouse coordinates for last mousemove event we saw
168   int32_t mMouseClientX;
169   int32_t mMouseClientY;
170 
171   // Mouse coordinates for tooltip event
172   int32_t mMouseScreenX;
173   int32_t mMouseScreenY;
174 
175   bool mShowingTooltip;
176 
177   bool mTooltipShownOnce;
178 
179   // The string of text that we last displayed.
180   nsString mLastShownTooltipText;
181 
182   nsWeakPtr mLastDocshell;
183 
184   // The node hovered over that fired the timer. This may turn into the node
185   // that triggered the tooltip, but only if the timer ever gets around to
186   // firing. This is a strong reference, because the tooltip content can be
187   // destroyed while we're waiting for the tooltip to pop up, and we need to
188   // detect that. It's set only when the tooltip timer is created and launched.
189   // The timer must either fire or be cancelled (or possibly released?), and we
190   // release this reference in each of those cases. So we don't leak.
191   nsCOMPtr<nsINode> mPossibleTooltipNode;
192 };
193 
194 #endif /* nsDocShellTreeOwner_h__ */
195