Bug 1531128 part 2. Add a docshell API for determining whether a navigation is in progress. r=mccr8
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 27 Feb 2019 23:21:29 +0000
changeset 519446 170b333092c82ce0cf39eec04f91f3700c9260e4
parent 519445 21c7deb32a777b484039c8f85d748b75a47f5b95
child 519447 9b84cbe0e2a3e0ec2e29c7e79a7a080025816a15
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1531128
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1531128 part 2. Add a docshell API for determining whether a navigation is in progress. r=mccr8 This is needed by the document.open spec, which cancels loads for the document only if a navigation is pending. Differential Revision: https://phabricator.services.mozilla.com/D21441
docshell/base/nsDocShell.cpp
docshell/base/nsIDocShell.idl
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -13448,8 +13448,48 @@ nsDocShell::GetColorMatrix(uint32_t* aMa
 
 bool nsDocShell::IsForceReloading() { return IsForceReloadType(mLoadType); }
 
 NS_IMETHODIMP
 nsDocShell::GetBrowsingContext(BrowsingContext** aBrowsingContext) {
   *aBrowsingContext = do_AddRef(mBrowsingContext).take();
   return NS_OK;
 }
+
+bool nsDocShell::GetIsAttemptingToNavigate() {
+  // XXXbz the document.open spec says to abort even if there's just a
+  // queued navigation task, sort of.  It's not clear whether browsers
+  // actually do that, and we didn't use to do it, so for now let's
+  // not do that.
+  // https://github.com/whatwg/html/issues/3447 tracks the spec side of this.
+  if (mDocumentRequest) {
+    // There's definitely a navigation in progress.
+    return true;
+  }
+
+  // javascript: channels have slightly weird behavior: they're LOAD_BACKGROUND
+  // until the script runs, which means they're not sending loadgroup
+  // notifications and hence not getting set as mDocumentRequest.  Look through
+  // our loadgroup for document-level javascript: loads.
+  if (!mLoadGroup) {
+    return false;
+  }
+
+  nsCOMPtr<nsISimpleEnumerator> requests;
+  mLoadGroup->GetRequests(getter_AddRefs(requests));
+  bool hasMore = false;
+  while (NS_SUCCEEDED(requests->HasMoreElements(&hasMore)) && hasMore) {
+    nsCOMPtr<nsISupports> elem;
+    requests->GetNext(getter_AddRefs(elem));
+    nsCOMPtr<nsIScriptChannel> scriptChannel(do_QueryInterface(elem));
+    if (!scriptChannel) {
+      continue;
+    }
+
+    if (scriptChannel->GetIsDocumentLoad()) {
+      // This is a javascript: load that might lead to a new document,
+      // hence a navigation.
+      return true;
+    }
+  }
+
+  return false;
+}
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -1119,9 +1119,15 @@ interface nsIDocShell : nsIDocShellTreeI
    * content blocking events happened so far in the current tab from the
    * content process.
    *
    * This returns a Promise which resolves to a string on success, and is
    * rejected on failure.  For documentation on the string format, please
    * see nsISecureBrowserUI.contentBlockingLogJSON.
    */
   Promise getContentBlockingLog();
+
+  /**
+   * Return whether this docshell is "attempting to navigate" in the
+   * sense that's relevant to document.open.
+   */
+  [notxpcom, nostdcall] readonly attribute boolean isAttemptingToNavigate;
 };