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: 9mOVXYyV1Il
--- 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,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/* This test ensures that the click-to-play "Activate Plugin" overlay
+ * is shown when expected.
+ * All testcases are in the plugin_shouldShowOverlay.html file.
+ */
+
+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) {