xpfe/appshell/src/nsContentTreeOwner.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: set ts=2 sw=2 et tw=79:
     3  *
     4  * This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 // Local Includes
     9 #include "nsContentTreeOwner.h"
    10 #include "nsXULWindow.h"
    12 // Helper Classes
    13 #include "nsIServiceManager.h"
    14 #include "nsAutoPtr.h"
    16 // Interfaces needed to be included
    17 #include "nsIDOMNode.h"
    18 #include "nsIDOMElement.h"
    19 #include "nsIDOMNodeList.h"
    20 #include "nsIDOMWindow.h"
    21 #include "nsIDOMChromeWindow.h"
    22 #include "nsIBrowserDOMWindow.h"
    23 #include "nsIDOMXULElement.h"
    24 #include "nsIEmbeddingSiteWindow.h"
    25 #include "nsIPrompt.h"
    26 #include "nsIAuthPrompt.h"
    27 #include "nsIWindowMediator.h"
    28 #include "nsIXULBrowserWindow.h"
    29 #include "nsIPrincipal.h"
    30 #include "nsIURIFixup.h"
    31 #include "nsCDefaultURIFixup.h"
    32 #include "nsIWebNavigation.h"
    33 #include "nsDocShellCID.h"
    34 #include "nsIExternalURLHandlerService.h"
    35 #include "nsIMIMEInfo.h"
    36 #include "nsIWidget.h"
    37 #include "mozilla/BrowserElementParent.h"
    39 #include "nsIDOMDocument.h"
    40 #include "nsIScriptObjectPrincipal.h"
    41 #include "nsIURI.h"
    42 #include "nsIDocument.h"
    43 #if defined(XP_MACOSX)
    44 #include "nsThreadUtils.h"
    45 #endif
    47 #include "mozilla/Preferences.h"
    48 #include "mozilla/dom/Element.h"
    49 #include "mozilla/dom/ScriptSettings.h"
    51 using namespace mozilla;
    53 //*****************************************************************************
    54 //*** nsSiteWindow declaration
    55 //*****************************************************************************
    57 class nsSiteWindow : public nsIEmbeddingSiteWindow
    58 {
    59 public:
    60   nsSiteWindow(nsContentTreeOwner *aAggregator);
    61   virtual ~nsSiteWindow();
    63   NS_DECL_ISUPPORTS
    64   NS_DECL_NSIEMBEDDINGSITEWINDOW
    66 private:
    67   nsContentTreeOwner *mAggregator;
    68 };
    70 //*****************************************************************************
    71 //***    nsContentTreeOwner: Object Management
    72 //*****************************************************************************
    74 nsContentTreeOwner::nsContentTreeOwner(bool fPrimary) : mXULWindow(nullptr), 
    75    mPrimary(fPrimary), mContentTitleSetting(false)
    76 {
    77   // note if this fails, QI on nsIEmbeddingSiteWindow(2) will simply fail
    78   mSiteWindow = new nsSiteWindow(this);
    79 }
    81 nsContentTreeOwner::~nsContentTreeOwner()
    82 {
    83   delete mSiteWindow;
    84 }
    86 //*****************************************************************************
    87 // nsContentTreeOwner::nsISupports
    88 //*****************************************************************************   
    90 NS_IMPL_ADDREF(nsContentTreeOwner)
    91 NS_IMPL_RELEASE(nsContentTreeOwner)
    93 NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner)
    94    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
    95    NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
    96    NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
    97    NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
    98    NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
    99    NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome3)
   100    NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   101    NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
   102    // NOTE: This is using aggregation because there are some properties and
   103    // method on nsIBaseWindow (which we implement) and on
   104    // nsIEmbeddingSiteWindow (which we also implement) that have the same name.
   105    // And it just so happens that we want different behavior for these methods
   106    // and properties depending on the interface through which they're called
   107    // (SetFocus() is a good example here).  If it were not for that, we could
   108    // ditch the aggregation and just deal with not being able to use NS_DECL_*
   109    // macros for this stuff....
   110    NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIEmbeddingSiteWindow, mSiteWindow)
   111 NS_INTERFACE_MAP_END
   113 //*****************************************************************************
   114 // nsContentTreeOwner::nsIInterfaceRequestor
   115 //*****************************************************************************   
   117 NS_IMETHODIMP nsContentTreeOwner::GetInterface(const nsIID& aIID, void** aSink)
   118 {
   119   NS_ENSURE_ARG_POINTER(aSink);
   120   *aSink = 0;
   122   if(aIID.Equals(NS_GET_IID(nsIPrompt))) {
   123     NS_ENSURE_STATE(mXULWindow);
   124     return mXULWindow->GetInterface(aIID, aSink);
   125   }
   126   if(aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
   127     NS_ENSURE_STATE(mXULWindow);
   128     return mXULWindow->GetInterface(aIID, aSink);
   129   }
   130   if (aIID.Equals(NS_GET_IID(nsIDocShellTreeItem))) {
   131     NS_ENSURE_STATE(mXULWindow);
   132     nsCOMPtr<nsIDocShell> shell;
   133     mXULWindow->GetDocShell(getter_AddRefs(shell));
   134     if (shell)
   135       return shell->QueryInterface(aIID, aSink);
   136     return NS_ERROR_FAILURE;
   137   }
   139   if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
   140     NS_ENSURE_STATE(mXULWindow);
   141     nsCOMPtr<nsIDocShellTreeItem> shell;
   142     mXULWindow->GetPrimaryContentShell(getter_AddRefs(shell));
   143     if (shell) {
   144       nsCOMPtr<nsIInterfaceRequestor> thing(do_QueryInterface(shell));
   145       if (thing)
   146         return thing->GetInterface(aIID, aSink);
   147     }
   148     return NS_ERROR_FAILURE;
   149   }
   151   if (aIID.Equals(NS_GET_IID(nsIXULWindow))) {
   152     NS_ENSURE_STATE(mXULWindow);
   153     return mXULWindow->QueryInterface(aIID, aSink);
   154   }
   156   return QueryInterface(aIID, aSink);
   157 }
   159 //*****************************************************************************
   160 // nsContentTreeOwner::nsIDocShellTreeOwner
   161 //*****************************************************************************   
   163 NS_IMETHODIMP nsContentTreeOwner::FindItemWithName(const char16_t* aName,
   164    nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor,
   165    nsIDocShellTreeItem** aFoundItem)
   166 {
   167    NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
   169    NS_ENSURE_ARG_POINTER(aFoundItem);
   171    *aFoundItem = nullptr;
   173    bool fIs_Content = false;
   175    /* Special Cases */
   176    if (!aName || !*aName)
   177       return NS_OK;
   179    nsDependentString name(aName);
   181    if (name.LowerCaseEqualsLiteral("_blank"))
   182       return NS_OK;
   183    // _main is an IE target which should be case-insensitive but isn't
   184    // see bug 217886 for details
   185    if (name.LowerCaseEqualsLiteral("_content") ||
   186        name.EqualsLiteral("_main")) {
   187      // If we're being called with an aRequestor and it's targetable, just
   188      // return it -- _main and _content from inside targetable content shells
   189      // should just be that content shell.  Note that we don't have to worry
   190      // about the case when it's not targetable because it's primary -- that
   191      // will Just Work when we call GetPrimaryContentShell.
   192      NS_ENSURE_STATE(mXULWindow);
   193      if (aRequestor) {
   194        // This better be the root item!
   195 #ifdef DEBUG
   196        nsCOMPtr<nsIDocShellTreeItem> debugRoot;
   197        aRequestor->GetSameTypeRootTreeItem(getter_AddRefs(debugRoot));
   198        NS_ASSERTION(SameCOMIdentity(debugRoot, aRequestor),
   199                     "Bogus aRequestor");
   200 #endif
   202        int32_t count = mXULWindow->mTargetableShells.Count();
   203        for (int32_t i = 0; i < count; ++i) {
   204          nsCOMPtr<nsIDocShellTreeItem> item =
   205            do_QueryReferent(mXULWindow->mTargetableShells[i]);
   206          if (SameCOMIdentity(item, aRequestor)) {
   207            NS_ADDREF(*aFoundItem = aRequestor);
   208            return NS_OK;
   209          }
   210        }
   211      }
   212      mXULWindow->GetPrimaryContentShell(aFoundItem);
   213      if(*aFoundItem)
   214        return NS_OK;
   215      // Fall through and keep looking...
   216      fIs_Content = true;
   217    }
   219    nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
   220    NS_ENSURE_TRUE(windowMediator, NS_ERROR_FAILURE);
   222    nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
   223    NS_ENSURE_SUCCESS(windowMediator->GetXULWindowEnumerator(nullptr, 
   224       getter_AddRefs(windowEnumerator)), NS_ERROR_FAILURE);
   226    bool more;
   228    windowEnumerator->HasMoreElements(&more);
   229    while(more) {
   230      nsCOMPtr<nsISupports> nextWindow = nullptr;
   231      windowEnumerator->GetNext(getter_AddRefs(nextWindow));
   232      nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
   233      NS_ENSURE_TRUE(xulWindow, NS_ERROR_FAILURE);
   235      if (fIs_Content) {
   236        xulWindow->GetPrimaryContentShell(aFoundItem);
   237      } else {
   238        // Get all the targetable windows from xulWindow and search them
   239        nsRefPtr<nsXULWindow> win;
   240        xulWindow->QueryInterface(NS_GET_IID(nsXULWindow), getter_AddRefs(win));
   241        if (win) {
   242          int32_t count = win->mTargetableShells.Count();
   243          int32_t i;
   244          for (i = 0; i < count && !*aFoundItem; ++i) {
   245            nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem =
   246              do_QueryReferent(win->mTargetableShells[i]);
   247            if (shellAsTreeItem) {
   248              // Get the root tree item of same type, since roots are the only
   249              // things that call into the treeowner to look for named items.
   250              // XXXbz ideally we could guarantee that mTargetableShells only
   251              // contains roots, but the current treeowner apis don't allow
   252              // that... yet.
   253              nsCOMPtr<nsIDocShellTreeItem> root;
   254              shellAsTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
   255              NS_ASSERTION(root, "Must have root tree item of same type");
   256              shellAsTreeItem.swap(root);
   257              if (aRequestor != shellAsTreeItem) {
   258                // Do this so we can pass in the tree owner as the
   259                // requestor so the child knows not to call back up.
   260                nsCOMPtr<nsIDocShellTreeOwner> shellOwner;
   261                shellAsTreeItem->GetTreeOwner(getter_AddRefs(shellOwner));
   262                nsCOMPtr<nsISupports> shellOwnerSupports =
   263                  do_QueryInterface(shellOwner);
   265                shellAsTreeItem->FindItemWithName(aName, shellOwnerSupports,
   266                                                  aOriginalRequestor,
   267                                                  aFoundItem);
   268              }
   269            }
   270          }
   271        }
   272      }
   274      if (*aFoundItem)
   275        return NS_OK;
   277      windowEnumerator->HasMoreElements(&more);
   278    }
   279    return NS_OK;      
   280 }
   282 NS_IMETHODIMP
   283 nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
   284                                       bool aPrimary, bool aTargetable,
   285                                       const nsAString& aID)
   286 {
   287   NS_ENSURE_STATE(mXULWindow);
   288   return mXULWindow->ContentShellAdded(aContentShell, aPrimary, aTargetable,
   289                                        aID);
   290 }
   292 NS_IMETHODIMP
   293 nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
   294 {
   295   NS_ENSURE_STATE(mXULWindow);
   296   return mXULWindow->ContentShellRemoved(aContentShell);
   297 }
   299 NS_IMETHODIMP
   300 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
   301 {
   302    NS_ENSURE_STATE(mXULWindow);
   303    return mXULWindow->GetPrimaryContentShell(aShell);
   304 }
   306 NS_IMETHODIMP
   307 nsContentTreeOwner::GetContentWindow(JSContext* aCx,
   308                                      JS::MutableHandle<JS::Value> aVal)
   309 {
   310   NS_ENSURE_STATE(mXULWindow);
   311   return NS_ERROR_NOT_IMPLEMENTED;
   312 }
   314 NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
   315    int32_t aCX, int32_t aCY)
   316 {
   317    NS_ENSURE_STATE(mXULWindow);
   318    return mXULWindow->SizeShellTo(aShellItem, aCX, aCY);
   319 }
   321 NS_IMETHODIMP
   322 nsContentTreeOwner::SetPersistence(bool aPersistPosition,
   323                                    bool aPersistSize,
   324                                    bool aPersistSizeMode)
   325 {
   326   NS_ENSURE_STATE(mXULWindow);
   327   nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
   328   if (!docShellElement)
   329     return NS_ERROR_FAILURE;
   331   nsAutoString persistString;
   332   docShellElement->GetAttribute(NS_LITERAL_STRING("persist"), persistString);
   334   bool saveString = false;
   335   int32_t index;
   337   // Set X
   338   index = persistString.Find("screenX");
   339   if (!aPersistPosition && index >= 0) {
   340     persistString.Cut(index, 7);
   341     saveString = true;
   342   } else if (aPersistPosition && index < 0) {
   343     persistString.AppendLiteral(" screenX");
   344     saveString = true;
   345   }
   346   // Set Y
   347   index = persistString.Find("screenY");
   348   if (!aPersistPosition && index >= 0) {
   349     persistString.Cut(index, 7);
   350     saveString = true;
   351   } else if (aPersistPosition && index < 0) {
   352     persistString.AppendLiteral(" screenY");
   353     saveString = true;
   354   }
   355   // Set CX
   356   index = persistString.Find("width");
   357   if (!aPersistSize && index >= 0) {
   358     persistString.Cut(index, 5);
   359     saveString = true;
   360   } else if (aPersistSize && index < 0) {
   361     persistString.AppendLiteral(" width");
   362     saveString = true;
   363   }
   364   // Set CY
   365   index = persistString.Find("height");
   366   if (!aPersistSize && index >= 0) {
   367     persistString.Cut(index, 6);
   368     saveString = true;
   369   } else if (aPersistSize && index < 0) {
   370     persistString.AppendLiteral(" height");
   371     saveString = true;
   372   }
   373   // Set SizeMode
   374   index = persistString.Find("sizemode");
   375   if (!aPersistSizeMode && (index >= 0)) {
   376     persistString.Cut(index, 8);
   377     saveString = true;
   378   } else if (aPersistSizeMode && (index < 0)) {
   379     persistString.AppendLiteral(" sizemode");
   380     saveString = true;
   381   }
   383   ErrorResult rv;
   384   if(saveString) {
   385     docShellElement->SetAttribute(NS_LITERAL_STRING("persist"), persistString, rv);
   386   }
   388   return NS_OK;
   389 }
   391 NS_IMETHODIMP
   392 nsContentTreeOwner::GetPersistence(bool* aPersistPosition,
   393                                    bool* aPersistSize,
   394                                    bool* aPersistSizeMode)
   395 {
   396   NS_ENSURE_STATE(mXULWindow);
   397   nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
   398   if (!docShellElement)
   399     return NS_ERROR_FAILURE;
   401   nsAutoString persistString;
   402   docShellElement->GetAttribute(NS_LITERAL_STRING("persist"), persistString);
   404   // data structure doesn't quite match the question, but it's close enough
   405   // for what we want (since this method is never actually called...)
   406   if (aPersistPosition)
   407     *aPersistPosition = persistString.Find("screenX") >= 0 || persistString.Find("screenY") >= 0 ? true : false;
   408   if (aPersistSize)
   409     *aPersistSize = persistString.Find("width") >= 0 || persistString.Find("height") >= 0 ? true : false;
   410   if (aPersistSizeMode)
   411     *aPersistSizeMode = persistString.Find("sizemode") >= 0 ? true : false;
   413   return NS_OK;
   414 }
   416 NS_IMETHODIMP
   417 nsContentTreeOwner::GetTargetableShellCount(uint32_t* aResult)
   418 {
   419   NS_ENSURE_STATE(mXULWindow);
   420   *aResult = mXULWindow->mTargetableShells.Count();
   421   return NS_OK;
   422 }
   424 //*****************************************************************************
   425 // nsContentTreeOwner::nsIWebBrowserChrome3
   426 //*****************************************************************************   
   428 NS_IMETHODIMP nsContentTreeOwner::OnBeforeLinkTraversal(const nsAString &originalTarget,
   429                                                         nsIURI *linkURI,
   430                                                         nsIDOMNode *linkNode,
   431                                                         bool isAppTab,
   432                                                         nsAString &_retval)
   433 {
   434   NS_ENSURE_STATE(mXULWindow);
   436   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
   437   mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
   439   if (xulBrowserWindow)
   440     return xulBrowserWindow->OnBeforeLinkTraversal(originalTarget, linkURI,
   441                                                    linkNode, isAppTab, _retval);
   443   _retval = originalTarget;
   444   return NS_OK;
   445 }
   447 //*****************************************************************************
   448 // nsContentTreeOwner::nsIWebBrowserChrome2
   449 //*****************************************************************************   
   451 NS_IMETHODIMP nsContentTreeOwner::SetStatusWithContext(uint32_t aStatusType,
   452                                                        const nsAString &aStatusText,
   453                                                        nsISupports *aStatusContext)
   454 {
   455   // We only allow the status to be set from the primary content shell
   456   if (!mPrimary && aStatusType != STATUS_LINK)
   457     return NS_OK;
   459   NS_ENSURE_STATE(mXULWindow);
   461   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
   462   mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
   464   if (xulBrowserWindow)
   465   {
   466     switch(aStatusType)
   467     {
   468     case STATUS_SCRIPT:
   469       xulBrowserWindow->SetJSStatus(aStatusText);
   470       break;
   471     case STATUS_LINK:
   472       {
   473         nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aStatusContext);
   474         xulBrowserWindow->SetOverLink(aStatusText, element);
   475         break;
   476       }
   477     }
   478   }
   480   return NS_OK;
   481 }
   483 //*****************************************************************************
   484 // nsContentTreeOwner::nsIWebBrowserChrome
   485 //*****************************************************************************   
   487 NS_IMETHODIMP nsContentTreeOwner::SetStatus(uint32_t aStatusType,
   488                                             const char16_t* aStatus)
   489 {
   490   return SetStatusWithContext(aStatusType,
   491       aStatus ? static_cast<const nsString &>(nsDependentString(aStatus))
   492               : EmptyString(),
   493       nullptr);
   494 }
   496 NS_IMETHODIMP nsContentTreeOwner::SetWebBrowser(nsIWebBrowser* aWebBrowser)
   497 {
   498    NS_ERROR("Haven't Implemented this yet");
   499    return NS_ERROR_FAILURE;
   500 }
   502 NS_IMETHODIMP nsContentTreeOwner::GetWebBrowser(nsIWebBrowser** aWebBrowser)
   503 {
   504   // Unimplemented, and probably will remain so; xpfe windows have docshells,
   505   // not webbrowsers.
   506   NS_ENSURE_ARG_POINTER(aWebBrowser);
   507   *aWebBrowser = 0;
   508   return NS_ERROR_FAILURE;
   509 }
   511 NS_IMETHODIMP nsContentTreeOwner::SetChromeFlags(uint32_t aChromeFlags)
   512 {
   513    NS_ENSURE_STATE(mXULWindow);
   514    return mXULWindow->SetChromeFlags(aChromeFlags);
   515 }
   517 NS_IMETHODIMP nsContentTreeOwner::GetChromeFlags(uint32_t* aChromeFlags)
   518 {
   519   NS_ENSURE_STATE(mXULWindow);
   520   return mXULWindow->GetChromeFlags(aChromeFlags);
   521 }
   523 NS_IMETHODIMP nsContentTreeOwner::DestroyBrowserWindow()
   524 {
   525    NS_ERROR("Haven't Implemented this yet");
   526    return NS_ERROR_FAILURE;
   527 }
   529 NS_IMETHODIMP nsContentTreeOwner::SizeBrowserTo(int32_t aCX, int32_t aCY)
   530 {
   531    NS_ERROR("Haven't Implemented this yet");
   532    return NS_ERROR_FAILURE;
   533 }
   535 NS_IMETHODIMP nsContentTreeOwner::ShowAsModal()
   536 {
   537    NS_ENSURE_STATE(mXULWindow);
   538    return mXULWindow->ShowModal();
   539 }
   541 NS_IMETHODIMP nsContentTreeOwner::IsWindowModal(bool *_retval)
   542 {
   543   NS_ENSURE_STATE(mXULWindow);
   544   *_retval = mXULWindow->mContinueModalLoop;
   545   return NS_OK;
   546 }
   548 NS_IMETHODIMP nsContentTreeOwner::ExitModalEventLoop(nsresult aStatus)
   549 {
   550    NS_ENSURE_STATE(mXULWindow);
   551    return mXULWindow->ExitModalLoop(aStatus);   
   552 }
   554 //*****************************************************************************
   555 // nsContentTreeOwner::nsIBaseWindow
   556 //*****************************************************************************   
   558 NS_IMETHODIMP nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
   559    nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy)   
   560 {
   561    // Ignore wigdet parents for now.  Don't think those are a vaild thing to call.
   562    NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, false), NS_ERROR_FAILURE);
   564    return NS_OK;
   565 }
   567 NS_IMETHODIMP nsContentTreeOwner::Create()
   568 {
   569    NS_ASSERTION(false, "You can't call this");
   570    return NS_ERROR_UNEXPECTED;
   571 }
   573 NS_IMETHODIMP nsContentTreeOwner::Destroy()
   574 {
   575    NS_ENSURE_STATE(mXULWindow);
   576    return mXULWindow->Destroy();
   577 }
   579 NS_IMETHODIMP nsContentTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
   580 {
   581    NS_ENSURE_STATE(mXULWindow);
   582    return mXULWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
   583 }
   585 NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY)
   586 {
   587    NS_ENSURE_STATE(mXULWindow);
   588    return mXULWindow->SetPosition(aX, aY);
   589 }
   591 NS_IMETHODIMP nsContentTreeOwner::GetPosition(int32_t* aX, int32_t* aY)
   592 {
   593    NS_ENSURE_STATE(mXULWindow);
   594    return mXULWindow->GetPosition(aX, aY);
   595 }
   597 NS_IMETHODIMP nsContentTreeOwner::SetSize(int32_t aCX, int32_t aCY, bool aRepaint)
   598 {
   599    NS_ENSURE_STATE(mXULWindow);
   600    return mXULWindow->SetSize(aCX, aCY, aRepaint);
   601 }
   603 NS_IMETHODIMP nsContentTreeOwner::GetSize(int32_t* aCX, int32_t* aCY)
   604 {
   605    NS_ENSURE_STATE(mXULWindow);
   606    return mXULWindow->GetSize(aCX, aCY);
   607 }
   609 NS_IMETHODIMP nsContentTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY,
   610    int32_t aCX, int32_t aCY, bool aRepaint)
   611 {
   612    NS_ENSURE_STATE(mXULWindow);
   613    return mXULWindow->SetPositionAndSize(aX, aY, aCX, aCY, aRepaint);
   614 }
   616 NS_IMETHODIMP nsContentTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY,
   617    int32_t* aCX, int32_t* aCY)
   618 {
   619    NS_ENSURE_STATE(mXULWindow);
   620    return mXULWindow->GetPositionAndSize(aX, aY, aCX, aCY); 
   621 }
   623 NS_IMETHODIMP nsContentTreeOwner::Repaint(bool aForce)
   624 {
   625    NS_ENSURE_STATE(mXULWindow);
   626    return mXULWindow->Repaint(aForce);
   627 }
   629 NS_IMETHODIMP nsContentTreeOwner::GetParentWidget(nsIWidget** aParentWidget)
   630 {
   631    NS_ENSURE_STATE(mXULWindow);
   632    return mXULWindow->GetParentWidget(aParentWidget);
   633 }
   635 NS_IMETHODIMP nsContentTreeOwner::SetParentWidget(nsIWidget* aParentWidget)
   636 {
   637    NS_ASSERTION(false, "You can't call this");
   638    return NS_ERROR_NOT_IMPLEMENTED;
   639 }
   641 NS_IMETHODIMP nsContentTreeOwner::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
   642 {
   643    NS_ENSURE_STATE(mXULWindow);
   644    return mXULWindow->GetParentNativeWindow(aParentNativeWindow);
   645 }
   647 NS_IMETHODIMP nsContentTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow)
   648 {
   649    NS_ASSERTION(false, "You can't call this");
   650    return NS_ERROR_NOT_IMPLEMENTED;
   651 }
   653 NS_IMETHODIMP nsContentTreeOwner::GetNativeHandle(nsAString& aNativeHandle)
   654 {
   655    NS_ENSURE_STATE(mXULWindow);
   656    return mXULWindow->GetNativeHandle(aNativeHandle);
   657 }
   659 NS_IMETHODIMP nsContentTreeOwner::GetVisibility(bool* aVisibility)
   660 {
   661    NS_ENSURE_STATE(mXULWindow);
   662    return mXULWindow->GetVisibility(aVisibility);
   663 }
   665 NS_IMETHODIMP nsContentTreeOwner::SetVisibility(bool aVisibility)
   666 {
   667    NS_ENSURE_STATE(mXULWindow);
   668    return mXULWindow->SetVisibility(aVisibility);
   669 }
   671 NS_IMETHODIMP nsContentTreeOwner::GetEnabled(bool *aEnabled)
   672 {
   673    NS_ENSURE_STATE(mXULWindow);
   674    return mXULWindow->GetEnabled(aEnabled);
   675 }
   677 NS_IMETHODIMP nsContentTreeOwner::SetEnabled(bool aEnable)
   678 {
   679    NS_ENSURE_STATE(mXULWindow);
   680    return mXULWindow->SetEnabled(aEnable);
   681 }
   683 NS_IMETHODIMP nsContentTreeOwner::GetMainWidget(nsIWidget** aMainWidget)
   684 {
   685    NS_ENSURE_ARG_POINTER(aMainWidget);
   686    NS_ENSURE_STATE(mXULWindow);
   688    *aMainWidget = mXULWindow->mWindow;
   689    NS_IF_ADDREF(*aMainWidget);
   691    return NS_OK;
   692 }
   694 NS_IMETHODIMP nsContentTreeOwner::SetFocus()
   695 {
   696    NS_ENSURE_STATE(mXULWindow);
   697    return mXULWindow->SetFocus();
   698 }
   700 NS_IMETHODIMP nsContentTreeOwner::GetTitle(char16_t** aTitle)
   701 {
   702    NS_ENSURE_ARG_POINTER(aTitle);
   703    NS_ENSURE_STATE(mXULWindow);
   705    return mXULWindow->GetTitle(aTitle);
   706 }
   708 NS_IMETHODIMP nsContentTreeOwner::SetTitle(const char16_t* aTitle)
   709 {
   710    // We only allow the title to be set from the primary content shell
   711   if(!mPrimary || !mContentTitleSetting)
   712     return NS_OK;
   714   NS_ENSURE_STATE(mXULWindow);
   716   nsAutoString   title;
   717   nsAutoString   docTitle(aTitle);
   719   if (docTitle.IsEmpty())
   720     docTitle.Assign(mTitleDefault);
   722   if (!docTitle.IsEmpty()) {
   723     if (!mTitlePreface.IsEmpty()) {
   724       // Title will be: "Preface: Doc Title - Mozilla"
   725       title.Assign(mTitlePreface);
   726       title.Append(docTitle);
   727     }
   728     else {
   729       // Title will be: "Doc Title - Mozilla"
   730       title = docTitle;
   731     }
   733     if (!mWindowTitleModifier.IsEmpty())
   734       title += mTitleSeparator + mWindowTitleModifier;
   735   }
   736   else
   737     title.Assign(mWindowTitleModifier); // Title will just be plain "Mozilla"
   739   //
   740   // if there is no location bar we modify the title to display at least
   741   // the scheme and host (if any) as an anti-spoofing measure.
   742   //
   743   nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
   745   if (docShellElement) {
   746     nsAutoString chromeString;
   747     docShellElement->GetAttribute(NS_LITERAL_STRING("chromehidden"), chromeString);
   748     if (chromeString.Find(NS_LITERAL_STRING("location")) != kNotFound) {
   749       //
   750       // location bar is turned off, find the browser location
   751       //
   752       // use the document's nsPrincipal to find the true owner
   753       // in case of javascript: or data: documents
   754       //
   755       nsCOMPtr<nsIDocShellTreeItem> dsitem;
   756       GetPrimaryContentShell(getter_AddRefs(dsitem));
   757       nsCOMPtr<nsIDOMDocument> domdoc(do_GetInterface(dsitem));
   758       nsCOMPtr<nsIScriptObjectPrincipal> doc(do_QueryInterface(domdoc));
   759       if (doc) {
   760         nsCOMPtr<nsIURI> uri;
   761         nsIPrincipal* principal = doc->GetPrincipal();
   762         if (principal) {
   763           principal->GetURI(getter_AddRefs(uri));
   764           if (uri) {
   765             //
   766             // remove any user:pass information
   767             //
   768             nsCOMPtr<nsIURIFixup> fixup(do_GetService(NS_URIFIXUP_CONTRACTID));
   769             if (fixup) {
   770               nsCOMPtr<nsIURI> tmpuri;
   771               nsresult rv = fixup->CreateExposableURI(uri,getter_AddRefs(tmpuri));
   772               if (NS_SUCCEEDED(rv) && tmpuri) {
   773                 // (don't bother if there's no host)
   774                 nsAutoCString host;
   775                 nsAutoCString prepath;
   776                 tmpuri->GetHost(host);
   777                 tmpuri->GetPrePath(prepath);
   778                 if (!host.IsEmpty()) {
   779                   //
   780                   // We have a scheme/host, update the title
   781                   //
   782                   title.Insert(NS_ConvertUTF8toUTF16(prepath) +
   783                                mTitleSeparator, 0);
   784                 }
   785               }
   786             }
   787           }
   788         }
   789       }
   790     }
   791     nsIDocument* document = docShellElement->OwnerDoc();
   792     ErrorResult rv;
   793     document->SetTitle(title, rv);
   794     return rv.ErrorCode();
   795   }
   797   return mXULWindow->SetTitle(title.get());
   798 }
   800 //*****************************************************************************
   801 // nsContentTreeOwner: nsIWindowProvider
   802 //*****************************************************************************   
   803 NS_IMETHODIMP
   804 nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
   805                                   uint32_t aChromeFlags,
   806                                   bool aCalledFromJS,
   807                                   bool aPositionSpecified,
   808                                   bool aSizeSpecified,
   809                                   nsIURI* aURI,
   810                                   const nsAString& aName,
   811                                   const nsACString& aFeatures,
   812                                   bool* aWindowIsNew,
   813                                   nsIDOMWindow** aReturn)
   814 {
   815   NS_ENSURE_ARG_POINTER(aParent);
   817   *aReturn = nullptr;
   819   if (!mXULWindow) {
   820     // Nothing to do here
   821     return NS_OK;
   822   }
   824 #ifdef DEBUG
   825   nsCOMPtr<nsIWebNavigation> parentNav = do_GetInterface(aParent);
   826   nsCOMPtr<nsIDocShellTreeOwner> parentOwner = do_GetInterface(parentNav);
   827   NS_ASSERTION(SameCOMIdentity(parentOwner,
   828                                static_cast<nsIDocShellTreeOwner*>(this)),
   829                "Parent from wrong docshell tree?");
   830 #endif
   832   // If aParent is inside an <iframe mozbrowser> and this isn't a request to
   833   // open a modal-type window, we're going to create a new <iframe mozbrowser>
   834   // and return its window here.
   835   nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
   836   if (docshell && docshell->GetIsInBrowserOrApp() &&
   837       !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
   838                         nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
   839                         nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
   841     BrowserElementParent::OpenWindowResult opened =
   842       BrowserElementParent::OpenWindowInProcess(aParent, aURI, aName,
   843                                                 aFeatures, aReturn);
   845     // If OpenWindowInProcess handled the open (by opening it or blocking the
   846     // popup), tell our caller not to proceed trying to create a new window
   847     // through other means.
   848     if (opened != BrowserElementParent::OPEN_WINDOW_IGNORED) {
   849       *aWindowIsNew = opened == BrowserElementParent::OPEN_WINDOW_ADDED;
   850       return *aWindowIsNew ? NS_OK : NS_ERROR_ABORT;
   851     }
   853     // If we're in an app and the target is _blank, send the url to the OS
   854     if (aName.LowerCaseEqualsLiteral("_blank")) {
   855       nsCOMPtr<nsIExternalURLHandlerService> exUrlServ(
   856                         do_GetService(NS_EXTERNALURLHANDLERSERVICE_CONTRACTID));
   857       if (exUrlServ) {
   859         nsCOMPtr<nsIHandlerInfo> info;
   860         bool found;
   861         exUrlServ->GetURLHandlerInfoFromOS(aURI, &found, getter_AddRefs(info));
   863         if (info && found) {
   864           info->LaunchWithURI(aURI, nullptr);
   865           return NS_ERROR_ABORT;
   866         }
   868       }
   869     }
   870   }
   872   // the parent window is fullscreen mode or not.
   873   bool isFullScreen = false;
   874   if (aParent) {
   875     aParent->GetFullScreen(&isFullScreen);
   876   }
   878   // Where should we open this?
   879   int32_t containerPref;
   880   if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
   881                                     &containerPref))) {
   882     return NS_OK;
   883   }
   885   bool isDisabledOpenNewWindow =
   886     isFullScreen &&
   887     Preferences::GetBool("browser.link.open_newwindow.disabled_in_fullscreen");
   889   if (isDisabledOpenNewWindow && (containerPref == nsIBrowserDOMWindow::OPEN_NEWWINDOW)) {
   890     containerPref = nsIBrowserDOMWindow::OPEN_NEWTAB;
   891   }
   893   if (containerPref != nsIBrowserDOMWindow::OPEN_NEWTAB &&
   894       containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
   895     // Just open a window normally
   896     return NS_OK;
   897   }
   899   if (aCalledFromJS) {
   900     /* Now check our restriction pref.  The restriction pref is a power-user's
   901        fine-tuning pref. values:     
   902        0: no restrictions - divert everything
   903        1: don't divert window.open at all
   904        2: don't divert window.open with features
   905     */
   906     int32_t restrictionPref =
   907       Preferences::GetInt("browser.link.open_newwindow.restriction", 2);
   908     if (restrictionPref < 0 || restrictionPref > 2) {
   909       restrictionPref = 2; // Sane default behavior
   910     }
   912     if (isDisabledOpenNewWindow) {
   913       // In browser fullscreen, the window should be opened
   914       // in the current window with no features (see bug 803675)
   915       restrictionPref = 0;
   916     }
   918     if (restrictionPref == 1) {
   919       return NS_OK;
   920     }
   922     if (restrictionPref == 2 &&
   923         // Only continue if there are no size/position features and no special
   924         // chrome flags.
   925         (aChromeFlags != nsIWebBrowserChrome::CHROME_ALL ||
   926          aPositionSpecified || aSizeSpecified)) {
   927       return NS_OK;
   928     }
   929   }
   931   nsCOMPtr<nsIDOMWindow> domWin;
   932   mXULWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
   933   nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(domWin);
   934   if (!chromeWin) {
   935     // Really odd... but whatever
   936     NS_WARNING("nsXULWindow's DOMWindow is not a chrome window");
   937     return NS_OK;
   938   }
   940   nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
   941   chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
   942   if (!browserDOMWin) {
   943     return NS_OK;
   944   }
   946   *aWindowIsNew = (containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
   948   {
   949     dom::AutoNoJSAPI nojsapi;
   951     // Get a new rendering area from the browserDOMWin.  We don't want
   952     // to be starting any loads here, so get it with a null URI.
   953     return browserDOMWin->OpenURI(nullptr, aParent, containerPref,
   954                                   nsIBrowserDOMWindow::OPEN_NEW, aReturn);
   955   }
   956 }
   958 //*****************************************************************************
   959 // nsContentTreeOwner: Accessors
   960 //*****************************************************************************
   962 #if defined(XP_MACOSX)
   963 class nsContentTitleSettingEvent : public nsRunnable
   964 {
   965 public:
   966   nsContentTitleSettingEvent(dom::Element* dse, const nsAString& wtm)
   967     : mElement(dse),
   968       mTitleDefault(wtm) {}
   970   NS_IMETHOD Run()
   971   {
   972     ErrorResult rv;
   973     mElement->SetAttribute(NS_LITERAL_STRING("titledefault"), mTitleDefault, rv);
   974     mElement->RemoveAttribute(NS_LITERAL_STRING("titlemodifier"), rv);
   975     return NS_OK;
   976   }
   978 private:
   979   nsCOMPtr<dom::Element> mElement;
   980   nsString mTitleDefault;
   981 };
   982 #endif
   984 void nsContentTreeOwner::XULWindow(nsXULWindow* aXULWindow)
   985 {
   986    mXULWindow = aXULWindow;
   987    if (mXULWindow && mPrimary) {
   988       // Get the window title modifiers
   989       nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
   991       nsAutoString   contentTitleSetting;
   993       if(docShellElement)
   994          {
   995          docShellElement->GetAttribute(NS_LITERAL_STRING("contenttitlesetting"), contentTitleSetting);
   996          if(contentTitleSetting.EqualsLiteral("true"))
   997             {
   998             mContentTitleSetting = true;
   999             docShellElement->GetAttribute(NS_LITERAL_STRING("titledefault"), mTitleDefault);
  1000             docShellElement->GetAttribute(NS_LITERAL_STRING("titlemodifier"), mWindowTitleModifier);
  1001             docShellElement->GetAttribute(NS_LITERAL_STRING("titlepreface"), mTitlePreface);
  1003 #if defined(XP_MACOSX)
  1004             // On OS X, treat the titlemodifier like it's the titledefault, and don't ever append
  1005             // the separator + appname.
  1006             if (mTitleDefault.IsEmpty()) {
  1007                 NS_DispatchToCurrentThread(
  1008                     new nsContentTitleSettingEvent(docShellElement,
  1009                                                    mWindowTitleModifier));
  1010                 mTitleDefault = mWindowTitleModifier;
  1011                 mWindowTitleModifier.Truncate();
  1013 #endif
  1014             docShellElement->GetAttribute(NS_LITERAL_STRING("titlemenuseparator"), mTitleSeparator);
  1017       else
  1019          NS_ERROR("This condition should never happen.  If it does, "
  1020             "we just won't get a modifier, but it still shouldn't happen.");
  1025 nsXULWindow* nsContentTreeOwner::XULWindow()
  1027    return mXULWindow;
  1030 //*****************************************************************************
  1031 //*** nsSiteWindow implementation
  1032 //*****************************************************************************
  1034 nsSiteWindow::nsSiteWindow(nsContentTreeOwner *aAggregator)
  1036   mAggregator = aAggregator;
  1039 nsSiteWindow::~nsSiteWindow()
  1043 NS_IMPL_ADDREF_USING_AGGREGATOR(nsSiteWindow, mAggregator)
  1044 NS_IMPL_RELEASE_USING_AGGREGATOR(nsSiteWindow, mAggregator)
  1046 NS_INTERFACE_MAP_BEGIN(nsSiteWindow)
  1047   NS_INTERFACE_MAP_ENTRY(nsISupports)
  1048   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
  1049 NS_INTERFACE_MAP_END_AGGREGATED(mAggregator)
  1051 NS_IMETHODIMP
  1052 nsSiteWindow::SetDimensions(uint32_t aFlags,
  1053                     int32_t aX, int32_t aY, int32_t aCX, int32_t aCY)
  1055   // XXX we're ignoring aFlags
  1056   return mAggregator->SetPositionAndSize(aX, aY, aCX, aCY, true);
  1059 NS_IMETHODIMP
  1060 nsSiteWindow::GetDimensions(uint32_t aFlags,
  1061                     int32_t *aX, int32_t *aY, int32_t *aCX, int32_t *aCY)
  1063   // XXX we're ignoring aFlags
  1064   return mAggregator->GetPositionAndSize(aX, aY, aCX, aCY);
  1067 NS_IMETHODIMP
  1068 nsSiteWindow::SetFocus(void)
  1070 #if 0
  1071   /* This implementation focuses the main document and could make sense.
  1072      However this method is actually being used from within
  1073      nsGlobalWindow::Focus (providing a hook for MDI embedding apps)
  1074      and it's better for our purposes to not pick a document and
  1075      focus it, but allow nsGlobalWindow to carry on unhindered.
  1076   */
  1077   nsXULWindow *window = mAggregator->XULWindow();
  1078   if (window) {
  1079     nsCOMPtr<nsIDocShell> docshell;
  1080     window->GetDocShell(getter_AddRefs(docshell));
  1081     nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell));
  1082     if (domWindow)
  1083       domWindow->Focus();
  1085 #endif
  1086   return NS_OK;
  1089 /* this implementation focuses another window. if there isn't another
  1090    window to focus, we do nothing. */
  1091 NS_IMETHODIMP
  1092 nsSiteWindow::Blur(void)
  1094   NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
  1096   nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
  1097   nsCOMPtr<nsIXULWindow>        xulWindow;
  1098   bool                          more, foundUs;
  1099   nsXULWindow                  *ourWindow = mAggregator->XULWindow();
  1102     nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
  1103     if (windowMediator)
  1104       windowMediator->GetZOrderXULWindowEnumerator(0, true,
  1105                         getter_AddRefs(windowEnumerator));
  1108   if (!windowEnumerator)
  1109     return NS_ERROR_FAILURE;
  1111   // step through the top-level windows
  1112   foundUs = false;
  1113   windowEnumerator->HasMoreElements(&more);
  1114   while (more) {
  1116     nsCOMPtr<nsISupports>  nextWindow;
  1117     nsCOMPtr<nsIXULWindow> nextXULWindow;
  1119     windowEnumerator->GetNext(getter_AddRefs(nextWindow));
  1120     nextXULWindow = do_QueryInterface(nextWindow);
  1122     // got it!(?)
  1123     if (foundUs) {
  1124       xulWindow = nextXULWindow;
  1125       break;
  1128     // remember the very first one, in case we have to wrap
  1129     if (!xulWindow)
  1130       xulWindow = nextXULWindow;
  1132     // look for us
  1133     if (nextXULWindow == ourWindow)
  1134       foundUs = true;
  1136     windowEnumerator->HasMoreElements(&more);
  1139   // change focus to the window we just found
  1140   if (xulWindow) {
  1141     nsCOMPtr<nsIDocShell> docshell;
  1142     xulWindow->GetDocShell(getter_AddRefs(docshell));
  1143     nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell));
  1144     if (domWindow)
  1145       domWindow->Focus();
  1147   return NS_OK;
  1150 NS_IMETHODIMP
  1151 nsSiteWindow::GetVisibility(bool *aVisibility)
  1153   return mAggregator->GetVisibility(aVisibility);
  1156 NS_IMETHODIMP
  1157 nsSiteWindow::SetVisibility(bool aVisibility)
  1159   return mAggregator->SetVisibility(aVisibility);
  1162 NS_IMETHODIMP
  1163 nsSiteWindow::GetTitle(char16_t * *aTitle)
  1165   return mAggregator->GetTitle(aTitle);
  1168 NS_IMETHODIMP
  1169 nsSiteWindow::SetTitle(const char16_t * aTitle)
  1171   return mAggregator->SetTitle(aTitle);
  1174 NS_IMETHODIMP
  1175 nsSiteWindow::GetSiteWindow(void **aSiteWindow)
  1177   return mAggregator->GetParentNativeWindow(aSiteWindow);

mercurial