Backed out changeset 7c0ca61c3552 (bug 1321270) for bustage
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 30 Nov 2016 16:46:25 +0100
changeset 324823 c8c4aa44419c08e669397cfe8c5e79be64efa924
parent 324822 e3b6a523e34bc36384ea0cbc27bdb7c2e0938064
child 324824 a8eed0b176b532a6f4d8aceba50e65de570499f4
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
bugs1321270
milestone53.0a1
backs out7c0ca61c3552c2c7809dc769e7365e629402b947
Backed out changeset 7c0ca61c3552 (bug 1321270) for bustage
dom/base/nsPIDOMWindow.h
dom/base/nsPIDOMWindowInlines.h
embedding/components/windowwatcher/nsWindowWatcher.cpp
embedding/nsIWindowCreator2.idl
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -190,16 +190,18 @@ public:
   virtual bool IsRunningTimeout() = 0;
 
 protected:
   // Lazily instantiate an about:blank document if necessary, and if
   // we have what it takes to do so.
   void MaybeCreateDoc();
 
 public:
+  inline bool IsLoadingOrRunningTimeout() const;
+
   // Check whether a document is currently loading
   inline bool IsLoading() const;
   inline bool IsHandlingResizeEvent() const;
 
   // Set the window up with an about:blank document with the current subject
   // principal.
   // Outer windows only.
   virtual void SetInitialPrincipalToSubject() = 0;
--- a/dom/base/nsPIDOMWindowInlines.h
+++ b/dom/base/nsPIDOMWindowInlines.h
@@ -31,16 +31,26 @@ const nsPIDOMWindowOuter*
 nsPIDOMWindow<T>::AsOuter() const
 {
   MOZ_ASSERT(IsOuterWindow());
   return reinterpret_cast<const nsPIDOMWindowOuter*>(this);
 }
 
 template <class T>
 bool
+nsPIDOMWindow<T>::IsLoadingOrRunningTimeout() const
+{
+  if (IsOuterWindow()) {
+    return AsOuter()->GetCurrentInnerWindow()->IsLoadingOrRunningTimeout();
+  }
+  return !mIsDocumentLoaded || mRunningTimeout;
+}
+
+template <class T>
+bool
 nsPIDOMWindow<T>::IsLoading() const
 {
   if (IsOuterWindow()) {
     auto* win = AsOuter()->GetCurrentInnerWindow();
 
     if (!win) {
       NS_ERROR("No current inner window available!");
 
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -479,16 +479,17 @@ nsWindowWatcher::OpenWindowWithoutParent
 {
   return OpenWindowWithTabParent(nullptr, EmptyCString(), true, 1.0f, aResult);
 }
 
 nsresult
 nsWindowWatcher::CreateChromeWindow(const nsACString& aFeatures,
                                     nsIWebBrowserChrome* aParentChrome,
                                     uint32_t aChromeFlags,
+                                    uint32_t aContextFlags,
                                     nsITabParent* aOpeningTabParent,
                                     mozIDOMWindowProxy* aOpener,
                                     nsIWebBrowserChrome** aResult)
 {
   nsCOMPtr<nsIWindowCreator2> windowCreator2(do_QueryInterface(mWindowCreator));
   if (NS_WARN_IF(!windowCreator2)) {
     return NS_ERROR_UNEXPECTED;
   }
@@ -498,19 +499,18 @@ nsWindowWatcher::CreateChromeWindow(cons
 #ifdef MOZ_WIDGET_GONK
   int retval = WinHasOption(aFeatures, "mozDisplayId", 0, nullptr);
   windowCreator2->SetScreenId(retval);
 #endif
 
   bool cancel = false;
   nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
   nsresult rv =
-    windowCreator2->CreateChromeWindow2(aParentChrome, aChromeFlags,
-                                        0 /* contextFlag */,  aOpeningTabParent,
-                                        aOpener, &cancel,
+    windowCreator2->CreateChromeWindow2(aParentChrome, aChromeFlags, aContextFlags,
+                                        aOpeningTabParent, aOpener, &cancel,
                                         getter_AddRefs(newWindowChrome));
 
   if (NS_SUCCEEDED(rv) && cancel) {
     newWindowChrome = nullptr;
     return NS_ERROR_ABORT;
   }
 
   newWindowChrome.forget(aResult);
@@ -604,26 +604,32 @@ nsWindowWatcher::OpenWindowWithTabParent
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIWindowCreator2> windowCreator2(do_QueryInterface(mWindowCreator));
   if (NS_WARN_IF(!windowCreator2)) {
     return NS_ERROR_UNEXPECTED;
   }
 
+  uint32_t contextFlags = 0;
+  if (parentWindowOuter->IsLoadingOrRunningTimeout()) {
+    contextFlags |=
+            nsIWindowCreator2::PARENT_IS_LOADING_OR_RUNNING_TIMEOUT;
+  }
+
   uint32_t chromeFlags = CalculateChromeFlagsForChild(aFeatures);
 
   // A content process has asked for a new window, which implies
   // that the new window will need to be remote.
   chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
 
   nsCOMPtr<nsIWebBrowserChrome> parentChrome(do_GetInterface(parentTreeOwner));
   nsCOMPtr<nsIWebBrowserChrome> newWindowChrome;
 
-  CreateChromeWindow(aFeatures, parentChrome, chromeFlags, 0 /* contextFlags */,
+  CreateChromeWindow(aFeatures, parentChrome, chromeFlags, contextFlags,
                      aOpeningTabParent, nullptr, getter_AddRefs(newWindowChrome));
 
   if (NS_WARN_IF(!newWindowChrome)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   nsCOMPtr<nsIDocShellTreeItem> chromeTreeItem = do_GetInterface(newWindowChrome);
   if (NS_WARN_IF(!chromeTreeItem)) {
@@ -959,21 +965,47 @@ nsWindowWatcher::OpenWindowInternal(mozI
       }
     }
 
     NS_ASSERTION(mWindowCreator,
                  "attempted to open a new window with no WindowCreator");
     rv = NS_ERROR_FAILURE;
     if (mWindowCreator) {
       nsCOMPtr<nsIWebBrowserChrome> newChrome;
+
+      /* If the window creator is an nsIWindowCreator2, we can give it
+         some hints. The only hint at this time is whether the opening window
+         is in a situation that's likely to mean this is an unrequested
+         popup window we're creating. However we're not completely honest:
+         we clear that indicator if the opener is chrome, so that the
+         downstream consumer can treat the indicator to mean simply
+         that the new window is subject to popup control. */
       nsCOMPtr<nsIWindowCreator2> windowCreator2(
         do_QueryInterface(mWindowCreator));
       if (windowCreator2) {
+        uint32_t contextFlags = 0;
+        bool popupConditions = false;
+
+        // is the parent under popup conditions?
+        if (parentWindow) {
+          popupConditions = parentWindow->IsLoadingOrRunningTimeout();
+        }
+
+        // chrome is always allowed, so clear the flag if the opener is chrome
+        if (popupConditions) {
+          popupConditions = !isCallerChrome;
+        }
+
+        if (popupConditions) {
+          contextFlags |=
+            nsIWindowCreator2::PARENT_IS_LOADING_OR_RUNNING_TIMEOUT;
+        }
+
         mozIDOMWindowProxy* openerWindow = aForceNoOpener ? nullptr : aParent;
-        rv = CreateChromeWindow(features, parentChrome, chromeFlags,
+        rv = CreateChromeWindow(features, parentChrome, chromeFlags, contextFlags,
                                 nullptr, openerWindow, getter_AddRefs(newChrome));
 
       } else {
         rv = mWindowCreator->CreateChromeWindow(parentChrome, chromeFlags,
                                                 getter_AddRefs(newChrome));
       }
 
       if (newChrome) {
--- a/embedding/nsIWindowCreator2.idl
+++ b/embedding/nsIWindowCreator2.idl
@@ -25,16 +25,19 @@ interface mozIDOMWindowProxy;
 [scriptable, uuid(b6c44689-f97e-4f32-a723-29eeddfbdc53)]
 
 interface nsIWindowCreator2 : nsIWindowCreator {
 
   /**
    * Definitions for contextFlags
    */
 
+  // Likely that the window is an advertising popup. 
+  const unsigned long PARENT_IS_LOADING_OR_RUNNING_TIMEOUT = 0x00000001;
+
   /** Create a new window. Gecko will/may call this method, if made
       available to it, to create new windows.
       @param parent Parent window, if any. Null if not. The newly created
                     window should be made a child/dependent window of
                     the parent, if any (and if the concept applies
                     to the underlying OS).
       @param chromeFlags Chrome features from nsIWebBrowserChrome
       @param contextFlags Flags about the context of the window being created.