Commit f7bfaba7 authored by Sandor Molnar's avatar Sandor Molnar
Browse files

Backed out 2 changesets (bug 1731597) for causing multiple wpt failures. CLOSED TREE

Backed out changeset 48cc3daf8201 (bug 1731597)
Backed out changeset db878c07f32a (bug 1731597)
parent 103e258b
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -406,38 +406,38 @@ RefPtr<ClientOpPromise> ClientOpenWindow(const ClientOpenWindowArgs& aArgs) {
  return promise.forget();
#endif  // MOZ_WIDGET_ANDROID

  RefPtr<BrowsingContextCallbackReceivedPromise::Private>
      browsingContextReadyPromise =
          new BrowsingContextCallbackReceivedPromise::Private(__func__);
  RefPtr<nsIBrowsingContextReadyCallback> callback =
      new nsBrowsingContextReadyCallback(browsingContextReadyPromise);

  RefPtr<nsOpenWindowInfo> openInfo = new nsOpenWindowInfo();
  openInfo->mBrowsingContextReadyCallback = callback;
  openInfo->mOriginAttributes = principal->OriginAttributesRef();
  openInfo->mIsRemote = true;

  openInfo->OnBrowsingContextReady(
      [argsValidated, promise](BrowsingContext* aBC) {
        if (aBC) {
          WaitForLoad(argsValidated, aBC, promise);
        } else {
          // in case of failure, reject the original promise
          CopyableErrorResult result;
          result.ThrowTypeError("Unable to open window");
          promise->Reject(result, __func__);
        }
      });

  RefPtr<BrowsingContext> bc;
  ErrorResult errResult;
  OpenWindow(argsValidated, openInfo, getter_AddRefs(bc), errResult);
  if (NS_WARN_IF(errResult.Failed())) {
    // Reject the promise immediately without waiting for the callback.
    openInfo->mBrowsingContextReadyCallback = nullptr;
    promise->Reject(errResult, __func__);
    return promise;
  }

  // If we immediately got a BrowsingContext back, we can invoke the ready
  // callback ourselves.
  browsingContextReadyPromise->Then(
      GetCurrentSerialEventTarget(), __func__,
      [argsValidated, promise](const RefPtr<BrowsingContext>& aBC) {
        WaitForLoad(argsValidated, aBC, promise);
      },
      [promise]() {
        // in case of failure, reject the original promise
        CopyableErrorResult result;
        result.ThrowTypeError("Unable to open window");
        promise->Reject(result, __func__);
      });
  if (bc) {
    if (nsCOMPtr cb = openInfo->mBrowsingContextReadyCallback.forget()) {
      cb->BrowsingContextReady(bc);
    }
    browsingContextReadyPromise->Resolve(bc, __func__);
  }
  return promise;
}
+78 −74
Original line number Diff line number Diff line
@@ -5133,10 +5133,10 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
    const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
    const nsCString& aFeatures, const float& aFullZoom,
    BrowserParent* aNextRemoteBrowser, const nsString& aName, nsresult& aResult,
    bool* aWindowIsNew, int32_t& aOpenLocation,
    nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo,
    bool aLoadURI, nsIContentSecurityPolicy* aCsp,
    const OriginAttributes& aOriginAttributes) {
    nsCOMPtr<nsIRemoteTab>& aNewRemoteTab, bool* aWindowIsNew,
    int32_t& aOpenLocation, nsIPrincipal* aTriggeringPrincipal,
    nsIReferrerInfo* aReferrerInfo, bool aLoadURI,
    nsIContentSecurityPolicy* aCsp, const OriginAttributes& aOriginAttributes) {
  // The content process should never be in charge of computing whether or
  // not a window should be private - the parent will do that.
  const uint32_t badFlags = nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW |
@@ -5156,7 +5156,6 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
  openInfo->mOriginAttributes = aOriginAttributes;

  MOZ_ASSERT_IF(aForWindowDotPrint, aForPrinting);
  MOZ_ASSERT_IF(aSetOpener, !aLoadURI);

  RefPtr<BrowserParent> topParent = BrowserParent::GetFrom(aThisTab);
  while (topParent && topParent->GetBrowserBridgeParent()) {
@@ -5255,8 +5254,16 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
    }
    RefPtr<nsFrameLoaderOwner> frameLoaderOwner = do_QueryObject(el);
    if (NS_SUCCEEDED(aResult) && frameLoaderOwner) {
      MOZ_ASSERT_IF(aNextRemoteBrowser,
                    BrowserParent::GetFrom(el) == aNextRemoteBrowser);
      RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
      if (frameLoader) {
        aNewRemoteTab = frameLoader->GetRemoteTab();
        // At this point, it's possible the inserted frameloader hasn't gone
        // through layout yet. To ensure that the dimensions that we send down
        // when telling the frameloader to display will be correct (instead of
        // falling back to a 10x10 default), we force layout if necessary to get
        // the most up-to-date dimensions. See bug 1358712 for details.
        frameLoader->ForceLayoutIfNecessary();
      }
    } else if (NS_SUCCEEDED(aResult) && !frameLoaderOwner) {
      // Fall through to the normal window opening code path when there is no
      // window which we can open a new tab in.
@@ -5278,52 +5285,62 @@ mozilla::ipc::IPCResult ContentParent::CommonCreateWindow(
    return IPC_OK();
  }

  // If we're going to perform a load, pre-configure the nsDocShellLoadState
  // which we'll use to perform the load. We'll start the load from the
  // `OnBrowsingContextReady` callback when it's inserted into the DOM.
  RefPtr<nsDocShellLoadState> loadState;
  if (aURIToLoad && aLoadURI) {
    loadState = MakeRefPtr<nsDocShellLoadState>(aURIToLoad);
    loadState->SetReferrerInfo(aReferrerInfo);
    loadState->SetTriggeringPrincipal(aTriggeringPrincipal);
    loadState->SetCsp(aCsp);
    uint32_t loadFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
    if (!aTriggeringPrincipal->IsSystemPrincipal()) {
      loadFlags |= nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD;
    }
    loadState->SetLoadFlags(loadFlags);
  }

  // Register a callback to be called when the newly created window is inserted
  // into the DOM. We'll use this to configure the BrowsingContext's name and
  // potentially start a load in it.
  openInfo->OnBrowsingContextReady(
      [aName, loadState, nextRemoteBrowser = RefPtr{aNextRemoteBrowser}](
          BrowsingContext* aBrowsingContext) {
        if (NS_WARN_IF(!aBrowsingContext)) {
          return;
  aResult = pwwatch->OpenWindowWithRemoteTab(thisBrowserHost, aFeatures,
                                             aCalledFromJS, aFullZoom, openInfo,
                                             getter_AddRefs(aNewRemoteTab));
  if (NS_WARN_IF(NS_FAILED(aResult))) {
    return IPC_OK();
  }

  MOZ_ASSERT(aNewRemoteTab);
  RefPtr<BrowserHost> newBrowserHost = BrowserHost::GetFrom(aNewRemoteTab);
  RefPtr<BrowserParent> newBrowserParent = newBrowserHost->GetActor();

  // At this point, it's possible the inserted frameloader hasn't gone through
  // layout yet. To ensure that the dimensions that we send down when telling
  // the frameloader to display will be correct (instead of falling back to a
  // 10x10 default), we force layout if necessary to get the most up-to-date
  // dimensions. See bug 1358712 for details.
  //
  // This involves doing a bit of gymnastics in order to get at the FrameLoader,
  // so we scope this to avoid polluting the main function scope.
  {
    nsCOMPtr<Element> frameElement = newBrowserHost->GetOwnerElement();
    MOZ_ASSERT(frameElement);
    RefPtr<nsFrameLoaderOwner> frameLoaderOwner = do_QueryObject(frameElement);
    MOZ_ASSERT(frameLoaderOwner);
    RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
    MOZ_ASSERT(frameLoader);
    frameLoader->ForceLayoutIfNecessary();
  }
        MOZ_ASSERT_IF(
            nextRemoteBrowser,
            nextRemoteBrowser->GetBrowsingContext() == aBrowsingContext);

  // If we were passed a name for the window which would override the default,
  // we should send it down to the new tab.
  if (nsContentUtils::IsOverridingWindowName(aName)) {
          MOZ_ALWAYS_SUCCEEDS(aBrowsingContext->SetName(aName));
    MOZ_ALWAYS_SUCCEEDS(newBrowserHost->GetBrowsingContext()->SetName(aName));
  }
        if (loadState) {
          // Ensure that we've performed layout out the new window's browser
          // before we start loading in it.
          if (RefPtr<nsFrameLoaderOwner> flo =
                  do_QueryObject(aBrowsingContext->GetEmbedderElement())) {
            if (RefPtr<nsFrameLoader> fl = flo->GetFrameLoader()) {
              fl->ForceLayoutIfNecessary();

  MOZ_ASSERT(newBrowserHost->GetBrowsingContext()->OriginAttributesRef() ==
             aOriginAttributes);

  if (aURIToLoad && aLoadURI) {
    nsCOMPtr<mozIDOMWindowProxy> openerWindow;
    if (aSetOpener && topParent) {
      openerWindow = topParent->GetParentWindowOuter();
    }
    nsCOMPtr<nsIBrowserDOMWindow> newBrowserDOMWin =
        newBrowserParent->GetBrowserDOMWindow();
    if (NS_WARN_IF(!newBrowserDOMWin)) {
      aResult = NS_ERROR_ABORT;
      return IPC_OK();
    }
          aBrowsingContext->LoadURI(loadState);
    RefPtr<BrowsingContext> bc;
    aResult = newBrowserDOMWin->OpenURI(
        aURIToLoad, openInfo, nsIBrowserDOMWindow::OPEN_CURRENTWINDOW,
        nsIBrowserDOMWindow::OPEN_NEW, aTriggeringPrincipal, aCsp,
        getter_AddRefs(bc));
  }
      });

  aResult = pwwatch->OpenWindowWithRemoteTab(
      thisBrowserHost, aFeatures, aCalledFromJS, aFullZoom, openInfo);
  return IPC_OK();
}

@@ -5409,40 +5426,26 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindow(
    }
  }

  if (newTab->GetOwnerElement()) {
    return IPC_FAIL(
        this, "New BrowserParent must not have been inserted into the DOM");
  }

  BrowserParent::AutoUseNewTab aunt(newTab);

  nsCOMPtr<nsIRemoteTab> newRemoteTab;
  int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;
  mozilla::ipc::IPCResult ipcResult = CommonCreateWindow(
      aThisTab, parent, newBCOpenerId != 0, aChromeFlags, aCalledFromJS,
      aWidthSpecified, aForPrinting, aForPrintPreview, aURIToLoad, aFeatures,
      aFullZoom, newTab, VoidString(), rv, &cwi.windowOpened(), openLocation,
      aTriggeringPrincipal, aReferrerInfo, /* aLoadUri = */ false, aCsp,
      aOriginAttributes);
      aFullZoom, newTab, VoidString(), rv, newRemoteTab, &cwi.windowOpened(),
      openLocation, aTriggeringPrincipal, aReferrerInfo, /* aLoadUri = */ false,
      aCsp, aOriginAttributes);
  if (!ipcResult) {
    return ipcResult;
  }

  if (NS_WARN_IF(NS_FAILED(rv)) || !cwi.windowOpened()) {
  if (NS_WARN_IF(NS_FAILED(rv)) || !newRemoteTab) {
    return IPC_OK();
  }

  // At this point, it's possible the inserted frameloader hasn't gone through
  // layout yet. To ensure that the dimensions that we send down when telling
  // the frameloader to display will be correct (instead of falling back to a
  // 10x10 default), we force layout if necessary to get the most up-to-date
  // dimensions. See bug 1358712 for details.
  RefPtr<nsFrameLoaderOwner> frameLoaderOwner =
      do_QueryObject(newTab->GetOwnerElement());
  MOZ_DIAGNOSTIC_ASSERT(frameLoaderOwner,
                        "The new tab must have been inserted");
  RefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
  MOZ_DIAGNOSTIC_ASSERT(frameLoader, "The new tab should have a frameLoader");
  frameLoader->ForceLayoutIfNecessary();
  MOZ_ASSERT(BrowserHost::GetFrom(newRemoteTab.get()) ==
             newTab->GetBrowserHost());

  newTab->SwapFrameScriptsFrom(cwi.frameScripts());
  newTab->MaybeShowFrame();
@@ -5473,7 +5476,8 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
    return IPC_OK();
  }

  bool windowIsNew = true;
  nsCOMPtr<nsIRemoteTab> newRemoteTab;
  bool windowIsNew;
  int32_t openLocation = nsIBrowserDOMWindow::OPEN_NEWWINDOW;

  // If we have enough data, check the schemes of the loader and loadee
@@ -5506,9 +5510,9 @@ mozilla::ipc::IPCResult ContentParent::RecvCreateWindowInDifferentProcess(
      aThisTab, parent, /* aSetOpener = */ false, aChromeFlags, aCalledFromJS,
      aWidthSpecified, /* aForPrinting = */ false,
      /* aForPrintPreview = */ false, aURIToLoad, aFeatures, aFullZoom,
      /* aNextRemoteBrowser = */ nullptr, aName, rv, &windowIsNew, openLocation,
      aTriggeringPrincipal, aReferrerInfo, /* aLoadUri = */ true, aCsp,
      aOriginAttributes);
      /* aNextRemoteBrowser = */ nullptr, aName, rv, newRemoteTab, &windowIsNew,
      openLocation, aTriggeringPrincipal, aReferrerInfo,
      /* aLoadUri = */ true, aCsp, aOriginAttributes);
  if (!ipcResult) {
    return ipcResult;
  }
+2 −1
Original line number Diff line number Diff line
@@ -768,7 +768,8 @@ class ContentParent final
      const bool& aForWindowDotPrint, nsIURI* aURIToLoad,
      const nsCString& aFeatures, const float& aFullZoom,
      BrowserParent* aNextRemoteBrowser, const nsString& aName,
      nsresult& aResult, bool* aWindowIsNew, int32_t& aOpenLocation,
      nsresult& aResult, nsCOMPtr<nsIRemoteTab>& aNewRemoteTab,
      bool* aWindowIsNew, int32_t& aOpenLocation,
      nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo,
      bool aLoadUri, nsIContentSecurityPolicy* aCsp,
      const OriginAttributes& aOriginAttributes);
+23 −40
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@
#include "mozilla/OriginAttributes.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/BrowserParent.h"
#include "nsThreadUtils.h"

NS_IMPL_ISUPPORTS(nsOpenWindowInfo, nsIOpenWindowInfo)

@@ -45,11 +44,11 @@ NS_IMETHODIMP nsOpenWindowInfo::GetScriptableOriginAttributes(
  return NS_OK;
}

const mozilla::OriginAttributes& nsOpenWindowInfo::GetOriginAttributes() {
const OriginAttributes& nsOpenWindowInfo::GetOriginAttributes() {
  return mOriginAttributes;
}

mozilla::dom::BrowserParent* nsOpenWindowInfo::GetNextRemoteBrowser() {
BrowserParent* nsOpenWindowInfo::GetNextRemoteBrowser() {
  return mNextRemoteBrowser;
}

@@ -58,48 +57,32 @@ nsOpenWindowInfo::BrowsingContextReadyCallback() {
  return mBrowsingContextReadyCallback;
}

namespace {

class nsBrowsingContextReadyCallback final
    : public nsIBrowsingContextReadyCallback {
 public:
  NS_DECL_ISUPPORTS
NS_IMPL_ISUPPORTS(nsBrowsingContextReadyCallback,
                  nsIBrowsingContextReadyCallback)

  explicit nsBrowsingContextReadyCallback(
      std::function<void(mozilla::dom::BrowsingContext*)>&& aCallback)
      : mCallback(aCallback) {}
nsBrowsingContextReadyCallback::nsBrowsingContextReadyCallback(
    RefPtr<BrowsingContextCallbackReceivedPromise::Private> aPromise)
    : mPromise(std::move(aPromise)) {}

  NS_IMETHOD BrowsingContextReady(mozilla::dom::BrowsingContext* aBC) override {
    if (!mCallback) {
      return NS_OK;
nsBrowsingContextReadyCallback::~nsBrowsingContextReadyCallback() {
  if (mPromise) {
    mPromise->Reject(NS_ERROR_FAILURE, __func__);
  }
    // Spin the event loop to make sure everything's been initialized before we
    // invoke the callback.
    NS_DispatchToMainThread(NS_NewRunnableFunction(
        "BrowsingContextReadyCallback",
        [callback = std::move(mCallback), bc = RefPtr{aBC}] { callback(bc); }));
    mCallback = nullptr;
    return NS_OK;
  mPromise = nullptr;
}

 private:
  ~nsBrowsingContextReadyCallback() { BrowsingContextReady(nullptr); }

  std::function<void(mozilla::dom::BrowsingContext*)> mCallback;
};

NS_IMPL_ISUPPORTS(nsBrowsingContextReadyCallback,
                  nsIBrowsingContextReadyCallback)

}  // namespace

nsresult nsOpenWindowInfo::OnBrowsingContextReady(
    std::function<void(mozilla::dom::BrowsingContext*)>&& aCallback) {
  if (mBrowsingContextReadyCallback) {
    return NS_ERROR_ALREADY_INITIALIZED;
NS_IMETHODIMP nsBrowsingContextReadyCallback::BrowsingContextReady(
    BrowsingContext* aBC) {
  MOZ_DIAGNOSTIC_ASSERT(mPromise,
                        "The 'browsing context ready' callback is null");
  if (!mPromise) {
    return NS_OK;
  }
  if (aBC) {
    mPromise->Resolve(aBC, __func__);
  } else {
    mPromise->Reject(NS_ERROR_FAILURE, __func__);
  }
  mBrowsingContextReadyCallback =
      mozilla::MakeAndAddRef<nsBrowsingContextReadyCallback>(
          std::move(aCallback));
  mPromise = nullptr;
  return NS_OK;
}
+16 −3
Original line number Diff line number Diff line
@@ -27,11 +27,24 @@ class nsOpenWindowInfo : public nsIOpenWindowInfo {
  RefPtr<mozilla::dom::BrowsingContext> mParent;
  RefPtr<nsIBrowsingContextReadyCallback> mBrowsingContextReadyCallback;

  nsresult OnBrowsingContextReady(
      std::function<void(mozilla::dom::BrowsingContext*)>&& aCallback);

 private:
  virtual ~nsOpenWindowInfo() = default;
};

class nsBrowsingContextReadyCallback : public nsIBrowsingContextReadyCallback {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIBROWSINGCONTEXTREADYCALLBACK

  explicit nsBrowsingContextReadyCallback(
      RefPtr<mozilla::dom::BrowsingContextCallbackReceivedPromise::Private>
          aPromise);

 private:
  virtual ~nsBrowsingContextReadyCallback();

  RefPtr<mozilla::dom::BrowsingContextCallbackReceivedPromise::Private>
      mPromise;
};

#endif  // nsOpenWindowInfo_h
Loading