tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XULFrameElement.cpp (6758B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/dom/XULFrameElement.h"
      8 
      9 #include "mozilla/AsyncEventDispatcher.h"
     10 #include "mozilla/dom/BrowserParent.h"
     11 #include "mozilla/dom/HTMLIFrameElement.h"
     12 #include "mozilla/dom/WindowProxyHolder.h"
     13 #include "mozilla/dom/XULFrameElementBinding.h"
     14 #include "nsCOMPtr.h"
     15 #include "nsFrameLoader.h"
     16 #include "nsIBrowser.h"
     17 #include "nsIContent.h"
     18 #include "nsIOpenWindowInfo.h"
     19 
     20 namespace mozilla::dom {
     21 
     22 NS_IMPL_CYCLE_COLLECTION_CLASS(XULFrameElement)
     23 
     24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULFrameElement, nsXULElement)
     25  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
     26  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenWindowInfo)
     27 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     28 
     29 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULFrameElement, nsXULElement)
     30  if (tmp->mFrameLoader) {
     31    tmp->mFrameLoader->Destroy();
     32  }
     33  NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenWindowInfo)
     34 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     35 
     36 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(XULFrameElement, nsXULElement,
     37                                             nsFrameLoaderOwner)
     38 
     39 JSObject* XULFrameElement::WrapNode(JSContext* aCx,
     40                                    JS::Handle<JSObject*> aGivenProto) {
     41  return XULFrameElement_Binding::Wrap(aCx, this, aGivenProto);
     42 }
     43 
     44 nsDocShell* XULFrameElement::GetDocShell() {
     45  RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
     46  return frameLoader ? frameLoader->GetDocShell(IgnoreErrors()) : nullptr;
     47 }
     48 
     49 already_AddRefed<nsIWebNavigation> XULFrameElement::GetWebNavigation() {
     50  nsCOMPtr<nsIDocShell> docShell = GetDocShell();
     51  nsCOMPtr<nsIWebNavigation> webnav = do_QueryInterface(docShell);
     52  return webnav.forget();
     53 }
     54 
     55 Nullable<WindowProxyHolder> XULFrameElement::GetContentWindow() {
     56  RefPtr<nsDocShell> docShell = GetDocShell();
     57  if (docShell) {
     58    return docShell->GetWindowProxy();
     59  }
     60 
     61  return nullptr;
     62 }
     63 
     64 Document* XULFrameElement::GetContentDocument() {
     65  nsCOMPtr<nsIDocShell> docShell = GetDocShell();
     66  if (docShell) {
     67    nsCOMPtr<nsPIDOMWindowOuter> win = docShell->GetWindow();
     68    if (win) {
     69      return win->GetDoc();
     70    }
     71  }
     72  return nullptr;
     73 }
     74 
     75 uint64_t XULFrameElement::BrowserId() {
     76  if (mFrameLoader) {
     77    if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
     78      return bc->GetBrowserId();
     79    }
     80  }
     81  return 0;
     82 }
     83 
     84 nsIOpenWindowInfo* XULFrameElement::GetOpenWindowInfo() const {
     85  return mOpenWindowInfo;
     86 }
     87 
     88 void XULFrameElement::SetOpenWindowInfo(nsIOpenWindowInfo* aInfo) {
     89  mOpenWindowInfo = aInfo;
     90 }
     91 
     92 void XULFrameElement::LoadSrc() {
     93  if (!IsInComposedDoc()) {
     94    return;
     95  }
     96  RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
     97  if (!frameLoader) {
     98    // We may have had a nsIOpenWindowInfo set on us by browser chrome, due to
     99    // being used as the target for a `window.open` call. Fetch that information
    100    // if it's available, and clear it out so we don't read it again.
    101    nsCOMPtr<nsIOpenWindowInfo> openWindowInfo = mOpenWindowInfo.forget();
    102 
    103    // false as the networkCreated parameter so that xul:iframe/browser/editor
    104    // session history handling works like dynamic html:iframes. Usually xul
    105    // elements are used in chrome, which doesn't have session history at all.
    106    mFrameLoader = nsFrameLoader::Create(this, false, openWindowInfo);
    107    if (NS_WARN_IF(!mFrameLoader)) {
    108      return;
    109    }
    110 
    111    AsyncEventDispatcher::RunDOMEventWhenSafe(
    112        *this, u"XULFrameLoaderCreated"_ns, CanBubble::eYes);
    113  }
    114 
    115  mFrameLoader->LoadFrame(/* aOriginalSrc */ false,
    116                          /* aShouldCheckForRecursion */ false);
    117 }
    118 
    119 void XULFrameElement::SwapFrameLoaders(HTMLIFrameElement& aOtherLoaderOwner,
    120                                       ErrorResult& rv) {
    121  aOtherLoaderOwner.SwapFrameLoaders(this, rv);
    122 }
    123 
    124 void XULFrameElement::SwapFrameLoaders(XULFrameElement& aOtherLoaderOwner,
    125                                       ErrorResult& rv) {
    126  if (&aOtherLoaderOwner == this) {
    127    // nothing to do
    128    return;
    129  }
    130 
    131  aOtherLoaderOwner.SwapFrameLoaders(this, rv);
    132 }
    133 
    134 void XULFrameElement::SwapFrameLoaders(nsFrameLoaderOwner* aOtherLoaderOwner,
    135                                       mozilla::ErrorResult& rv) {
    136  if (RefPtr<Document> doc = GetComposedDoc()) {
    137    // SwapWithOtherLoader relies on frames being up-to-date.
    138    doc->FlushPendingNotifications(FlushType::Frames);
    139  }
    140 
    141  RefPtr<nsFrameLoader> loader = GetFrameLoader();
    142  RefPtr<nsFrameLoader> otherLoader = aOtherLoaderOwner->GetFrameLoader();
    143  if (!loader || !otherLoader) {
    144    rv.Throw(NS_ERROR_NOT_IMPLEMENTED);
    145    return;
    146  }
    147 
    148  rv = loader->SwapWithOtherLoader(otherLoader, this, aOtherLoaderOwner);
    149 }
    150 
    151 nsresult XULFrameElement::BindToTree(BindContext& aContext, nsINode& aParent) {
    152  MOZ_TRY(nsXULElement::BindToTree(aContext, aParent));
    153 
    154  if (IsInComposedDoc()) {
    155    NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
    156                 "Missing a script blocker!");
    157    // We're in a document now.  Kick off the frame load.
    158    LoadSrc();
    159  }
    160 
    161  return NS_OK;
    162 }
    163 
    164 void XULFrameElement::UnbindFromTree(UnbindContext& aContext) {
    165  if (RefPtr<nsFrameLoader> frameLoader = GetFrameLoader()) {
    166    frameLoader->Destroy();
    167  }
    168  mFrameLoader = nullptr;
    169 
    170  nsXULElement::UnbindFromTree(aContext);
    171 }
    172 
    173 void XULFrameElement::DestroyContent() {
    174  RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
    175  if (frameLoader) {
    176    frameLoader->Destroy();
    177  }
    178  mFrameLoader = nullptr;
    179 
    180  nsXULElement::DestroyContent();
    181 }
    182 
    183 void XULFrameElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
    184                                   const nsAttrValue* aValue,
    185                                   const nsAttrValue* aOldValue,
    186                                   nsIPrincipal* aSubjectPrincipal,
    187                                   bool aNotify) {
    188  if (aNamespaceID == kNameSpaceID_None) {
    189    if (aName == nsGkAtoms::src && aValue) {
    190      LoadSrc();
    191    } else if (aName == nsGkAtoms::disablefullscreen && mFrameLoader) {
    192      if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
    193        MOZ_ALWAYS_SUCCEEDS(bc->SetFullscreenAllowedByOwner(!aValue));
    194      }
    195    } else if (aName == nsGkAtoms::transparent && mFrameLoader &&
    196               (!!aValue != !!aOldValue)) {
    197      if (auto* bp = mFrameLoader->GetBrowserParent()) {
    198        bp->NotifyTransparencyChanged();
    199      }
    200    }
    201  }
    202 
    203  return nsXULElement::AfterSetAttr(aNamespaceID, aName, aValue, aOldValue,
    204                                    aSubjectPrincipal, aNotify);
    205 }
    206 
    207 }  // namespace mozilla::dom