Bug 1405655 - Only hide Flash Activation overlay UI if the entire plugin is covered. r=dothayer draft
authorFelipe Gomes <felipc@gmail.com>
Fri, 13 Oct 2017 22:12:24 -0300
changeset 680411 44c00191a4ce5b98f6f906a280ec70c21eae7fd9
parent 678653 5cc87630fff42a8cb272ec58c530ef68007ecacd
child 735854 7cd56ad094f84809fc25b0b4150cb2dcf6d182b5
push id84502
push userfelipc@gmail.com
push dateSat, 14 Oct 2017 01:13:08 +0000
reviewersdothayer
bugs1405655
milestone58.0a1
Bug 1405655 - Only hide Flash Activation overlay UI if the entire plugin is covered. r=dothayer As opposed to right now where we hide if any of the corners or the center of the plugin is covered. MozReview-Commit-ID: 8Nkt55ncBS4
browser/base/content/test/plugins/browser.ini
browser/base/content/test/plugins/browser_CTP_shouldShowOverlay.js
browser/base/content/test/plugins/plugin_shouldShowOverlay.html
browser/modules/PluginContent.jsm
--- a/browser/base/content/test/plugins/browser.ini
+++ b/browser/base/content/test/plugins/browser.ini
@@ -24,16 +24,17 @@ support-files =
   plugin_clickToPlayDeny.html
   plugin_favorfallback.html
   plugin_hidden_to_visible.html
   plugin_iframe.html
   plugin_outsideScrollArea.html
   plugin_overlayed.html
   plugin_positioned.html
   plugin_simple_blank.swf
+  plugin_shouldShowOverlay.html
   plugin_small.html
   plugin_small_2.html
   plugin_syncRemoved.html
   plugin_test.html
   plugin_test2.html
   plugin_test3.html
   plugin_two_types.html
   plugin_unknown.html
@@ -71,16 +72,17 @@ tags = blocklist
 [browser_CTP_notificationBar.js]
 tags = blocklist
 [browser_CTP_outsideScrollArea.js]
 tags = blocklist
 [browser_CTP_remove_navigate.js]
 tags = blocklist
 [browser_CTP_resize.js]
 tags = blocklist
+[browser_CTP_shouldShowOverlay.js]
 [browser_CTP_zoom.js]
 tags = blocklist
 [browser_blocking.js]
 tags = blocklist
 [browser_iterate_hidden_plugins.js]
 [browser_plugins_added_dynamically.js]
 tags = blocklist
 [browser_pluginnotification.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/browser_CTP_shouldShowOverlay.js
@@ -0,0 +1,47 @@
+"use strict";
+
+var rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
+
+var gTestBrowser = null;
+
+add_task(async function() {
+  registerCleanupFunction(function() {
+    clearAllPluginPermissions();
+    setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
+    gBrowser.removeCurrentTab();
+    gTestBrowser = null;
+  });
+});
+
+add_task(async function() {
+  gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
+  gTestBrowser = gBrowser.selectedBrowser;
+
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY, "Test Plug-in");
+
+  let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  ok(!popupNotification, "Sanity check, should not have a click-to-play notification");
+
+  await promiseTabLoadEvent(gBrowser.selectedTab, gTestRoot + "plugin_shouldShowOverlay.html");
+
+  // Work around for delayed PluginBindingAttached
+  await promiseUpdatePluginBindings(gTestBrowser);
+
+  await ContentTask.spawn(gTestBrowser, null, async function() {
+    let doc = content.document;
+    let testcases = doc.querySelectorAll(".testcase");
+
+    for (let testcase of testcases) {
+      let plugin = testcase.querySelector("object");
+      Assert.ok(plugin, `plugin exists in ${testcase.id}`);
+
+      let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+      Assert.ok(overlay, `overlay exists in ${testcase.id}`);
+
+      let expectedVisibility = (testcase.getAttribute("shouldshow") == "true");
+      Assert.ok(overlay.classList.contains("visible") == expectedVisibility,
+                `The expected visibility is correct in ${testcase.id}`);
+    }
+  })
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/plugin_shouldShowOverlay.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+object {
+	width: 200px;
+	height: 200px;
+}
+
+.testcase {
+	position: relative;
+	margin-bottom: 5px;
+}
+
+.cover {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	background-color: green;
+}
+</style>
+</head>
+<body>
+
+  <div id="testcase1" class="testcase" shouldshow="true"
+       style="top: -100px">
+    <!-- Should show overlay even though the top part is outside
+    	 of the page. -->
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase2" class="testcase" shouldshow="true"
+       style="left: -100px">
+    <!-- Should show overlay even though the left part is outside
+    	 of the page. -->
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase3" class="testcase" shouldshow="false"
+       style="left: -210px">
+    <!-- The object is entirely outside of the page, so the overlay
+         should NOT show. -->
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase4" class="testcase" shouldshow="true">
+    <!-- Should show overlay even though the top-left corner is covered. -->
+    <div class="cover" style="top: 0; left: 0"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase5" class="testcase" shouldshow="true">
+  	<!-- Should show overlay even though the top-right corner is covered. -->
+    <div class="cover" style="top: 0; left: 180px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase6" class="testcase" shouldshow="true">
+  	<!-- Should show overlay even though the bottom-left corner is covered. -->
+    <div class="cover" style="top: 180px; left: 0"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+
+  <div id="testcase7" class="testcase" shouldshow="true">
+  	<!-- Should show overlay even though the bottom-right corner is covered. -->
+    <div class="cover" style="top: 180px; left: 180px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase8" class="testcase" shouldshow="true">
+  	<!-- Should show overlay even though the center is covered. -->
+  	<div class="cover" style="top: 90px; left: 90px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase9" class="testcase" shouldshow="true">
+  	<!-- Should show overlay even though multiple points are covered,
+  		 but not all of them. -->
+  	<div class="cover" style="top: 0; left: 0"></div>
+  	<div class="cover" style="top: 0; left: 180px"></div>
+  	<div class="cover" style="top: 180px; left: 0"></div>
+    <div class="cover" style="top: 180px; left: 180px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase10" class="testcase" shouldshow="true">
+  	<!-- Another case where 4 are covered, but not all. -->
+  	<div class="cover" style="top: 90px; left: 90px"></div>
+  	<div class="cover" style="top: 0; left: 180px"></div>
+  	<div class="cover" style="top: 180px; left: 0"></div>
+    <div class="cover" style="top: 180px; left: 180px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase11" class="testcase" shouldshow="false">
+  	<!-- All corners and center are covered here, so in this
+  	     case the overlay should NOT show. -->
+  	<div class="cover" style="top: 0; left: 0"></div>
+  	<div class="cover" style="top: 0; left: 180px"></div>
+  	<div class="cover" style="top: 180px; left: 0"></div>
+    <div class="cover" style="top: 180px; left: 180px"></div>
+    <div class="cover" style="top: 90px; left: 90px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+  <div id="testcase12" class="testcase" shouldshow="false">
+  	  	<!-- All corners and center are covered here, by a single
+  	  	element. In this case the overlay should NOT show. -->
+    <div class="cover" style="width: 200px; height:200px"></div>
+    <object type="application/x-test"></object>
+  </div>
+
+</body>
+</html>
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -325,32 +325,31 @@ PluginContent.prototype = {
     let centerX = left + (right - left) / 2;
     let centerY = top + (bottom - top) / 2;
     let points = [[left, top],
                    [left, bottom],
                    [right, top],
                    [right, bottom],
                    [centerX, centerY]];
 
-    if (right <= 0 || top <= 0) {
-      return false;
-    }
-
     let contentWindow = plugin.ownerGlobal;
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
 
     for (let [x, y] of points) {
+      if (x < 0 || y < 0) {
+        continue;
+      }
       let el = cwu.elementFromPoint(x, y, true, true);
-      if (el !== plugin) {
-        return false;
+      if (el === plugin) {
+        return true;
       }
     }
 
-    return true;
+    return false;
   },
 
   addLinkClickCallback(linkNode, callbackName /* callbackArgs...*/) {
     // XXX just doing (callback)(arg) was giving a same-origin error. bug?
     let self = this;
     let callbackArgs = Array.prototype.slice.call(arguments).slice(2);
     linkNode.addEventListener("click",
                               function(evt) {