LCOV - code coverage report
Current view: directory - embedding/browser/webBrowser - nsDocShellTreeOwner.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 803 0 0.0 %
Date: 2012-06-02 Functions: 93 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is the Mozilla browser.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications, Inc.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1999
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Travis Bogard <travis@netscape.com>
      24                 :  *   Adam Lock <adamlock@netscape.com>
      25                 :  *   Mike Pinkerton <pinkerton@netscape.com>
      26                 :  *   Dan Rosen <dr@netscape.com>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      30                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : // Local Includes
      43                 : #include "nsDocShellTreeOwner.h"
      44                 : #include "nsWebBrowser.h"
      45                 : 
      46                 : // Helper Classes
      47                 : #include "nsStyleCoord.h"
      48                 : #include "nsSize.h"
      49                 : #include "nsHTMLReflowState.h"
      50                 : #include "nsIServiceManager.h"
      51                 : #include "nsComponentManagerUtils.h"
      52                 : #include "nsXPIDLString.h"
      53                 : #include "nsIAtom.h"
      54                 : #include "nsReadableUtils.h"
      55                 : #include "nsUnicharUtils.h"
      56                 : #include "nsISimpleEnumerator.h"
      57                 : #include "nsGUIEvent.h"
      58                 : #include "mozilla/LookAndFeel.h"
      59                 : 
      60                 : // Interfaces needed to be included
      61                 : #include "nsPresContext.h"
      62                 : #include "nsIContextMenuListener.h"
      63                 : #include "nsIContextMenuListener2.h"
      64                 : #include "nsITooltipListener.h"
      65                 : #include "nsIPrivateDOMEvent.h"
      66                 : #include "nsIDOMNode.h"
      67                 : #include "nsIDOMNodeList.h"
      68                 : #include "nsIDOMDocument.h"
      69                 : #include "nsIDOMDocumentType.h"
      70                 : #include "nsIDOMElement.h"
      71                 : #include "Link.h"
      72                 : #include "nsIDOMSVGElement.h"
      73                 : #include "nsIDOMSVGTitleElement.h"
      74                 : #include "nsIDOMEvent.h"
      75                 : #include "nsIDOMMouseEvent.h"
      76                 : #include "nsIDOMNSEvent.h"
      77                 : #include "nsIDOMNamedNodeMap.h"
      78                 : #include "nsIFormControl.h"
      79                 : #include "nsIDOMHTMLInputElement.h"
      80                 : #include "nsIDOMHTMLTextAreaElement.h"
      81                 : #include "nsIDOMHTMLHtmlElement.h"
      82                 : #include "nsIDOMHTMLAppletElement.h"
      83                 : #include "nsIDOMHTMLObjectElement.h"
      84                 : #include "nsIDOMHTMLEmbedElement.h"
      85                 : #include "nsIDOMHTMLDocument.h"
      86                 : #include "nsIImageLoadingContent.h"
      87                 : #include "nsIWebNavigation.h"
      88                 : #include "nsIDOMHTMLElement.h"
      89                 : #include "nsIPresShell.h"
      90                 : #include "nsPIDOMWindow.h"
      91                 : #include "nsPIWindowRoot.h"
      92                 : #include "nsIDOMWindowCollection.h"
      93                 : #include "nsIWindowWatcher.h"
      94                 : #include "nsPIWindowWatcher.h"
      95                 : #include "nsIPrompt.h"
      96                 : #include "nsRect.h"
      97                 : #include "nsIWebBrowserChromeFocus.h"
      98                 : #include "nsIContent.h"
      99                 : #include "imgIContainer.h"
     100                 : #include "nsContextMenuInfo.h"
     101                 : #include "nsPresContext.h"
     102                 : #include "nsIViewManager.h"
     103                 : #include "nsIView.h"
     104                 : #include "nsEventListenerManager.h"
     105                 : #include "nsIDOMDragEvent.h"
     106                 : #include "nsIConstraintValidation.h"
     107                 : 
     108                 : using namespace mozilla;
     109                 : 
     110                 : //
     111                 : // GetEventReceiver
     112                 : //
     113                 : // A helper routine that navigates the tricky path from a |nsWebBrowser| to
     114                 : // a |nsIDOMEventTarget| via the window root and chrome event handler.
     115                 : //
     116                 : static nsresult
     117               0 : GetDOMEventTarget( nsWebBrowser* inBrowser, nsIDOMEventTarget** aTarget)
     118                 : {
     119               0 :   NS_ENSURE_ARG_POINTER(inBrowser);
     120                 :   
     121               0 :   nsCOMPtr<nsIDOMWindow> domWindow;
     122               0 :   inBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
     123               0 :   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
     124                 : 
     125               0 :   nsCOMPtr<nsPIDOMWindow> domWindowPrivate = do_QueryInterface(domWindow);
     126               0 :   NS_ENSURE_TRUE(domWindowPrivate, NS_ERROR_FAILURE);
     127               0 :   nsPIDOMWindow *rootWindow = domWindowPrivate->GetPrivateRoot();
     128               0 :   NS_ENSURE_TRUE(rootWindow, NS_ERROR_FAILURE);
     129                 :   nsCOMPtr<nsIDOMEventTarget> target =
     130               0 :     rootWindow->GetChromeEventHandler();
     131               0 :   NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
     132               0 :   target.forget(aTarget);
     133                 :   
     134               0 :   return NS_OK;
     135                 : }
     136                 : 
     137                 : 
     138                 : //*****************************************************************************
     139                 : //***    nsDocShellTreeOwner: Object Management
     140                 : //*****************************************************************************
     141                 : 
     142               0 : nsDocShellTreeOwner::nsDocShellTreeOwner() :
     143                 :    mWebBrowser(nsnull), 
     144                 :    mTreeOwner(nsnull),
     145                 :    mPrimaryContentShell(nsnull),
     146                 :    mWebBrowserChrome(nsnull),
     147                 :    mOwnerWin(nsnull),
     148                 :    mOwnerRequestor(nsnull),
     149                 :    mChromeTooltipListener(nsnull),
     150               0 :    mChromeContextMenuListener(nsnull)
     151                 : {
     152               0 : }
     153                 : 
     154               0 : nsDocShellTreeOwner::~nsDocShellTreeOwner()
     155                 : {
     156               0 :   RemoveChromeListeners();
     157               0 : }
     158                 : 
     159                 : //*****************************************************************************
     160                 : // nsDocShellTreeOwner::nsISupports
     161                 : //*****************************************************************************   
     162                 : 
     163               0 : NS_IMPL_ADDREF(nsDocShellTreeOwner)
     164               0 : NS_IMPL_RELEASE(nsDocShellTreeOwner)
     165                 : 
     166               0 : NS_INTERFACE_MAP_BEGIN(nsDocShellTreeOwner)
     167               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
     168               0 :     NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
     169               0 :     NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
     170               0 :     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     171               0 :     NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
     172               0 :     NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
     173               0 :     NS_INTERFACE_MAP_ENTRY(nsICDocShellTreeOwner)
     174               0 :     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     175               0 : NS_INTERFACE_MAP_END
     176                 : 
     177                 : //*****************************************************************************
     178                 : // nsDocShellTreeOwner::nsIInterfaceRequestor
     179                 : //*****************************************************************************   
     180                 : 
     181                 : NS_IMETHODIMP
     182               0 : nsDocShellTreeOwner::GetInterface(const nsIID& aIID, void** aSink)
     183                 : {
     184               0 :   NS_ENSURE_ARG_POINTER(aSink);
     185                 : 
     186               0 :   if(NS_SUCCEEDED(QueryInterface(aIID, aSink)))
     187               0 :     return NS_OK;
     188                 : 
     189               0 :   if (aIID.Equals(NS_GET_IID(nsIWebBrowserChromeFocus))) {
     190               0 :     if (mWebBrowserChromeWeak != nsnull)
     191               0 :       return mWebBrowserChromeWeak->QueryReferent(aIID, aSink);
     192               0 :     return mOwnerWin->QueryInterface(aIID, aSink);
     193                 :   }
     194                 : 
     195               0 :   if (aIID.Equals(NS_GET_IID(nsIPrompt))) {
     196                 :     nsIPrompt *prompt;
     197               0 :     EnsurePrompter();
     198               0 :     prompt = mPrompter;
     199               0 :     if (prompt) {
     200               0 :       NS_ADDREF(prompt);
     201               0 :       *aSink = prompt;
     202               0 :       return NS_OK;
     203                 :     }
     204               0 :     return NS_NOINTERFACE;
     205                 :   }
     206                 : 
     207               0 :   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     208                 :     nsIAuthPrompt *prompt;
     209               0 :     EnsureAuthPrompter();
     210               0 :     prompt = mAuthPrompter;
     211               0 :     if (prompt) {
     212               0 :       NS_ADDREF(prompt);
     213               0 :       *aSink = prompt;
     214               0 :       return NS_OK;
     215                 :     }
     216               0 :     return NS_NOINTERFACE;
     217                 :   }
     218                 : 
     219               0 :   nsCOMPtr<nsIInterfaceRequestor> req = GetOwnerRequestor();
     220               0 :   if (req)
     221               0 :     return req->GetInterface(aIID, aSink);
     222                 : 
     223               0 :   return NS_NOINTERFACE;
     224                 : }
     225                 : 
     226                 : //*****************************************************************************
     227                 : // nsDocShellTreeOwner::nsIDocShellTreeOwner
     228                 : //*****************************************************************************   
     229                 : 
     230                 : NS_IMETHODIMP
     231               0 : nsDocShellTreeOwner::FindItemWithName(const PRUnichar* aName,
     232                 :                                       nsIDocShellTreeItem* aRequestor,
     233                 :                                       nsIDocShellTreeItem* aOriginalRequestor,
     234                 :                                       nsIDocShellTreeItem** aFoundItem)
     235                 : {
     236               0 :   NS_ENSURE_ARG(aName);
     237               0 :   NS_ENSURE_ARG_POINTER(aFoundItem);
     238               0 :   *aFoundItem = nsnull; // if we don't find one, we return NS_OK and a null result 
     239                 :   nsresult rv;
     240                 : 
     241               0 :   nsAutoString name(aName);
     242                 : 
     243               0 :   if (!mWebBrowser)
     244               0 :     return NS_OK; // stymied
     245                 : 
     246                 :   /* special cases */
     247               0 :   if(name.IsEmpty())
     248               0 :     return NS_OK;
     249               0 :   if(name.LowerCaseEqualsLiteral("_blank"))
     250               0 :     return NS_OK;
     251                 :   // _main is an IE target which should be case-insensitive but isn't
     252                 :   // see bug 217886 for details
     253                 :   // XXXbz what if our browser isn't targetable?  We need to handle that somehow.
     254               0 :   if(name.LowerCaseEqualsLiteral("_content") || name.EqualsLiteral("_main")) {
     255               0 :     *aFoundItem = mWebBrowser->mDocShellAsItem;
     256               0 :     NS_IF_ADDREF(*aFoundItem);
     257               0 :     return NS_OK;
     258                 :   }
     259                 : 
     260               0 :   if (!SameCOMIdentity(aRequestor, mWebBrowser->mDocShellAsItem)) {
     261                 :     // This isn't a request coming up from our kid, so check with said kid
     262               0 :     nsISupports* thisSupports = static_cast<nsIDocShellTreeOwner*>(this);
     263                 :     rv =
     264               0 :       mWebBrowser->mDocShellAsItem->FindItemWithName(aName, thisSupports,
     265               0 :                                                      aOriginalRequestor, aFoundItem);
     266               0 :     if (NS_FAILED(rv) || *aFoundItem) {
     267               0 :       return rv;
     268                 :     }
     269                 :   }
     270                 : 
     271                 :   // next, if we have a parent and it isn't the requestor, ask it
     272               0 :   if(mTreeOwner) {
     273               0 :     nsCOMPtr<nsIDocShellTreeOwner> reqAsTreeOwner(do_QueryInterface(aRequestor));
     274               0 :     if (mTreeOwner != reqAsTreeOwner)
     275                 :       return mTreeOwner->FindItemWithName(aName, mWebBrowser->mDocShellAsItem,
     276               0 :                                           aOriginalRequestor, aFoundItem);
     277               0 :     return NS_OK;
     278                 :   }
     279                 : 
     280                 :   // finally, failing everything else, search all windows
     281                 :   return FindItemWithNameAcrossWindows(aName, aRequestor, aOriginalRequestor,
     282               0 :                                        aFoundItem);
     283                 : }
     284                 : 
     285                 : nsresult
     286               0 : nsDocShellTreeOwner::FindItemWithNameAcrossWindows(const PRUnichar* aName,
     287                 :                                                    nsIDocShellTreeItem* aRequestor,
     288                 :                                                    nsIDocShellTreeItem* aOriginalRequestor,
     289                 :                                                    nsIDocShellTreeItem** aFoundItem)
     290                 : {
     291                 :   // search for the item across the list of top-level windows
     292               0 :   nsCOMPtr<nsPIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     293               0 :   if (!wwatch)
     294               0 :     return NS_OK;
     295                 : 
     296               0 :   return wwatch->FindItemWithName(aName, aRequestor, aOriginalRequestor,
     297               0 :                                   aFoundItem);
     298                 : }
     299                 : 
     300                 : void
     301               0 : nsDocShellTreeOwner::EnsurePrompter()
     302                 : {
     303               0 :   if (mPrompter)
     304               0 :     return;
     305                 : 
     306               0 :   nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     307               0 :   if (wwatch && mWebBrowser) {
     308               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
     309               0 :     mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
     310               0 :     if (domWindow)
     311               0 :       wwatch->GetNewPrompter(domWindow, getter_AddRefs(mPrompter));
     312                 :   }
     313                 : }
     314                 : 
     315                 : void
     316               0 : nsDocShellTreeOwner::EnsureAuthPrompter()
     317                 : {
     318               0 :   if (mAuthPrompter)
     319               0 :     return;
     320                 : 
     321               0 :   nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     322               0 :   if (wwatch && mWebBrowser) {
     323               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
     324               0 :     mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
     325               0 :     if (domWindow)
     326               0 :       wwatch->GetNewAuthPrompter(domWindow, getter_AddRefs(mAuthPrompter));
     327                 :   }
     328                 : }
     329                 : 
     330                 : void
     331               0 : nsDocShellTreeOwner::AddToWatcher()
     332                 : {
     333               0 :   if (mWebBrowser) {
     334               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
     335               0 :     mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
     336               0 :     if (domWindow) {
     337               0 :       nsCOMPtr<nsPIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     338               0 :       if (wwatch) {
     339               0 :         nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
     340               0 :         if (webBrowserChrome)
     341               0 :           wwatch->AddWindow(domWindow, webBrowserChrome);
     342                 :       }
     343                 :     }
     344                 :   }
     345               0 : }
     346                 : 
     347                 : void
     348               0 : nsDocShellTreeOwner::RemoveFromWatcher()
     349                 : {
     350               0 :   if (mWebBrowser) {
     351               0 :     nsCOMPtr<nsIDOMWindow> domWindow;
     352               0 :     mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
     353               0 :     if (domWindow) {
     354               0 :       nsCOMPtr<nsPIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
     355               0 :       if (wwatch)
     356               0 :         wwatch->RemoveWindow(domWindow);
     357                 :     }
     358                 :   }
     359               0 : }
     360                 : 
     361                 : 
     362                 : NS_IMETHODIMP
     363               0 : nsDocShellTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
     364                 :                                        bool aPrimary, bool aTargetable,
     365                 :                                        const nsAString& aID)
     366                 : {
     367               0 :    if(mTreeOwner)
     368                 :       return mTreeOwner->ContentShellAdded(aContentShell, aPrimary,
     369               0 :                                            aTargetable, aID);
     370                 : 
     371               0 :    if (aPrimary)
     372               0 :       mPrimaryContentShell = aContentShell;
     373               0 :    return NS_OK;
     374                 : }
     375                 : 
     376                 : NS_IMETHODIMP
     377               0 : nsDocShellTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
     378                 : {
     379               0 :   if(mTreeOwner)
     380               0 :     return mTreeOwner->ContentShellRemoved(aContentShell);
     381                 : 
     382               0 :   if(mPrimaryContentShell == aContentShell)
     383               0 :     mPrimaryContentShell = nsnull;
     384                 : 
     385               0 :   return NS_OK;
     386                 : }
     387                 : 
     388                 : NS_IMETHODIMP
     389               0 : nsDocShellTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
     390                 : {
     391               0 :    NS_ENSURE_ARG_POINTER(aShell);
     392                 : 
     393               0 :    if(mTreeOwner)
     394               0 :        return mTreeOwner->GetPrimaryContentShell(aShell);
     395                 : 
     396               0 :    *aShell = (mPrimaryContentShell ? mPrimaryContentShell : mWebBrowser->mDocShellAsItem.get());
     397               0 :    NS_IF_ADDREF(*aShell);
     398                 : 
     399               0 :    return NS_OK;
     400                 : }
     401                 : 
     402                 : NS_IMETHODIMP
     403               0 : nsDocShellTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
     404                 :                                  PRInt32 aCX, PRInt32 aCY)
     405                 : {
     406               0 :    nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
     407                 : 
     408               0 :    NS_ENSURE_STATE(mTreeOwner || webBrowserChrome);
     409                 : 
     410               0 :    if(mTreeOwner)
     411               0 :       return mTreeOwner->SizeShellTo(aShellItem, aCX, aCY);
     412                 : 
     413               0 :    if(aShellItem == mWebBrowser->mDocShellAsItem)
     414               0 :       return webBrowserChrome->SizeBrowserTo(aCX, aCY);
     415                 : 
     416               0 :    nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(aShellItem));
     417               0 :    NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
     418                 : 
     419               0 :    nsCOMPtr<nsIDOMDocument> domDocument;
     420               0 :    webNav->GetDocument(getter_AddRefs(domDocument));
     421               0 :    NS_ENSURE_TRUE(domDocument, NS_ERROR_FAILURE);
     422                 : 
     423               0 :    nsCOMPtr<nsIDOMElement> domElement;
     424               0 :    domDocument->GetDocumentElement(getter_AddRefs(domElement));
     425               0 :    NS_ENSURE_TRUE(domElement, NS_ERROR_FAILURE);
     426                 : 
     427                 :    // Set the preferred Size
     428                 :    //XXX
     429               0 :    NS_ERROR("Implement this");
     430                 :    /*
     431                 :    Set the preferred size on the aShellItem.
     432                 :    */
     433                 : 
     434               0 :    nsRefPtr<nsPresContext> presContext;
     435               0 :    mWebBrowser->mDocShell->GetPresContext(getter_AddRefs(presContext));
     436               0 :    NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
     437                 : 
     438               0 :    nsIPresShell *presShell = presContext->GetPresShell();
     439               0 :    NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
     440                 : 
     441               0 :    NS_ENSURE_SUCCESS(presShell->ResizeReflow(NS_UNCONSTRAINEDSIZE,
     442                 :       NS_UNCONSTRAINEDSIZE), NS_ERROR_FAILURE);
     443                 :    
     444               0 :    nsRect shellArea = presContext->GetVisibleArea();
     445                 : 
     446               0 :    PRInt32 browserCX = presContext->AppUnitsToDevPixels(shellArea.width);
     447               0 :    PRInt32 browserCY = presContext->AppUnitsToDevPixels(shellArea.height);
     448                 : 
     449               0 :    return webBrowserChrome->SizeBrowserTo(browserCX, browserCY);
     450                 : }
     451                 : 
     452                 : NS_IMETHODIMP
     453               0 : nsDocShellTreeOwner::SetPersistence(bool aPersistPosition,
     454                 :                                     bool aPersistSize,
     455                 :                                     bool aPersistSizeMode)
     456                 : {
     457               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     458                 : }
     459                 : 
     460                 : NS_IMETHODIMP
     461               0 : nsDocShellTreeOwner::GetPersistence(bool* aPersistPosition,
     462                 :                                     bool* aPersistSize,
     463                 :                                     bool* aPersistSizeMode)
     464                 : {
     465               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     466                 : }
     467                 : 
     468                 : NS_IMETHODIMP
     469               0 : nsDocShellTreeOwner::GetTargetableShellCount(PRUint32* aResult)
     470                 : {
     471               0 :   if(mTreeOwner) {
     472               0 :     mTreeOwner->GetTargetableShellCount(aResult);
     473                 :   } else {
     474               0 :     *aResult = 0;
     475                 :   }
     476                 : 
     477               0 :   return NS_OK;
     478                 : }
     479                 : 
     480                 : //*****************************************************************************
     481                 : // nsDocShellTreeOwner::nsIBaseWindow
     482                 : //*****************************************************************************   
     483                 : 
     484                 : 
     485                 : NS_IMETHODIMP
     486               0 : nsDocShellTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
     487                 :                                 nsIWidget* aParentWidget, PRInt32 aX,
     488                 :                                 PRInt32 aY, PRInt32 aCX, PRInt32 aCY)   
     489                 : {
     490               0 :   return NS_ERROR_NULL_POINTER;
     491                 : }
     492                 : 
     493                 : NS_IMETHODIMP
     494               0 : nsDocShellTreeOwner::Create()
     495                 : {
     496               0 :   return NS_ERROR_NULL_POINTER;
     497                 : }
     498                 : 
     499                 : NS_IMETHODIMP
     500               0 : nsDocShellTreeOwner::Destroy()
     501                 : {
     502               0 :   nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
     503               0 :   if (webBrowserChrome)
     504                 :   {
     505               0 :     return webBrowserChrome->DestroyBrowserWindow();
     506                 :   }
     507                 : 
     508               0 :   return NS_ERROR_NULL_POINTER;
     509                 : }
     510                 : 
     511                 : NS_IMETHODIMP
     512               0 : nsDocShellTreeOwner::SetPosition(PRInt32 aX, PRInt32 aY)
     513                 : {
     514               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     515               0 :   if (ownerWin)
     516                 :   {
     517               0 :     return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
     518               0 :                                    aX, aY, 0, 0);
     519                 :   }
     520               0 :   return NS_ERROR_NULL_POINTER;
     521                 : }
     522                 : 
     523                 : NS_IMETHODIMP
     524               0 : nsDocShellTreeOwner::GetPosition(PRInt32* aX, PRInt32* aY)
     525                 : {
     526               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     527               0 :   if (ownerWin)
     528                 :   {
     529               0 :     return ownerWin->GetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
     530               0 :                                    aX, aY, nsnull, nsnull);
     531                 :   }
     532               0 :   return NS_ERROR_NULL_POINTER;
     533                 : }
     534                 : 
     535                 : NS_IMETHODIMP
     536               0 : nsDocShellTreeOwner::SetSize(PRInt32 aCX, PRInt32 aCY, bool aRepaint)
     537                 : {
     538               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     539               0 :   if (ownerWin)
     540                 :   {
     541               0 :     return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER,
     542               0 :                                    0, 0, aCX, aCY);
     543                 :   }
     544               0 :   return NS_ERROR_NULL_POINTER;
     545                 : }
     546                 : 
     547                 : NS_IMETHODIMP
     548               0 : nsDocShellTreeOwner::GetSize(PRInt32* aCX, PRInt32* aCY)
     549                 : {
     550               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     551               0 :   if (ownerWin)
     552                 :   {
     553               0 :     return ownerWin->GetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER,
     554               0 :                                    nsnull, nsnull, aCX, aCY);
     555                 :   }
     556               0 :   return NS_ERROR_NULL_POINTER;
     557                 : }
     558                 : 
     559                 : NS_IMETHODIMP
     560               0 : nsDocShellTreeOwner::SetPositionAndSize(PRInt32 aX, PRInt32 aY, PRInt32 aCX,
     561                 :                                         PRInt32 aCY, bool aRepaint)
     562                 : {
     563               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     564               0 :   if (ownerWin)
     565                 :   {
     566               0 :     return ownerWin->SetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER |
     567                 :                                    nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
     568               0 :                                    aX, aY, aCX, aCY);
     569                 :   }
     570               0 :   return NS_ERROR_NULL_POINTER;
     571                 : }
     572                 : 
     573                 : NS_IMETHODIMP
     574               0 : nsDocShellTreeOwner::GetPositionAndSize(PRInt32* aX, PRInt32* aY, PRInt32* aCX,
     575                 :                                         PRInt32* aCY)
     576                 : {
     577               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     578               0 :   if (ownerWin)
     579                 :   {
     580               0 :     return ownerWin->GetDimensions(nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER |
     581                 :                                    nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION,
     582               0 :                                    aX, aY, aCX, aCY);
     583                 :   }
     584               0 :   return NS_ERROR_NULL_POINTER;
     585                 : }
     586                 : 
     587                 : NS_IMETHODIMP
     588               0 : nsDocShellTreeOwner::Repaint(bool aForce)
     589                 : {
     590               0 :   return NS_ERROR_NULL_POINTER;
     591                 : }
     592                 : 
     593                 : NS_IMETHODIMP
     594               0 : nsDocShellTreeOwner::GetParentWidget(nsIWidget** aParentWidget)
     595                 : {
     596               0 :   return NS_ERROR_NULL_POINTER;
     597                 : }
     598                 : 
     599                 : NS_IMETHODIMP
     600               0 : nsDocShellTreeOwner::SetParentWidget(nsIWidget* aParentWidget)
     601                 : {
     602               0 :   return NS_ERROR_NULL_POINTER;
     603                 : }
     604                 : 
     605                 : NS_IMETHODIMP
     606               0 : nsDocShellTreeOwner::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
     607                 : {
     608               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     609               0 :   if (ownerWin)
     610                 :   {
     611               0 :     return ownerWin->GetSiteWindow(aParentNativeWindow);
     612                 :   }
     613               0 :   return NS_ERROR_NULL_POINTER;
     614                 : }
     615                 : 
     616                 : NS_IMETHODIMP
     617               0 : nsDocShellTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow)
     618                 : {
     619               0 :   return NS_ERROR_NULL_POINTER;
     620                 : }
     621                 : 
     622                 : NS_IMETHODIMP
     623               0 : nsDocShellTreeOwner::GetVisibility(bool* aVisibility)
     624                 : {
     625               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     626               0 :   if (ownerWin)
     627                 :   {
     628               0 :     return ownerWin->GetVisibility(aVisibility);
     629                 :   }
     630               0 :   return NS_ERROR_NULL_POINTER;
     631                 : }
     632                 : 
     633                 : NS_IMETHODIMP
     634               0 : nsDocShellTreeOwner::SetVisibility(bool aVisibility)
     635                 : {
     636               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     637               0 :   if (ownerWin)
     638                 :   {
     639               0 :     return ownerWin->SetVisibility(aVisibility);
     640                 :   }
     641               0 :   return NS_ERROR_NULL_POINTER;
     642                 : }
     643                 : 
     644                 : NS_IMETHODIMP
     645               0 : nsDocShellTreeOwner::GetEnabled(bool *aEnabled)
     646                 : {
     647               0 :   NS_ENSURE_ARG_POINTER(aEnabled);
     648               0 :   *aEnabled = true;
     649               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     650                 : }
     651                 : 
     652                 : NS_IMETHODIMP
     653               0 : nsDocShellTreeOwner::SetEnabled(bool aEnabled)
     654                 : {
     655               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     656                 : }
     657                 : 
     658                 : NS_IMETHODIMP
     659               0 : nsDocShellTreeOwner::GetMainWidget(nsIWidget** aMainWidget)
     660                 : {
     661               0 :     return NS_ERROR_NULL_POINTER;
     662                 : }
     663                 : 
     664                 : NS_IMETHODIMP
     665               0 : nsDocShellTreeOwner::SetFocus()
     666                 : {
     667               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     668               0 :   if (ownerWin)
     669                 :   {
     670               0 :     return ownerWin->SetFocus();
     671                 :   }
     672               0 :   return NS_ERROR_NULL_POINTER;
     673                 : }
     674                 : 
     675                 : NS_IMETHODIMP
     676               0 : nsDocShellTreeOwner::GetTitle(PRUnichar** aTitle)
     677                 : {
     678               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     679               0 :   if (ownerWin)
     680                 :   {
     681               0 :     return ownerWin->GetTitle(aTitle);
     682                 :   }
     683               0 :   return NS_ERROR_NULL_POINTER;
     684                 : }
     685                 : 
     686                 : NS_IMETHODIMP
     687               0 : nsDocShellTreeOwner::SetTitle(const PRUnichar* aTitle)
     688                 : {
     689               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin = GetOwnerWin();
     690               0 :   if (ownerWin)
     691                 :   {
     692               0 :     return ownerWin->SetTitle(aTitle);
     693                 :   }
     694               0 :   return NS_ERROR_NULL_POINTER;
     695                 : }
     696                 : 
     697                 : 
     698                 : //*****************************************************************************
     699                 : // nsDocShellTreeOwner::nsIWebProgressListener
     700                 : //*****************************************************************************   
     701                 : 
     702                 : 
     703                 : NS_IMETHODIMP
     704               0 : nsDocShellTreeOwner::OnProgressChange(nsIWebProgress* aProgress,
     705                 :                                       nsIRequest* aRequest,
     706                 :                                       PRInt32 aCurSelfProgress,
     707                 :                                       PRInt32 aMaxSelfProgress, 
     708                 :                                       PRInt32 aCurTotalProgress,
     709                 :                                       PRInt32 aMaxTotalProgress)
     710                 : {
     711                 :     // In the absence of DOM document creation event, this method is the
     712                 :     // most convenient place to install the mouse listener on the
     713                 :     // DOM document.
     714               0 :     return AddChromeListeners();
     715                 : }
     716                 : 
     717                 : NS_IMETHODIMP
     718               0 : nsDocShellTreeOwner::OnStateChange(nsIWebProgress* aProgress,
     719                 :                                    nsIRequest* aRequest,
     720                 :                                    PRUint32 aProgressStateFlags,
     721                 :                                    nsresult aStatus)
     722                 : {
     723               0 :     return NS_OK;
     724                 : }
     725                 : 
     726                 : NS_IMETHODIMP
     727               0 : nsDocShellTreeOwner::OnLocationChange(nsIWebProgress* aWebProgress,
     728                 :                                       nsIRequest* aRequest,
     729                 :                                       nsIURI* aURI,
     730                 :                                       PRUint32 aFlags)
     731                 : {
     732               0 :     return NS_OK;
     733                 : }
     734                 : 
     735                 : NS_IMETHODIMP 
     736               0 : nsDocShellTreeOwner::OnStatusChange(nsIWebProgress* aWebProgress,
     737                 :                                     nsIRequest* aRequest,
     738                 :                                     nsresult aStatus,
     739                 :                                     const PRUnichar* aMessage)
     740                 : {
     741               0 :     return NS_OK;
     742                 : }
     743                 : 
     744                 : NS_IMETHODIMP 
     745               0 : nsDocShellTreeOwner::OnSecurityChange(nsIWebProgress *aWebProgress, 
     746                 :                                       nsIRequest *aRequest, 
     747                 :                                       PRUint32 state)
     748                 : {
     749               0 :     return NS_OK;
     750                 : }
     751                 : 
     752                 : 
     753                 : //*****************************************************************************
     754                 : // nsDocShellTreeOwner: Helpers
     755                 : //*****************************************************************************   
     756                 : 
     757                 : //*****************************************************************************
     758                 : // nsDocShellTreeOwner: Accessors
     759                 : //*****************************************************************************   
     760                 : 
     761                 : void
     762               0 : nsDocShellTreeOwner::WebBrowser(nsWebBrowser* aWebBrowser)
     763                 : {
     764               0 :   if ( !aWebBrowser )
     765               0 :     RemoveChromeListeners();
     766               0 :   if (aWebBrowser != mWebBrowser) {
     767               0 :     mPrompter = 0;
     768               0 :     mAuthPrompter = 0;
     769                 :   }
     770                 : 
     771               0 :   mWebBrowser = aWebBrowser;
     772               0 : }
     773                 : 
     774                 : nsWebBrowser *
     775               0 : nsDocShellTreeOwner::WebBrowser()
     776                 : {
     777               0 :    return mWebBrowser;
     778                 : }
     779                 : 
     780                 : NS_IMETHODIMP
     781               0 : nsDocShellTreeOwner::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
     782                 : { 
     783               0 :   if(aTreeOwner) {
     784               0 :     nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(aTreeOwner));
     785               0 :     NS_ENSURE_TRUE(webBrowserChrome, NS_ERROR_INVALID_ARG);
     786               0 :     NS_ENSURE_SUCCESS(SetWebBrowserChrome(webBrowserChrome), NS_ERROR_INVALID_ARG);
     787               0 :     mTreeOwner = aTreeOwner;
     788                 :   }
     789                 :   else {
     790               0 :     mTreeOwner = nsnull;
     791               0 :     nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
     792               0 :     if (!webBrowserChrome)
     793               0 :       NS_ENSURE_SUCCESS(SetWebBrowserChrome(nsnull), NS_ERROR_FAILURE);
     794                 :   }
     795                 : 
     796               0 :   return NS_OK;
     797                 : }
     798                 : 
     799                 : NS_IMETHODIMP
     800               0 : nsDocShellTreeOwner::SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome)
     801                 : {
     802               0 :   if(!aWebBrowserChrome) {
     803               0 :     mWebBrowserChrome = nsnull;
     804               0 :     mOwnerWin = nsnull;
     805               0 :     mOwnerRequestor = nsnull;
     806               0 :     mWebBrowserChromeWeak = 0;
     807                 :   } else {
     808                 :     nsCOMPtr<nsISupportsWeakReference> supportsweak =
     809               0 :                                            do_QueryInterface(aWebBrowserChrome);
     810               0 :     if (supportsweak) {
     811               0 :       supportsweak->GetWeakReference(getter_AddRefs(mWebBrowserChromeWeak));
     812                 :     } else {
     813               0 :       nsCOMPtr<nsIEmbeddingSiteWindow> ownerWin(do_QueryInterface(aWebBrowserChrome));
     814               0 :       nsCOMPtr<nsIInterfaceRequestor> requestor(do_QueryInterface(aWebBrowserChrome));
     815                 : 
     816                 :       // it's ok for ownerWin or requestor to be null.
     817               0 :       mWebBrowserChrome = aWebBrowserChrome;
     818               0 :       mOwnerWin = ownerWin;
     819               0 :       mOwnerRequestor = requestor;
     820                 :     }
     821                 :   }
     822               0 :   return NS_OK;
     823                 : }
     824                 : 
     825                 : 
     826                 : //
     827                 : // AddChromeListeners
     828                 : //
     829                 : // Hook up things to the chrome like context menus and tooltips, if the chrome
     830                 : // has implemented the right interfaces.
     831                 : //
     832                 : NS_IMETHODIMP
     833               0 : nsDocShellTreeOwner::AddChromeListeners()
     834                 : {
     835               0 :   nsresult rv = NS_OK;
     836                 : 
     837               0 :   nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome = GetWebBrowserChrome();
     838               0 :   if (!webBrowserChrome)
     839               0 :     return NS_ERROR_FAILURE;
     840                 : 
     841                 :   // install tooltips
     842               0 :   if ( !mChromeTooltipListener ) { 
     843                 :     nsCOMPtr<nsITooltipListener>
     844               0 :                            tooltipListener(do_QueryInterface(webBrowserChrome));
     845               0 :     if ( tooltipListener ) {
     846                 :       mChromeTooltipListener = new ChromeTooltipListener(mWebBrowser,
     847               0 :                                                          webBrowserChrome);
     848               0 :       if ( mChromeTooltipListener ) {
     849               0 :         NS_ADDREF(mChromeTooltipListener);
     850               0 :         rv = mChromeTooltipListener->AddChromeListeners();
     851                 :       }
     852                 :       else
     853               0 :         rv = NS_ERROR_OUT_OF_MEMORY;
     854                 :     }
     855                 :   }
     856                 :   
     857                 :   // install context menus
     858               0 :   if ( !mChromeContextMenuListener ) {
     859                 :     nsCOMPtr<nsIContextMenuListener2>
     860               0 :                           contextListener2(do_QueryInterface(webBrowserChrome));
     861                 :     nsCOMPtr<nsIContextMenuListener>
     862               0 :                            contextListener(do_QueryInterface(webBrowserChrome));
     863               0 :     if ( contextListener2 || contextListener ) {
     864                 :       mChromeContextMenuListener =
     865               0 :                    new ChromeContextMenuListener(mWebBrowser, webBrowserChrome);
     866               0 :       if ( mChromeContextMenuListener ) {
     867               0 :         NS_ADDREF(mChromeContextMenuListener);
     868               0 :         rv = mChromeContextMenuListener->AddChromeListeners();
     869                 :       }
     870                 :       else
     871               0 :         rv = NS_ERROR_OUT_OF_MEMORY;
     872                 :     }
     873                 :   }
     874                 : 
     875                 :   // register dragover and drop event listeners with the listener manager
     876               0 :   nsCOMPtr<nsIDOMEventTarget> target;
     877               0 :   GetDOMEventTarget(mWebBrowser, getter_AddRefs(target));
     878                 : 
     879               0 :   nsEventListenerManager* elmP = target->GetListenerManager(true);
     880               0 :   if (elmP) {
     881               0 :     elmP->AddEventListenerByType(this, NS_LITERAL_STRING("dragover"),
     882                 :                                  NS_EVENT_FLAG_BUBBLE |
     883               0 :                                  NS_EVENT_FLAG_SYSTEM_EVENT);
     884               0 :     elmP->AddEventListenerByType(this, NS_LITERAL_STRING("drop"),
     885                 :                                  NS_EVENT_FLAG_BUBBLE |
     886               0 :                                  NS_EVENT_FLAG_SYSTEM_EVENT);
     887                 :   }
     888                 : 
     889               0 :   return rv;
     890                 :   
     891                 : } // AddChromeListeners
     892                 : 
     893                 : 
     894                 : NS_IMETHODIMP
     895               0 : nsDocShellTreeOwner::RemoveChromeListeners()
     896                 : {
     897               0 :   if ( mChromeTooltipListener ) {
     898               0 :     mChromeTooltipListener->RemoveChromeListeners();
     899               0 :     NS_RELEASE(mChromeTooltipListener);
     900                 :   }
     901               0 :   if ( mChromeContextMenuListener ) {
     902               0 :     mChromeContextMenuListener->RemoveChromeListeners();
     903               0 :     NS_RELEASE(mChromeContextMenuListener);
     904                 :   }
     905                 : 
     906               0 :   nsCOMPtr<nsIDOMEventTarget> piTarget;
     907               0 :   GetDOMEventTarget(mWebBrowser, getter_AddRefs(piTarget));
     908               0 :   if (!piTarget)
     909               0 :     return NS_OK;
     910                 : 
     911               0 :   nsEventListenerManager* elmP = piTarget->GetListenerManager(true);
     912               0 :   if (elmP)
     913                 :   {
     914               0 :     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("dragover"),
     915                 :                                     NS_EVENT_FLAG_BUBBLE |
     916               0 :                                     NS_EVENT_FLAG_SYSTEM_EVENT);
     917               0 :     elmP->RemoveEventListenerByType(this, NS_LITERAL_STRING("drop"),
     918                 :                                     NS_EVENT_FLAG_BUBBLE |
     919               0 :                                     NS_EVENT_FLAG_SYSTEM_EVENT);
     920                 :   }
     921                 : 
     922               0 :   return NS_OK;
     923                 : }
     924                 : 
     925                 : NS_IMETHODIMP
     926               0 : nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
     927                 : {
     928               0 :   nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
     929               0 :   NS_ENSURE_TRUE(dragEvent, NS_ERROR_INVALID_ARG);
     930                 : 
     931               0 :   nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aEvent);
     932               0 :   if (domNSEvent) {
     933                 :     bool defaultPrevented;
     934               0 :     domNSEvent->GetPreventDefault(&defaultPrevented);
     935               0 :     if (defaultPrevented)
     936               0 :       return NS_OK;
     937                 :   }
     938                 : 
     939               0 :   nsCOMPtr<nsIDroppedLinkHandler> handler = do_GetService("@mozilla.org/content/dropped-link-handler;1");
     940               0 :   if (handler) {
     941               0 :     nsAutoString eventType;
     942               0 :     aEvent->GetType(eventType);
     943               0 :     if (eventType.EqualsLiteral("dragover")) {
     944                 :       bool canDropLink;
     945               0 :       handler->CanDropLink(dragEvent, false, &canDropLink);
     946               0 :       if (canDropLink)
     947               0 :         aEvent->PreventDefault();
     948                 :     }
     949               0 :     else if (eventType.EqualsLiteral("drop")) {
     950               0 :       nsIWebNavigation* webnav = static_cast<nsIWebNavigation *>(mWebBrowser);
     951                 : 
     952               0 :       nsAutoString link, name;
     953               0 :       if (webnav && NS_SUCCEEDED(handler->DropLink(dragEvent, link, false, name))) {
     954               0 :         if (!link.IsEmpty()) {
     955               0 :           webnav->LoadURI(link.get(), 0, nsnull, nsnull, nsnull);
     956                 :         }
     957                 :       }
     958                 :       else {
     959               0 :         aEvent->StopPropagation();
     960               0 :         aEvent->PreventDefault();
     961                 :       }
     962                 :     }
     963                 :   }
     964                 : 
     965               0 :   return NS_OK;
     966                 : }
     967                 : 
     968                 : already_AddRefed<nsIWebBrowserChrome>
     969               0 : nsDocShellTreeOwner::GetWebBrowserChrome()
     970                 : {
     971               0 :   nsCOMPtr<nsIWebBrowserChrome> chrome;
     972               0 :   if (mWebBrowserChromeWeak) {
     973               0 :     chrome = do_QueryReferent(mWebBrowserChromeWeak);
     974               0 :   } else if (mWebBrowserChrome) {
     975               0 :     chrome = mWebBrowserChrome;
     976                 :   }
     977               0 :   return chrome.forget();
     978                 : }
     979                 : 
     980                 : already_AddRefed<nsIEmbeddingSiteWindow>
     981               0 : nsDocShellTreeOwner::GetOwnerWin()
     982                 : {
     983               0 :   nsCOMPtr<nsIEmbeddingSiteWindow> win;
     984               0 :   if (mWebBrowserChromeWeak) {
     985               0 :     win = do_QueryReferent(mWebBrowserChromeWeak);
     986               0 :   } else if (mOwnerWin) {
     987               0 :     win = mOwnerWin;
     988                 :   }
     989               0 :   return win.forget();
     990                 : }
     991                 : 
     992                 : already_AddRefed<nsIInterfaceRequestor>
     993               0 : nsDocShellTreeOwner::GetOwnerRequestor()
     994                 : {
     995               0 :   nsCOMPtr<nsIInterfaceRequestor> req;
     996               0 :   if (mWebBrowserChromeWeak) {
     997               0 :     req = do_QueryReferent(mWebBrowserChromeWeak);
     998               0 :   } else if (mOwnerRequestor) {
     999               0 :     req = mOwnerRequestor;
    1000                 :   }
    1001               0 :   return req.forget();
    1002                 : }
    1003                 : 
    1004                 : 
    1005                 : ///////////////////////////////////////////////////////////////////////////////
    1006                 : // DefaultTooltipTextProvider
    1007                 : 
    1008                 : class DefaultTooltipTextProvider : public nsITooltipTextProvider
    1009               0 : {
    1010                 : public:
    1011                 :     DefaultTooltipTextProvider();
    1012                 : 
    1013                 :     NS_DECL_ISUPPORTS
    1014                 :     NS_DECL_NSITOOLTIPTEXTPROVIDER
    1015                 :     
    1016                 : protected:
    1017                 :     nsCOMPtr<nsIAtom>   mTag_dialog;
    1018                 :     nsCOMPtr<nsIAtom>   mTag_dialogheader;
    1019                 :     nsCOMPtr<nsIAtom>   mTag_window;
    1020                 : };
    1021                 : 
    1022               0 : NS_IMPL_THREADSAFE_ISUPPORTS1(DefaultTooltipTextProvider, nsITooltipTextProvider)
    1023                 : 
    1024               0 : DefaultTooltipTextProvider::DefaultTooltipTextProvider()
    1025                 : {
    1026                 :     // There are certain element types which we don't want to use
    1027                 :     // as tool tip text. 
    1028               0 :     mTag_dialog       = do_GetAtom("dialog");
    1029               0 :     mTag_dialogheader = do_GetAtom("dialogheader");
    1030               0 :     mTag_window       = do_GetAtom("window");   
    1031               0 : }
    1032                 : 
    1033                 : //
    1034                 : // UseSVGTitle
    1035                 : //
    1036                 : // A helper routine that determines whether we're still interested
    1037                 : // in SVG titles. We need to stop at the SVG root element that
    1038                 : // has a document node parent
    1039                 : //
    1040                 : static bool
    1041               0 : UseSVGTitle(nsIDOMElement *currElement)
    1042                 : {
    1043               0 :   nsCOMPtr<nsIDOMSVGElement> svgContent(do_QueryInterface(currElement));
    1044               0 :   if (!svgContent)
    1045               0 :     return false;
    1046                 : 
    1047               0 :   nsCOMPtr<nsIDOMNode> parent;
    1048               0 :   currElement->GetParentNode(getter_AddRefs(parent));
    1049               0 :   if (!parent)
    1050               0 :     return false;
    1051                 : 
    1052                 :   PRUint16 nodeType;
    1053               0 :   nsresult rv = parent->GetNodeType(&nodeType);
    1054                 : 
    1055               0 :   return NS_SUCCEEDED(rv) && nodeType != nsIDOMNode::DOCUMENT_NODE;
    1056                 : }
    1057                 : 
    1058                 : /* void getNodeText (in nsIDOMNode aNode, out wstring aText); */
    1059                 : NS_IMETHODIMP
    1060               0 : DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
    1061                 :                                         bool *_retval)
    1062                 : {
    1063               0 :   NS_ENSURE_ARG_POINTER(aNode);
    1064               0 :   NS_ENSURE_ARG_POINTER(aText);
    1065                 :     
    1066               0 :   nsString outText;
    1067                 : 
    1068               0 :   bool lookingForSVGTitle = true;
    1069               0 :   bool found = false;
    1070               0 :   nsCOMPtr<nsIDOMNode> current ( aNode );
    1071                 : 
    1072                 :   // If the element implement the constraint validation API and has no title,
    1073                 :   // show the validation message, if any.
    1074               0 :   nsCOMPtr<nsIConstraintValidation> cvElement = do_QueryInterface(current);
    1075               0 :   if (cvElement) {
    1076               0 :     nsCOMPtr<nsIContent> content = do_QueryInterface(cvElement);
    1077               0 :     nsCOMPtr<nsIAtom> titleAtom = do_GetAtom("title");
    1078                 : 
    1079               0 :     nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(content);
    1080               0 :     bool formHasNoValidate = false;
    1081               0 :     mozilla::dom::Element* form = formControl->GetFormElement();
    1082               0 :     if (form) {
    1083               0 :       nsCOMPtr<nsIAtom> noValidateAtom = do_GetAtom("novalidate");
    1084               0 :       formHasNoValidate = form->HasAttr(kNameSpaceID_None, noValidateAtom);
    1085                 :     }
    1086                 : 
    1087               0 :     if (!content->HasAttr(kNameSpaceID_None, titleAtom) &&
    1088               0 :         !formHasNoValidate) {
    1089               0 :       cvElement->GetValidationMessage(outText);
    1090               0 :       found = !outText.IsEmpty();
    1091                 :     }
    1092                 :   }
    1093                 : 
    1094               0 :   while ( !found && current ) {
    1095               0 :     nsCOMPtr<nsIDOMElement> currElement ( do_QueryInterface(current) );
    1096               0 :     if ( currElement ) {
    1097               0 :       nsCOMPtr<nsIContent> content(do_QueryInterface(currElement));
    1098               0 :       if (content) {
    1099               0 :         nsIAtom *tagAtom = content->Tag();
    1100               0 :         if (tagAtom != mTag_dialog &&
    1101               0 :             tagAtom != mTag_dialogheader &&
    1102               0 :             tagAtom != mTag_window) {
    1103                 :           // first try the normal title attribute...
    1104               0 :           currElement->GetAttribute(NS_LITERAL_STRING("title"), outText);
    1105               0 :           if ( outText.Length() )
    1106               0 :             found = true;
    1107                 :           else {
    1108                 :             // ...ok, that didn't work, try it in the XLink namespace
    1109               0 :             NS_NAMED_LITERAL_STRING(xlinkNS, "http://www.w3.org/1999/xlink");
    1110               0 :             nsCOMPtr<mozilla::dom::Link> linkContent(do_QueryInterface(currElement));
    1111               0 :             if (linkContent) {
    1112               0 :               nsCOMPtr<nsIURI> uri(linkContent->GetURIExternal());
    1113               0 :               if (uri) {
    1114               0 :                 currElement->GetAttributeNS(NS_LITERAL_STRING("http://www.w3.org/1999/xlink"), NS_LITERAL_STRING("title"), outText);
    1115               0 :                 if ( outText.Length() )
    1116               0 :                   found = true;
    1117                 :               }
    1118                 :             }
    1119                 :             else {
    1120               0 :               if (lookingForSVGTitle) {
    1121               0 :                 lookingForSVGTitle = UseSVGTitle(currElement);
    1122                 :               }
    1123               0 :               if (lookingForSVGTitle) {
    1124               0 :                 nsCOMPtr<nsIDOMNodeList>childNodes;
    1125               0 :                 aNode->GetChildNodes(getter_AddRefs(childNodes));
    1126                 :                 PRUint32 childNodeCount;
    1127               0 :                 childNodes->GetLength(&childNodeCount);
    1128               0 :                 for (PRUint32 i = 0; i < childNodeCount; i++) {
    1129               0 :                   nsCOMPtr<nsIDOMNode>childNode;
    1130               0 :                   childNodes->Item(i, getter_AddRefs(childNode));
    1131               0 :                   nsCOMPtr<nsIDOMSVGTitleElement> titleElement(do_QueryInterface(childNode));
    1132               0 :                   if (titleElement) {
    1133               0 :                     titleElement->GetTextContent(outText);
    1134               0 :                     if ( outText.Length() )
    1135               0 :                       found = true;
    1136                 :                     break;
    1137                 :                   }
    1138                 :                 }
    1139                 :               }
    1140                 :             }
    1141                 :           }
    1142                 :         }
    1143                 :       }
    1144                 :     }
    1145                 :     
    1146                 :     // not found here, walk up to the parent and keep trying
    1147               0 :     if ( !found ) {
    1148               0 :       nsCOMPtr<nsIDOMNode> temp ( current );
    1149               0 :       temp->GetParentNode(getter_AddRefs(current));
    1150                 :     }
    1151                 :   } // while not found
    1152                 : 
    1153               0 :   *_retval = found;
    1154               0 :   *aText = (found) ? ToNewUnicode(outText) : nsnull;
    1155                 : 
    1156               0 :   return NS_OK;
    1157                 : }
    1158                 : 
    1159                 : ///////////////////////////////////////////////////////////////////////////////
    1160                 : 
    1161               0 : NS_IMPL_ISUPPORTS1(ChromeTooltipListener, nsIDOMEventListener)
    1162                 : 
    1163                 : //
    1164                 : // ChromeTooltipListener ctor
    1165                 : //
    1166                 : 
    1167               0 : ChromeTooltipListener::ChromeTooltipListener(nsWebBrowser* inBrowser,
    1168                 :                                              nsIWebBrowserChrome* inChrome) 
    1169                 :   : mWebBrowser(inBrowser), mWebBrowserChrome(inChrome),
    1170                 :      mTooltipListenerInstalled(false),
    1171                 :      mMouseClientX(0), mMouseClientY(0),
    1172               0 :      mShowingTooltip(false)
    1173                 : {
    1174               0 :   mTooltipTextProvider = do_GetService(NS_TOOLTIPTEXTPROVIDER_CONTRACTID);
    1175               0 :   if (!mTooltipTextProvider) {
    1176               0 :     nsISupports *pProvider = (nsISupports *) new DefaultTooltipTextProvider;
    1177               0 :     mTooltipTextProvider = do_QueryInterface(pProvider);
    1178                 :   }
    1179               0 : } // ctor
    1180                 : 
    1181                 : 
    1182                 : //
    1183                 : // ChromeTooltipListener dtor
    1184                 : //
    1185               0 : ChromeTooltipListener::~ChromeTooltipListener()
    1186                 : {
    1187                 : 
    1188               0 : } // dtor
    1189                 : 
    1190                 : 
    1191                 : //
    1192                 : // AddChromeListeners
    1193                 : //
    1194                 : // Hook up things to the chrome like context menus and tooltips, if the chrome
    1195                 : // has implemented the right interfaces.
    1196                 : //
    1197                 : NS_IMETHODIMP
    1198               0 : ChromeTooltipListener::AddChromeListeners()
    1199                 : {  
    1200               0 :   if (!mEventTarget)
    1201               0 :     GetDOMEventTarget(mWebBrowser, getter_AddRefs(mEventTarget));
    1202                 :   
    1203                 :   // Register the appropriate events for tooltips, but only if
    1204                 :   // the embedding chrome cares.
    1205               0 :   nsresult rv = NS_OK;
    1206               0 :   nsCOMPtr<nsITooltipListener> tooltipListener ( do_QueryInterface(mWebBrowserChrome) );
    1207               0 :   if ( tooltipListener && !mTooltipListenerInstalled ) {
    1208               0 :     rv = AddTooltipListener();
    1209               0 :     if ( NS_FAILED(rv) )
    1210               0 :       return rv;
    1211                 :   }
    1212                 :   
    1213               0 :   return rv;
    1214                 :   
    1215                 : } // AddChromeListeners
    1216                 : 
    1217                 : 
    1218                 : //
    1219                 : // AddTooltipListener
    1220                 : //
    1221                 : // Subscribe to the events that will allow us to track tooltips. We need "mouse" for mouseExit,
    1222                 : // "mouse motion" for mouseMove, and "key" for keyDown. As we add the listeners, keep track
    1223                 : // of how many succeed so we can clean up correctly in Release().
    1224                 : //
    1225                 : NS_IMETHODIMP
    1226               0 : ChromeTooltipListener::AddTooltipListener()
    1227                 : {
    1228               0 :   if (mEventTarget) {
    1229               0 :     nsresult rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("keydown"),
    1230               0 :                                                  this, false, false);
    1231               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1232               0 :     rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), this,
    1233               0 :                                         false, false);
    1234               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1235               0 :     rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), this,
    1236               0 :                                         false, false);
    1237               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1238               0 :     rv = mEventTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
    1239               0 :                                         false, false);
    1240               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1241                 : 
    1242               0 :     mTooltipListenerInstalled = true;
    1243                 :   }
    1244                 : 
    1245               0 :   return NS_OK;
    1246                 : }
    1247                 : 
    1248                 : 
    1249                 : //
    1250                 : // RemoveChromeListeners
    1251                 : //
    1252                 : // Unsubscribe from the various things we've hooked up to the window root.
    1253                 : //
    1254                 : NS_IMETHODIMP
    1255               0 : ChromeTooltipListener::RemoveChromeListeners ( )
    1256                 : {
    1257               0 :   HideTooltip();
    1258                 : 
    1259               0 :   if ( mTooltipListenerInstalled )
    1260               0 :     RemoveTooltipListener();
    1261                 :   
    1262               0 :   mEventTarget = nsnull;
    1263                 :   
    1264                 :   // it really doesn't matter if these fail...
    1265               0 :   return NS_OK;
    1266                 :   
    1267                 : } // RemoveChromeTooltipListeners
    1268                 : 
    1269                 : 
    1270                 : 
    1271                 : //
    1272                 : // RemoveTooltipListener
    1273                 : //
    1274                 : // Unsubscribe from all the various tooltip events that we were listening to
    1275                 : //
    1276                 : NS_IMETHODIMP 
    1277               0 : ChromeTooltipListener::RemoveTooltipListener()
    1278                 : {
    1279               0 :   if (mEventTarget) {
    1280                 :     nsresult rv =
    1281               0 :       mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), this,
    1282               0 :                                         false);
    1283               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1284               0 :     rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"),
    1285               0 :                                            this, false);
    1286               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1287               0 :     rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this,
    1288               0 :                                            false);
    1289               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1290               0 :     rv = mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
    1291               0 :                                            this, false);
    1292               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1293                 : 
    1294               0 :     mTooltipListenerInstalled = false;
    1295                 :   }
    1296                 : 
    1297               0 :   return NS_OK;
    1298                 : }
    1299                 : 
    1300                 : NS_IMETHODIMP
    1301               0 : ChromeTooltipListener::HandleEvent(nsIDOMEvent* aEvent)
    1302                 : {
    1303               0 :   nsAutoString eventType;
    1304               0 :   aEvent->GetType(eventType);
    1305                 : 
    1306               0 :   if (eventType.EqualsLiteral("keydown") ||
    1307               0 :       eventType.EqualsLiteral("mousedown") ||
    1308               0 :       eventType.EqualsLiteral("mouseout"))
    1309               0 :     return HideTooltip();
    1310               0 :   if (eventType.EqualsLiteral("mousemove"))
    1311               0 :     return MouseMove(aEvent);
    1312                 : 
    1313               0 :   NS_ERROR("Unexpected event type");
    1314               0 :   return NS_OK;
    1315                 : }
    1316                 : 
    1317                 : //
    1318                 : // MouseMove
    1319                 : //
    1320                 : // If we're a tooltip, fire off a timer to see if a tooltip should be shown. If the
    1321                 : // timer fires, we cache the node in |mPossibleTooltipNode|.
    1322                 : //
    1323                 : nsresult
    1324               0 : ChromeTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
    1325                 : {
    1326               0 :   nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
    1327               0 :   if (!mouseEvent)
    1328               0 :     return NS_OK;
    1329                 : 
    1330                 :   // stash the coordinates of the event so that we can still get back to it from within the 
    1331                 :   // timer callback. On win32, we'll get a MouseMove event even when a popup goes away --
    1332                 :   // even when the mouse doesn't change position! To get around this, we make sure the
    1333                 :   // mouse has really moved before proceeding.
    1334                 :   PRInt32 newMouseX, newMouseY;
    1335               0 :   mouseEvent->GetClientX(&newMouseX);
    1336               0 :   mouseEvent->GetClientY(&newMouseY);
    1337               0 :   if ( mMouseClientX == newMouseX && mMouseClientY == newMouseY )
    1338               0 :     return NS_OK;
    1339               0 :   mMouseClientX = newMouseX; mMouseClientY = newMouseY;
    1340               0 :   mouseEvent->GetScreenX(&mMouseScreenX);
    1341               0 :   mouseEvent->GetScreenY(&mMouseScreenY);
    1342                 : 
    1343                 :   // We want to close the tip if it is being displayed and the mouse moves. Recall 
    1344                 :   // that |mShowingTooltip| is set when the popup is showing. Furthermore, as the mouse
    1345                 :   // moves, we want to make sure we reset the timer to show it, so that the delay
    1346                 :   // is from when the mouse stops moving, not when it enters the element.
    1347               0 :   if ( mShowingTooltip )
    1348               0 :     return HideTooltip();
    1349               0 :   if ( mTooltipTimer )
    1350               0 :     mTooltipTimer->Cancel();
    1351                 : 
    1352               0 :   mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
    1353               0 :   if ( mTooltipTimer ) {
    1354               0 :     nsCOMPtr<nsIDOMEventTarget> eventTarget;
    1355               0 :     aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
    1356               0 :     if ( eventTarget )
    1357               0 :       mPossibleTooltipNode = do_QueryInterface(eventTarget);
    1358               0 :     if ( mPossibleTooltipNode ) {
    1359                 :       nsresult rv =
    1360               0 :         mTooltipTimer->InitWithFuncCallback(sTooltipCallback, this,
    1361               0 :           LookAndFeel::GetInt(LookAndFeel::eIntID_TooltipDelay, 500),
    1362               0 :           nsITimer::TYPE_ONE_SHOT);
    1363               0 :       if (NS_FAILED(rv))
    1364               0 :         mPossibleTooltipNode = nsnull;
    1365                 :     }
    1366                 :   }
    1367                 :   else
    1368               0 :     NS_WARNING ( "Could not create a timer for tooltip tracking" );
    1369                 :     
    1370               0 :   return NS_OK;
    1371                 :   
    1372                 : } // MouseMove
    1373                 : 
    1374                 : 
    1375                 : //
    1376                 : // ShowTooltip
    1377                 : //
    1378                 : // Tell the registered chrome that they should show the tooltip
    1379                 : //
    1380                 : NS_IMETHODIMP
    1381               0 : ChromeTooltipListener::ShowTooltip(PRInt32 inXCoords, PRInt32 inYCoords,
    1382                 :                                    const nsAString & inTipText)
    1383                 : {
    1384               0 :   nsresult rv = NS_OK;
    1385                 :   
    1386                 :   // do the work to call the client
    1387               0 :   nsCOMPtr<nsITooltipListener> tooltipListener ( do_QueryInterface(mWebBrowserChrome) );
    1388               0 :   if ( tooltipListener ) {
    1389               0 :     rv = tooltipListener->OnShowTooltip ( inXCoords, inYCoords, PromiseFlatString(inTipText).get() ); 
    1390               0 :     if ( NS_SUCCEEDED(rv) )
    1391               0 :       mShowingTooltip = true;
    1392                 :   }
    1393                 : 
    1394               0 :   return rv;
    1395                 :   
    1396                 : } // ShowTooltip
    1397                 : 
    1398                 : 
    1399                 : //
    1400                 : // HideTooltip
    1401                 : //
    1402                 : // Tell the registered chrome that they should rollup the tooltip
    1403                 : // NOTE: This routine is safe to call even if the popup is already closed.
    1404                 : //
    1405                 : NS_IMETHODIMP
    1406               0 : ChromeTooltipListener::HideTooltip()
    1407                 : {
    1408               0 :   nsresult rv = NS_OK;
    1409                 :   
    1410                 :   // shut down the relevant timers
    1411               0 :   if ( mTooltipTimer ) {
    1412               0 :     mTooltipTimer->Cancel();
    1413               0 :     mTooltipTimer = nsnull;
    1414                 :     // release tooltip target
    1415               0 :     mPossibleTooltipNode = nsnull;
    1416                 :   }
    1417               0 :   if ( mAutoHideTimer ) {
    1418               0 :     mAutoHideTimer->Cancel();
    1419               0 :     mAutoHideTimer = nsnull;
    1420                 :   }
    1421                 : 
    1422                 :   // if we're showing the tip, tell the chrome to hide it
    1423               0 :   if ( mShowingTooltip ) {
    1424               0 :     nsCOMPtr<nsITooltipListener> tooltipListener ( do_QueryInterface(mWebBrowserChrome) );
    1425               0 :     if ( tooltipListener ) {
    1426               0 :       rv = tooltipListener->OnHideTooltip ( );
    1427               0 :       if ( NS_SUCCEEDED(rv) )
    1428               0 :         mShowingTooltip = false;
    1429                 :     }
    1430                 :   }
    1431                 : 
    1432               0 :   return rv;
    1433                 :   
    1434                 : } // HideTooltip
    1435                 : 
    1436                 : 
    1437                 : //
    1438                 : // sTooltipCallback
    1439                 : //
    1440                 : // A timer callback, fired when the mouse has hovered inside of a frame for the 
    1441                 : // appropriate amount of time. Getting to this point means that we should show the
    1442                 : // tooltip, but only after we determine there is an appropriate TITLE element.
    1443                 : //
    1444                 : // This relies on certain things being cached into the |aChromeTooltipListener| object passed to
    1445                 : // us by the timer:
    1446                 : //   -- the x/y coordinates of the mouse      (mMouseClientY, mMouseClientX)
    1447                 : //   -- the dom node the user hovered over    (mPossibleTooltipNode)
    1448                 : //
    1449                 : void
    1450               0 : ChromeTooltipListener::sTooltipCallback(nsITimer *aTimer,
    1451                 :                                         void *aChromeTooltipListener)
    1452                 : {
    1453                 :   ChromeTooltipListener* self = static_cast<ChromeTooltipListener*>
    1454               0 :                                            (aChromeTooltipListener);
    1455               0 :   if ( self && self->mPossibleTooltipNode ){
    1456                 :     // The actual coordinates we want to put the tooltip at are relative to the
    1457                 :     // toplevel docshell of our mWebBrowser.  We know what the screen
    1458                 :     // coordinates of the mouse event were, which means we just need the screen
    1459                 :     // coordinates of the docshell.  Unfortunately, there is no good way to
    1460                 :     // find those short of groveling for the presentation in that docshell and
    1461                 :     // finding the screen coords of its toplevel widget...
    1462                 :     nsCOMPtr<nsIDocShell> docShell =
    1463               0 :       do_GetInterface(static_cast<nsIWebBrowser*>(self->mWebBrowser));
    1464               0 :     nsCOMPtr<nsIPresShell> shell;
    1465               0 :     if (docShell) {
    1466               0 :       docShell->GetPresShell(getter_AddRefs(shell));
    1467                 :     }
    1468                 : 
    1469               0 :     nsIWidget* widget = nsnull;
    1470               0 :     if (shell) {
    1471               0 :       nsIViewManager* vm = shell->GetViewManager();
    1472               0 :       if (vm) {
    1473               0 :         nsIView* view = vm->GetRootView();
    1474               0 :         if (view) {
    1475               0 :           nsPoint offset;
    1476               0 :           widget = view->GetNearestWidget(&offset);
    1477                 :         }
    1478                 :       }
    1479                 :     }
    1480                 : 
    1481               0 :     if (!widget) {
    1482                 :       // release tooltip target if there is one, NO MATTER WHAT
    1483               0 :       self->mPossibleTooltipNode = nsnull;
    1484                 :       return;
    1485                 :     }
    1486                 : 
    1487                 :     // if there is text associated with the node, show the tip and fire
    1488                 :     // off a timer to auto-hide it.
    1489                 : 
    1490               0 :     nsXPIDLString tooltipText;
    1491               0 :     if (self->mTooltipTextProvider) {
    1492               0 :       bool textFound = false;
    1493                 : 
    1494               0 :       self->mTooltipTextProvider->GetNodeText(
    1495               0 :           self->mPossibleTooltipNode, getter_Copies(tooltipText), &textFound);
    1496                 :       
    1497               0 :       if (textFound) {
    1498               0 :         nsString tipText(tooltipText);
    1499               0 :         self->CreateAutoHideTimer();
    1500               0 :         nsIntPoint screenDot = widget->WidgetToScreenOffset();
    1501                 :         self->ShowTooltip (self->mMouseScreenX - screenDot.x,
    1502                 :                            self->mMouseScreenY - screenDot.y,
    1503               0 :                            tipText);
    1504                 :       }
    1505                 :     }
    1506                 :     
    1507                 :     // release tooltip target if there is one, NO MATTER WHAT
    1508               0 :     self->mPossibleTooltipNode = nsnull;
    1509                 :   } // if "self" data valid
    1510                 :   
    1511                 : } // sTooltipCallback
    1512                 : 
    1513                 : 
    1514                 : //
    1515                 : // CreateAutoHideTimer
    1516                 : //
    1517                 : // Create a new timer to see if we should auto-hide. It's ok if this fails.
    1518                 : //
    1519                 : void
    1520               0 : ChromeTooltipListener::CreateAutoHideTimer()
    1521                 : {
    1522                 :   // just to be anal (er, safe)
    1523               0 :   if ( mAutoHideTimer ) {
    1524               0 :     mAutoHideTimer->Cancel();
    1525               0 :     mAutoHideTimer = nsnull;
    1526                 :   }
    1527                 :   
    1528               0 :   mAutoHideTimer = do_CreateInstance("@mozilla.org/timer;1");
    1529               0 :   if ( mAutoHideTimer )
    1530               0 :     mAutoHideTimer->InitWithFuncCallback(sAutoHideCallback, this, kTooltipAutoHideTime, 
    1531               0 :                                          nsITimer::TYPE_ONE_SHOT);
    1532                 : 
    1533               0 : } // CreateAutoHideTimer
    1534                 : 
    1535                 : 
    1536                 : //
    1537                 : // sAutoHideCallback
    1538                 : //
    1539                 : // This fires after a tooltip has been open for a certain length of time. Just tell
    1540                 : // the listener to close the popup. We don't have to worry, because HideTooltip() can
    1541                 : // be called multiple times, even if the tip has already been closed.
    1542                 : //
    1543                 : void
    1544               0 : ChromeTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener)
    1545                 : {
    1546               0 :   ChromeTooltipListener* self = static_cast<ChromeTooltipListener*>(aListener);
    1547               0 :   if ( self )
    1548               0 :     self->HideTooltip();
    1549                 : 
    1550                 :   // NOTE: |aTimer| and |self->mAutoHideTimer| are invalid after calling ClosePopup();
    1551                 :   
    1552               0 : } // sAutoHideCallback
    1553                 : 
    1554                 : 
    1555               0 : NS_IMPL_ISUPPORTS1(ChromeContextMenuListener, nsIDOMEventListener)
    1556                 : 
    1557                 : 
    1558                 : //
    1559                 : // ChromeTooltipListener ctor
    1560                 : //
    1561               0 : ChromeContextMenuListener::ChromeContextMenuListener(nsWebBrowser* inBrowser, nsIWebBrowserChrome* inChrome ) 
    1562                 :   : mContextMenuListenerInstalled(false),
    1563                 :     mWebBrowser(inBrowser),
    1564               0 :     mWebBrowserChrome(inChrome)
    1565                 : {
    1566               0 : } // ctor
    1567                 : 
    1568                 : 
    1569                 : //
    1570                 : // ChromeTooltipListener dtor
    1571                 : //
    1572               0 : ChromeContextMenuListener::~ChromeContextMenuListener()
    1573                 : {
    1574               0 : } // dtor
    1575                 : 
    1576                 : 
    1577                 : //
    1578                 : // AddContextMenuListener
    1579                 : //
    1580                 : // Subscribe to the events that will allow us to track context menus. Bascially, this
    1581                 : // is just the context-menu DOM event.
    1582                 : //
    1583                 : NS_IMETHODIMP
    1584               0 : ChromeContextMenuListener::AddContextMenuListener()
    1585                 : {
    1586               0 :   if (mEventTarget) {
    1587                 :     nsresult rv =
    1588               0 :       mEventTarget->AddEventListener(NS_LITERAL_STRING("contextmenu"), this,
    1589               0 :                                      false, false);
    1590               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1591                 : 
    1592               0 :     mContextMenuListenerInstalled = true;
    1593                 :   }
    1594                 : 
    1595               0 :   return NS_OK;
    1596                 : }
    1597                 : 
    1598                 : 
    1599                 : //
    1600                 : // RemoveContextMenuListener
    1601                 : //
    1602                 : // Unsubscribe from all the various context menu events that we were listening to. 
    1603                 : //
    1604                 : NS_IMETHODIMP 
    1605               0 : ChromeContextMenuListener::RemoveContextMenuListener()
    1606                 : {
    1607               0 :   if (mEventTarget) {
    1608                 :     nsresult rv =
    1609               0 :       mEventTarget->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this,
    1610               0 :                                         false);
    1611               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1612                 : 
    1613               0 :     mContextMenuListenerInstalled = false;
    1614                 :   }
    1615                 : 
    1616               0 :   return NS_OK;
    1617                 : }
    1618                 : 
    1619                 : 
    1620                 : //
    1621                 : // AddChromeListeners
    1622                 : //
    1623                 : // Hook up things to the chrome like context menus and tooltips, if the chrome
    1624                 : // has implemented the right interfaces.
    1625                 : //
    1626                 : NS_IMETHODIMP
    1627               0 : ChromeContextMenuListener::AddChromeListeners()
    1628                 : {  
    1629               0 :   if (!mEventTarget)
    1630               0 :     GetDOMEventTarget(mWebBrowser, getter_AddRefs(mEventTarget));
    1631                 :   
    1632                 :   // Register the appropriate events for context menus, but only if
    1633                 :   // the embedding chrome cares.
    1634               0 :   nsresult rv = NS_OK;
    1635                 : 
    1636               0 :   nsCOMPtr<nsIContextMenuListener2> contextListener2 ( do_QueryInterface(mWebBrowserChrome) );
    1637               0 :   nsCOMPtr<nsIContextMenuListener> contextListener ( do_QueryInterface(mWebBrowserChrome) );
    1638               0 :   if ( (contextListener || contextListener2) && !mContextMenuListenerInstalled )
    1639               0 :     rv = AddContextMenuListener();
    1640                 : 
    1641               0 :   return rv;
    1642                 :   
    1643                 : } // AddChromeListeners
    1644                 : 
    1645                 : 
    1646                 : //
    1647                 : // RemoveChromeListeners
    1648                 : //
    1649                 : // Unsubscribe from the various things we've hooked up to the window root.
    1650                 : //
    1651                 : NS_IMETHODIMP
    1652               0 : ChromeContextMenuListener::RemoveChromeListeners()
    1653                 : {
    1654               0 :   if ( mContextMenuListenerInstalled )
    1655               0 :     RemoveContextMenuListener();
    1656                 :   
    1657               0 :   mEventTarget = nsnull;
    1658                 :   
    1659                 :   // it really doesn't matter if these fail...
    1660               0 :   return NS_OK;
    1661                 :   
    1662                 : } // RemoveChromeTooltipListeners
    1663                 : 
    1664                 : 
    1665                 : 
    1666                 : //
    1667                 : // ContextMenu
    1668                 : //
    1669                 : // We're on call to show the context menu. Dig around in the DOM to
    1670                 : // find the type of object we're dealing with and notify the front
    1671                 : // end chrome.
    1672                 : //
    1673                 : NS_IMETHODIMP
    1674               0 : ChromeContextMenuListener::HandleEvent(nsIDOMEvent* aMouseEvent)
    1675                 : {
    1676               0 :   nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
    1677               0 :   NS_ENSURE_TRUE(mouseEvent, NS_ERROR_UNEXPECTED);
    1678                 : 
    1679               0 :   nsCOMPtr<nsIDOMNSEvent> domNSEvent = do_QueryInterface(aMouseEvent);
    1680                 : 
    1681               0 :   if (domNSEvent) {
    1682               0 :     bool isDefaultPrevented = false;
    1683               0 :     domNSEvent->GetPreventDefault(&isDefaultPrevented);
    1684                 : 
    1685               0 :     if (isDefaultPrevented) {
    1686               0 :       return NS_OK;
    1687                 :     }
    1688                 :   }
    1689                 : 
    1690               0 :   nsCOMPtr<nsIDOMEventTarget> targetNode;
    1691               0 :   nsresult res = aMouseEvent->GetTarget(getter_AddRefs(targetNode));
    1692               0 :   if (NS_FAILED(res))
    1693               0 :     return res;
    1694               0 :   if (!targetNode)
    1695               0 :     return NS_ERROR_NULL_POINTER;
    1696                 : 
    1697               0 :   nsCOMPtr<nsIDOMNode> targetDOMnode;
    1698               0 :   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(targetNode);
    1699               0 :   if (!node)
    1700               0 :     return NS_OK;
    1701                 : 
    1702                 :   // Stop the context menu event going to other windows (bug 78396)
    1703               0 :   aMouseEvent->PreventDefault();
    1704                 :   
    1705                 :   // If the listener is a nsIContextMenuListener2, create the info object
    1706               0 :   nsCOMPtr<nsIContextMenuListener2> menuListener2(do_QueryInterface(mWebBrowserChrome));
    1707               0 :   nsContextMenuInfo *menuInfoImpl = nsnull;
    1708               0 :   nsCOMPtr<nsIContextMenuInfo> menuInfo;
    1709               0 :   if (menuListener2) {
    1710               0 :     menuInfoImpl = new nsContextMenuInfo;
    1711               0 :     if (!menuInfoImpl)
    1712               0 :       return NS_ERROR_OUT_OF_MEMORY;
    1713               0 :     menuInfo = menuInfoImpl; 
    1714                 :   }
    1715                 : 
    1716               0 :   PRUint32 flags = nsIContextMenuListener::CONTEXT_NONE;
    1717               0 :   PRUint32 flags2 = nsIContextMenuListener2::CONTEXT_NONE;
    1718                 : 
    1719                 :   // XXX test for selected text
    1720                 : 
    1721                 :   PRUint16 nodeType;
    1722               0 :   res = node->GetNodeType(&nodeType);
    1723               0 :   NS_ENSURE_SUCCESS(res, res);
    1724                 : 
    1725                 :   // First, checks for nodes that never have children.
    1726               0 :   if (nodeType == nsIDOMNode::ELEMENT_NODE) {
    1727               0 :     nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(node));
    1728               0 :     if (content) {
    1729               0 :       nsCOMPtr<nsIURI> imgUri;
    1730               0 :       content->GetCurrentURI(getter_AddRefs(imgUri));
    1731               0 :       if (imgUri) {
    1732               0 :         flags |= nsIContextMenuListener::CONTEXT_IMAGE;
    1733               0 :         flags2 |= nsIContextMenuListener2::CONTEXT_IMAGE;
    1734               0 :         targetDOMnode = node;
    1735                 :       }
    1736                 :     }
    1737                 : 
    1738               0 :     nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
    1739               0 :     if (formControl) {
    1740               0 :       if (formControl->GetType() == NS_FORM_TEXTAREA) {
    1741               0 :         flags |= nsIContextMenuListener::CONTEXT_TEXT;
    1742               0 :         flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
    1743               0 :         targetDOMnode = node;
    1744                 :       } else {
    1745               0 :         nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(formControl));
    1746               0 :         if (inputElement) {
    1747               0 :           flags |= nsIContextMenuListener::CONTEXT_INPUT;
    1748               0 :           flags2 |= nsIContextMenuListener2::CONTEXT_INPUT;
    1749                 : 
    1750               0 :           if (menuListener2) {
    1751               0 :             if (formControl->IsSingleLineTextControl(false)) {
    1752               0 :               flags2 |= nsIContextMenuListener2::CONTEXT_TEXT;
    1753                 :             }
    1754                 :           }
    1755                 : 
    1756               0 :           targetDOMnode = node;
    1757                 :         }
    1758                 :       }
    1759                 :     }
    1760                 : 
    1761                 :     // always consume events for plugins and Java who may throw their
    1762                 :     // own context menus but not for image objects.  Document objects
    1763                 :     // will never be targets or ancestors of targets, so that's OK.
    1764               0 :     nsCOMPtr<nsIDOMHTMLObjectElement> objectElement;
    1765               0 :     if (!(flags & nsIContextMenuListener::CONTEXT_IMAGE))
    1766               0 :       objectElement = do_QueryInterface(node);
    1767               0 :     nsCOMPtr<nsIDOMHTMLEmbedElement> embedElement(do_QueryInterface(node));
    1768               0 :     nsCOMPtr<nsIDOMHTMLAppletElement> appletElement(do_QueryInterface(node));
    1769                 : 
    1770               0 :     if (objectElement || embedElement || appletElement)
    1771               0 :       return NS_OK;
    1772                 :   }
    1773                 : 
    1774                 :   // Bubble out, looking for items of interest
    1775               0 :   do {
    1776                 :     PRUint16 nodeType;
    1777               0 :     res = node->GetNodeType(&nodeType);
    1778               0 :     NS_ENSURE_SUCCESS(res, res);
    1779                 : 
    1780               0 :     if (nodeType == nsIDOMNode::ELEMENT_NODE) {
    1781                 : 
    1782                 :       // Test if the element has an associated link
    1783               0 :       nsCOMPtr<nsIDOMElement> element(do_QueryInterface(node));
    1784                 : 
    1785               0 :       bool hasAttr = false;
    1786               0 :       res = element->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
    1787                 : 
    1788               0 :       if (NS_SUCCEEDED(res) && hasAttr)
    1789                 :       {
    1790               0 :         flags |= nsIContextMenuListener::CONTEXT_LINK;
    1791               0 :         flags2 |= nsIContextMenuListener2::CONTEXT_LINK;
    1792               0 :         if (!targetDOMnode)
    1793               0 :           targetDOMnode = node;
    1794               0 :         if (menuInfoImpl)
    1795               0 :           menuInfoImpl->SetAssociatedLink(node);
    1796                 :         break; // exit do-while
    1797                 :       }
    1798                 :     }
    1799                 : 
    1800                 :     // walk-up-the-tree
    1801               0 :     nsCOMPtr<nsIDOMNode> parentNode;
    1802               0 :     node->GetParentNode(getter_AddRefs(parentNode));
    1803               0 :     node = parentNode;
    1804               0 :   } while (node);
    1805                 : 
    1806               0 :   if (!flags && !flags2) {
    1807                 :     // We found nothing of interest so far, check if we
    1808                 :     // have at least an html document.
    1809               0 :     nsCOMPtr<nsIDOMDocument> document;
    1810               0 :     node = do_QueryInterface(targetNode);
    1811               0 :     node->GetOwnerDocument(getter_AddRefs(document));
    1812               0 :     nsCOMPtr<nsIDOMHTMLDocument> htmlDocument(do_QueryInterface(document));
    1813               0 :     if (htmlDocument) {
    1814               0 :       flags |= nsIContextMenuListener::CONTEXT_DOCUMENT;
    1815               0 :       flags2 |= nsIContextMenuListener2::CONTEXT_DOCUMENT;
    1816               0 :       targetDOMnode = node;
    1817               0 :       if (!(flags & nsIContextMenuListener::CONTEXT_IMAGE)) {
    1818                 :         // check if this is a background image that the user was trying to click on
    1819                 :         // and if the listener is ready for that (only nsIContextMenuListener2 and up)
    1820               0 :         if (menuInfoImpl && menuInfoImpl->HasBackgroundImage(targetDOMnode)) {
    1821               0 :           flags2 |= nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE;
    1822                 :           // For the embedder to get the correct background image 
    1823                 :           // targetDOMnode must point to the original node. 
    1824               0 :           targetDOMnode = do_QueryInterface(targetNode);
    1825                 :         }
    1826                 :       }
    1827                 :     }
    1828                 :   }
    1829                 : 
    1830                 :   // we need to cache the event target into the focus controller's popupNode
    1831                 :   // so we can get at it later from command code, etc.:
    1832                 : 
    1833                 :   // get the dom window
    1834               0 :   nsCOMPtr<nsIDOMWindow> win;
    1835               0 :   res = mWebBrowser->GetContentDOMWindow(getter_AddRefs(win));
    1836               0 :   NS_ENSURE_SUCCESS(res, res);
    1837               0 :   NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
    1838                 : 
    1839               0 :   nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(win));
    1840               0 :   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
    1841               0 :   nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
    1842               0 :   NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
    1843               0 :   if (root) {
    1844                 :     // set the window root's popup node to the event target
    1845               0 :     root->SetPopupNode(targetDOMnode);
    1846                 :   }
    1847                 : 
    1848                 :   // Tell the listener all about the event
    1849               0 :   if ( menuListener2 ) {
    1850               0 :     menuInfoImpl->SetMouseEvent(aMouseEvent);
    1851               0 :     menuInfoImpl->SetDOMNode(targetDOMnode);
    1852               0 :     menuListener2->OnShowContextMenu(flags2, menuInfo);
    1853                 :   }
    1854                 :   else {
    1855               0 :     nsCOMPtr<nsIContextMenuListener> menuListener(do_QueryInterface(mWebBrowserChrome));
    1856               0 :     if ( menuListener )
    1857               0 :       menuListener->OnShowContextMenu(flags, aMouseEvent, targetDOMnode);
    1858                 :   }
    1859                 : 
    1860               0 :   return NS_OK;
    1861                 : 
    1862                 : } // MouseDown

Generated by: LCOV version 1.7