Merge m-c to m-i

This commit is contained in:
Phil Ringnalda 2013-10-27 19:25:15 -07:00
commit 11e739f7c6
22 changed files with 227 additions and 379 deletions

View File

@ -213,20 +213,12 @@ var gPluginHandler = {
},
handleEvent : function(event) {
let plugin;
let doc;
let eventType = event.type;
if (eventType === "PluginRemoved") {
doc = event.target;
}
else {
plugin = event.target;
doc = plugin.ownerDocument;
let plugin = event.target;
let doc = plugin.ownerDocument;
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
}
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
if (eventType == "PluginBindingAttached") {
// The plugin binding fires this event when it is created.
@ -308,13 +300,12 @@ var gPluginHandler = {
break;
case "PluginInstantiated":
case "PluginRemoved":
shouldShowNotification = true;
break;
}
// Show the in-content UI if it's not too big. The crashed plugin handler already did this.
if (eventType != "PluginCrashed" && eventType != "PluginRemoved") {
if (eventType != "PluginCrashed") {
let overlay = this.getPluginUI(plugin, "main");
if (overlay != null) {
if (!this.isTooSmall(plugin, overlay))
@ -336,7 +327,7 @@ var gPluginHandler = {
// Only show the notification after we've done the isTooSmall check, so
// that the notification can decide whether to show the "alert" icon
if (shouldShowNotification) {
this._showClickToPlayNotification(browser);
this._showClickToPlayNotification(browser, plugin, false);
}
},
@ -562,7 +553,7 @@ var gPluginHandler = {
if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
(aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
aEvent.button == 0 && aEvent.isTrusted) {
gPluginHandler._showClickToPlayNotification(browser, plugin);
gPluginHandler._showClickToPlayNotification(browser, plugin, true);
aEvent.stopPropagation();
aEvent.preventDefault();
}
@ -607,7 +598,7 @@ var gPluginHandler = {
}, true);
if (!playPreviewInfo.ignoreCTP) {
gPluginHandler._showClickToPlayNotification(browser);
gPluginHandler._showClickToPlayNotification(browser, aPlugin, false);
}
},
@ -625,14 +616,20 @@ var gPluginHandler = {
if (gPluginHandler.canActivatePlugin(objLoadingContent))
gPluginHandler._handleClickToPlayEvent(plugin);
}
gPluginHandler._showClickToPlayNotification(browser);
gPluginHandler._showClickToPlayNotification(browser, null, false);
},
_clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
if (event == "showing") {
gPluginHandler._makeCenterActions(this);
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_SHOWN")
.add(!this.options.primaryPlugin);
// Histograms always start at 0, even though our data starts at 1
let histogramCount = this.options.centerActions.size - 1;
if (histogramCount > 4) {
histogramCount = 4;
}
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_PLUGIN_COUNT")
.add(histogramCount);
}
else if (event == "dismissed") {
// Once the popup is dismissed, clicking the icon should show the full
@ -655,86 +652,6 @@ var gPluginHandler = {
return principal.origin;
},
_makeCenterActions: function PH_makeCenterActions(notification) {
let contentWindow = notification.browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let principal = contentWindow.document.nodePrincipal;
// This matches the behavior of nsPermssionManager, used for display purposes only
let principalHost = this._getHostFromPrincipal(principal);
let centerActions = [];
let pluginsFound = new Set();
for (let plugin of cwu.plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (plugin.getContentTypeForMIMEType(plugin.actualType) != Ci.nsIObjectLoadingContent.TYPE_PLUGIN) {
continue;
}
let pluginInfo = this._getPluginInfo(plugin);
if (pluginInfo.permissionString === null) {
Components.utils.reportError("No permission string for active plugin.");
continue;
}
if (pluginsFound.has(pluginInfo.permissionString)) {
continue;
}
pluginsFound.add(pluginInfo.permissionString);
// Add the per-site permissions and details URLs to pluginInfo here
// because they are more expensive to compute and so we avoid it in
// the tighter loop above.
let permissionObj = Services.perms.
getPermissionObject(principal, pluginInfo.permissionString, false);
if (permissionObj) {
pluginInfo.pluginPermissionHost = permissionObj.host;
pluginInfo.pluginPermissionType = permissionObj.expireType;
}
else {
pluginInfo.pluginPermissionHost = principalHost;
pluginInfo.pluginPermissionType = undefined;
}
let url;
// TODO: allow the blocklist to specify a better link, bug 873093
if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
url = Services.urlFormatter.formatURLPref("plugins.update.url");
}
else if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
}
else {
url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "clicktoplay";
}
pluginInfo.detailsLink = url;
centerActions.push(pluginInfo);
}
if (centerActions.length == 0) {
// TODO: this is a temporary band-aid to avoid broken doorhangers
// until bug 926605 is landed.
notification.options.centerActions = [];
setTimeout(() => PopupNotifications.remove(notification), 0);
return;
}
centerActions.sort(function(a, b) {
return a.pluginName.localeCompare(b.pluginName);
});
notification.options.centerActions = centerActions;
// Histograms always start at 0, even though our data starts at 1
let histogramCount = centerActions.length - 1;
if (histogramCount > 4) {
histogramCount = 4;
}
Services.telemetry.getHistogramById("PLUGINS_NOTIFICATION_PLUGIN_COUNT")
.add(histogramCount);
},
/**
* Called from the plugin doorhanger to set the new permissions for a plugin
* and activate plugins if necessary.
@ -798,6 +715,7 @@ var gPluginHandler = {
let plugins = cwu.plugins;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginFound = false;
for (let plugin of plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// canActivatePlugin will return false if this isn't a known plugin type,
@ -809,60 +727,141 @@ var gPluginHandler = {
overlay.removeEventListener("click", gPluginHandler._overlayClickListener, true);
}
plugin.playPlugin();
pluginFound = true;
}
}
// If there are no instances of the plugin on the page any more, what the
// user probably needs is for us to allow and then refresh.
if (!pluginFound) {
browser.reload();
}
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPlugin, aShowNow) {
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let plugins = [];
let contentWindow = aBrowser.contentWindow;
let contentDoc = aBrowser.contentDocument;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// cwu.plugins may contain non-plugin <object>s, filter them out
let plugins = cwu.plugins.filter((plugin) =>
plugin.getContentTypeForMIMEType(plugin.actualType) == Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
if (plugins.length == 0) {
if (notification) {
PopupNotifications.remove(notification);
// if aPlugin is null, that means the user has navigated back to a page with plugins, and we need
// to collect all the plugins
if (aPlugin === null) {
let contentWindow = aBrowser.contentWindow;
let contentDoc = aBrowser.contentDocument;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// cwu.plugins may contain non-plugin <object>s, filter them out
plugins = cwu.plugins.filter((plugin) =>
plugin.getContentTypeForMIMEType(plugin.actualType) == Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
if (plugins.length == 0) {
if (notification) {
PopupNotifications.remove(notification);
}
return;
}
} else {
plugins = [aPlugin];
}
// If this is a new notification, create a centerActions map, otherwise append
let centerActions;
if (notification) {
centerActions = notification.options.centerActions;
} else {
centerActions = new Map();
}
let principal = aBrowser.contentDocument.nodePrincipal;
let principalHost = this._getHostFromPrincipal(principal);
for (var plugin of plugins) {
let pluginInfo = this._getPluginInfo(plugin);
if (pluginInfo.permissionString === null) {
Cu.reportError("No permission string for active plugin.");
continue;
}
if (centerActions.has(pluginInfo.permissionString)) {
continue;
}
// Assume that plugins are hidden and then set override later
pluginInfo.hidden = true;
let overlay = this.getPluginUI(plugin, "main");
if (overlay && overlay.style.visibility != "hidden" && overlay.style.visibility != "") {
pluginInfo.hidden = false;
}
let permissionObj = Services.perms.
getPermissionObject(principal, pluginInfo.permissionString, false);
if (permissionObj) {
pluginInfo.pluginPermissionHost = permissionObj.host;
pluginInfo.pluginPermissionType = permissionObj.expireType;
}
else {
pluginInfo.pluginPermissionHost = principalHost;
pluginInfo.pluginPermissionType = undefined;
}
let url;
// TODO: allow the blocklist to specify a better link, bug 873093
if (pluginInfo.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
url = Services.urlFormatter.formatURLPref("plugins.update.url");
}
else if (pluginInfo.blocklistState != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
url = Services.blocklist.getPluginBlocklistURL(pluginInfo.pluginTag);
}
else {
url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "clicktoplay";
}
pluginInfo.detailsLink = url;
centerActions.set(pluginInfo.permissionString, pluginInfo);
}
let pluginBlocked = false;
let pluginHidden = false;
for (let pluginInfo of centerActions.values()) {
let fallbackType = pluginInfo.fallbackType;
if (fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE ||
fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE ||
fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED) {
pluginBlocked = true;
pluginHidden = false;
break;
}
if (fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY && pluginInfo.hidden) {
pluginHidden = true;
}
}
let iconClasses = document.getElementById("plugins-notification-icon").classList;
iconClasses.toggle("plugin-blocked", pluginBlocked);
iconClasses.toggle("plugin-hidden", pluginHidden);
let primaryPluginPermission = null;
if (aShowNow) {
primaryPluginPermission = this._getPluginInfo(aPlugin).permissionString;
}
if (notification) {
// Don't modify the notification UI while it's on the screen, that would be
// jumpy and might allow clickjacking.
if (aShowNow) {
notification.options.primaryPlugin = primaryPluginPermission;
notification.reshow();
}
return;
}
let icon = 'plugins-notification-icon';
for (let plugin of plugins) {
let fallbackType = plugin.pluginFallbackType;
if (fallbackType == plugin.PLUGIN_VULNERABLE_UPDATABLE ||
fallbackType == plugin.PLUGIN_VULNERABLE_NO_UPDATE ||
fallbackType == plugin.PLUGIN_BLOCKLISTED) {
icon = 'blocked-plugins-notification-icon';
break;
}
if (fallbackType == plugin.PLUGIN_CLICK_TO_PLAY) {
let overlay = this.getPluginUI(plugin, "main");
if (!overlay || overlay.style.visibility == 'hidden') {
icon = 'alert-plugins-notification-icon';
}
}
}
let dismissed = notification ? notification.dismissed : true;
if (aPrimaryPlugin)
dismissed = false;
let primaryPluginPermission = null;
if (aPrimaryPlugin) {
primaryPluginPermission = this._getPluginInfo(aPrimaryPlugin).permissionString;
}
let options = {
dismissed: dismissed,
dismissed: !aShowNow,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission
primaryPlugin: primaryPluginPermission,
centerActions: centerActions
};
PopupNotifications.show(aBrowser, "click-to-play-plugins",
"", icon,
"", "plugins-notification-icon",
null, null, options);
},

View File

@ -756,7 +756,6 @@ var gBrowserInit = {
gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
gBrowser.addEventListener("PluginInstantiated", gPluginHandler, true);
gBrowser.addEventListener("PluginRemoved", gPluginHandler, true);
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);

View File

@ -534,8 +534,6 @@
<image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="alert-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="blocked-plugins-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="plugin-install-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
<image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>

View File

@ -1277,7 +1277,7 @@ nsContextMenu.prototype = {
},
playPlugin: function() {
gPluginHandler._showClickToPlayNotification(this.browser, this.target);
gPluginHandler._showClickToPlayNotification(this.browser, this.target, true);
},
hidePlugin: function() {

View File

@ -60,7 +60,6 @@ support-files =
plugin_clickToPlayDeny.html
plugin_data_url.html
plugin_hidden_to_visible.html
plugin_iframe.html
plugin_small.html
plugin_test.html
plugin_test2.html
@ -87,7 +86,6 @@ support-files =
[browser_CTP_data_urls.js]
[browser_CTP_drag_drop.js]
[browser_CTP_iframe.js]
[browser_CTP_nonplugins.js]
[browser_CTP_resize.js]
[browser_URLBarSetURI.js]

View File

@ -71,32 +71,43 @@ function test1() {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 1, Plugin should not be activated");
window.document.addEventListener("popupshown", test2, false);
// When the popupshown DOM event is fired, the actual showing of the popup
// may still be pending. Clear the event loop before continuing so that
// subsequently-opened popups aren't cancelled by accident.
let goToNext = function() {
window.document.removeEventListener("popupshown", goToNext, false);
executeSoon(test2);
};
window.document.addEventListener("popupshown", goToNext, false);
EventUtils.synthesizeMouseAtCenter(plugin,
{ type: "contextmenu", button: 2 },
gTestBrowser.contentWindow);
}
function test2() {
window.document.removeEventListener("popupshown", test2, false);
let activate = window.document.getElementById("context-ctp-play");
ok(activate, "Test 2, Should have a context menu entry for activating the plugin");
let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 2, Should have a click-to-play notification");
ok(notification.dismissed, "Test 2, notification should be dismissed");
// Trigger the click-to-play popup
activate.doCommand();
let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 2, Should have a click-to-play notification");
ok(!notification.dismissed, "Test 2, The click-to-play notification should not be dismissed");
waitForCondition(() => !notification.dismissed,
test3, "Test 2, waited too long for context activation");
}
function test3() {
// Activate the plugin
PopupNotifications.panel.firstChild._primaryButton.click();
let plugin = gTestBrowser.contentDocument.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
waitForCondition(() => objLoadingContent.activated, test3, "Waited too long for plugin to activate");
waitForCondition(() => objLoadingContent.activated, test4, "Waited too long for plugin to activate");
}
function test3() {
function test4() {
finishTest();
}

View File

@ -161,10 +161,10 @@ function test2b() {
// Simulate choosing "Allow now" for the test plugin
notification.reshow();
is(notification.options.centerActions.length, 2, "Test 2b, Should have two types of plugin in the notification");
is(notification.options.centerActions.size, 2, "Test 2b, Should have two types of plugin in the notification");
var centerAction = null;
for (var action of notification.options.centerActions) {
for (var action of notification.options.centerActions.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;

View File

@ -64,13 +64,11 @@ function part5() {
gBrowser.selectedBrowser.removeEventListener("PluginBindingAttached", handleEvent);
ok(PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should have a click-to-play notification in the initial tab");
gNextTest = part6;
gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
gNewWindow.addEventListener("load", handleEvent, true);
waitForFocus(part6, gNewWindow);
}
function part6() {
gNewWindow.removeEventListener("load", handleEvent);
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
waitForCondition(condition, part7, "Waited too long for click-to-play notification");
}

View File

@ -1,135 +0,0 @@
var rootDir = getRootDirectory(gTestPath);
const gTestRoot = rootDir;
const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
var gTestBrowser = null;
var gNextTest = null;
var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
var gPageLoads = 0;
Components.utils.import("resource://gre/modules/Services.jsm");
// This listens for the next opened tab and checks it is of the right url.
// opencallback is called when the new tab is fully loaded
// closecallback is called when the tab is closed
function TabOpenListener(url, opencallback, closecallback) {
this.url = url;
this.opencallback = opencallback;
this.closecallback = closecallback;
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
}
TabOpenListener.prototype = {
url: null,
opencallback: null,
closecallback: null,
tab: null,
browser: null,
handleEvent: function(event) {
if (event.type == "TabOpen") {
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
this.tab = event.originalTarget;
this.browser = this.tab.linkedBrowser;
gBrowser.addEventListener("pageshow", this, false);
} else if (event.type == "pageshow") {
if (event.target.location.href != this.url)
return;
gBrowser.removeEventListener("pageshow", this, false);
this.tab.addEventListener("TabClose", this, false);
var url = this.browser.contentDocument.location.href;
is(url, this.url, "Should have opened the correct tab");
this.opencallback(this.tab, this.browser.contentWindow);
} else if (event.type == "TabClose") {
if (event.originalTarget != this.tab)
return;
this.tab.removeEventListener("TabClose", this, false);
this.opencallback = null;
this.tab = null;
this.browser = null;
// Let the window close complete
executeSoon(this.closecallback);
this.closecallback = null;
}
}
};
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
clearAllPluginPermissions();
Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
});
Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
var newTab = gBrowser.addTab();
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
Services.prefs.setBoolPref("plugins.click_to_play", true);
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_iframe.html");
}
function finishTest() {
clearAllPluginPermissions();
gTestBrowser.removeEventListener("load", pageLoad, true);
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function pageLoad() {
// Wait for the iframe to be loaded as well.
if (gPageLoads++ < 1)
return;
// The plugin events are async dispatched and can come after the load event
// This just allows the events to fire before we then go on to test the states.
executeSoon(gNextTest);
}
function prepareTest(nextTest, url) {
gNextTest = nextTest;
gTestBrowser.contentWindow.location = url;
}
// Due to layout being async, "PluginBindAttached" may trigger later.
// This wraps a function to force a layout flush, thus triggering it,
// and schedules the function execution so they're definitely executed
// afterwards.
function runAfterPluginBindingAttached(func) {
return function() {
let doc = gTestBrowser.contentDocument.getElementById('frame').contentDocument;
let elems = doc.getElementsByTagName('embed');
if (elems.length < 1) {
elems = doc.getElementsByTagName('object');
}
elems[0].clientTop;
executeSoon(func);
};
}
// Test that we don't show a doorhanger after removing the last plugin
// when the plugin was in an iframe.
function test1() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 1, Should have a click-to-play notification");
let frame = gTestBrowser.contentDocument.getElementById("frame");
frame.parentElement.removeChild(frame);
let condition = () => {
let notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
if (notification) {
notification.reshow();
}
return !notification;
}
waitForCondition(condition, finishTest, "Test1, Waited too long for notification too be removed");
}

View File

@ -149,12 +149,12 @@ function test2() {
let plugin = gTestBrowser.contentDocument.getElementById("test");
plugin.parentNode.removeChild(plugin);
runAfterPluginRemoved(() => executeSoon(test3));
executeSoon(test3);
}
function test3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 3, Should not have a click-to-play notification");
ok(popupNotification, "Test 3, Should still have a click-to-play notification");
finishTest();
}

View File

@ -40,7 +40,7 @@ function pluginBindingAttached() {
ok(notification, "should have popup notification");
// We don't set up the action list until the notification is shown
notification.reshow();
is(notification.options.centerActions.length, 1, "should be 1 type of plugin in the popup notification");
is(notification.options.centerActions.size, 1, "should be 1 type of plugin in the popup notification");
XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addSecondPlugin();
} else if (gNumPluginBindingsAttached == 2) {
var doc = gTestBrowser.contentDocument;
@ -51,7 +51,7 @@ function pluginBindingAttached() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have popup notification");
notification.reshow();
is(notification.options.centerActions.length, 2, "should be 2 types of plugin in the popup notification");
is(notification.options.centerActions.size, 2, "should be 2 types of plugin in the popup notification");
finish();
} else {
ok(false, "if we've gotten here, something is quite wrong");

View File

@ -179,7 +179,7 @@ function test5() {
ok(notification.dismissed, "Test 5: The plugin notification should be dismissed by default");
notification.reshow();
is(notification.options.centerActions.length, 1, "Test 5: Only the blocked plugin should be present in the notification");
is(notification.options.centerActions.size, 1, "Test 5: Only the blocked plugin should be present in the notification");
ok(PopupNotifications.panel.firstChild._buttonContainer.hidden, "Part 5: The blocked plugins notification should not have any buttons visible.");
ok(!gTestBrowser.missingPlugins, "Test 5, Should not be a missing plugin list");
@ -441,10 +441,11 @@ function test18f() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 18f, Plugin should not be activated");
// XXXBAD: this code doesn't do what you think it does! it is actually
// observing the "removed" event of the old notification, since we create
// a *new* one when the plugin is clicked.
notification.options.eventCallback = function() { executeSoon(test18g); };
var oldEventCallback = notification.options.eventCallback;
notification.options.eventCallback = function() {
oldEventCallback();
executeSoon(test18g);
};
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
}
@ -603,10 +604,10 @@ function test21a() {
// we have to actually show the panel to get the bindings to instantiate
notification.reshow();
is(notification.options.centerActions.length, 2, "Test 21a, Should have two types of plugin in the notification");
is(notification.options.centerActions.size, 2, "Test 21a, Should have two types of plugin in the notification");
var centerAction = null;
for (var action of notification.options.centerActions) {
for (var action of notification.options.centerActions.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;
@ -640,7 +641,7 @@ function test21c() {
ok(notification, "Test 21c, Should have a click-to-play notification");
notification.reshow();
ok(notification.options.centerActions.length == 2, "Test 21c, Should have one type of plugin in the notification");
ok(notification.options.centerActions.size == 2, "Test 21c, Should have one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
@ -661,7 +662,7 @@ function test21c() {
}
var centerAction = null;
for (var action of notification.options.centerActions) {
for (var action of notification.options.centerActions.values()) {
if (action.pluginName == "Second Test") {
centerAction = action;
break;

View File

@ -68,7 +68,7 @@ function testActivateAddSameTypePart2() {
function testActivateAddSameTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
let centerAction = null;
for (let action of popupNotification.options.centerActions) {
for (let action of popupNotification.options.centerActions.values()) {
if (action.pluginName == "Test") {
centerAction = action;
break;
@ -142,7 +142,7 @@ function testActivateAddDifferentTypePart2() {
function testActivateAddDifferentTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
is(popupNotification.options.centerActions.length, 1, "Should be one plugin action");
is(popupNotification.options.centerActions.size, 1, "Should be one plugin action");
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
ok(!plugin.activated, "testActivateAddDifferentTypePart3: plugin should not be activated");

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<iframe src="plugin_test.html" id="frame" width="300" height="300">
This should load plugin_test.html
</iframe>
</body>
</html>

View File

@ -1567,14 +1567,20 @@
<field name="_items">[]</field>
<constructor><![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
for (let action of this.notification.options.centerActions) {
let sortedActions = [];
for (let action of this.notification.options.centerActions.values()) {
sortedActions.push(action);
}
sortedActions.sort((a, b) => a.pluginName.localeCompare(b.pluginName));
for (let action of sortedActions) {
let item = document.createElementNS(XUL_NS, "row");
item.setAttribute("class", "plugin-popupnotification-centeritem");
item.action = action;
this.appendChild(item);
this._items.push(item);
}
switch (this.notification.options.centerActions.length) {
switch (this._items.length) {
case 0:
PopupNotifications._dismiss();
break;
@ -1639,7 +1645,7 @@
</method>
<method name="_setupSingleState">
<body><![CDATA[
var action = this.notification.options.centerActions[0];
var action = this._items[0].action;
var host = action.pluginPermissionHost;
let label, linkLabel, linkUrl, button1, button2;
@ -1803,7 +1809,7 @@
<method name="_singleActivateNow">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
this._items[0].action,
"allownow");
this._cancel();
]]></body>
@ -1811,7 +1817,7 @@
<method name="_singleBlock">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
this._items[0].action,
"block");
this._cancel();
]]></body>
@ -1819,7 +1825,7 @@
<method name="_singleActivateAlways">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
this._items[0].action,
"allowalways");
this._cancel();
]]></body>
@ -1827,7 +1833,7 @@
<method name="_singleContinue">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
this._items[0].action,
"continue");
this._cancel();
]]></body>

View File

@ -1296,30 +1296,22 @@ toolbar[iconsize="small"] #webrtc-status-button {
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#alert-plugins-notification-icon {
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#blocked-plugins-notification-icon {
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon,
#alert-plugins-notification-icon,
#blocked-plugins-notification-icon {
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover,
#alert-plugins-notification-icon:hover,
#blocked-plugins-notification-icon:hover {
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active,
#alert-plugins-notification-icon:active,
#blocked-plugins-notification-icon:active {
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
@ -1334,7 +1326,7 @@ toolbar[iconsize="small"] #webrtc-status-button {
visibility: collapse;
}
#blocked-plugins-notification-icon[showing] {
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}

View File

@ -24,8 +24,11 @@
-moz-border-end: 1px solid #222426; /* Match the sources list's dark margin. */
}
#sources-toolbar .devtools-toolbarbutton {
min-width: 32px;
}
#pretty-print {
min-width: 0;
font-weight: bold;
}

View File

@ -3207,29 +3207,23 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#alert-plugins-notification-icon {
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#blocked-plugins-notification-icon {
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon,
#alert-plugins-notification-icon,
#blocked-plugins-notification-icon {
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover,
#alert-plugins-notification-icon:hover,
#blocked-plugins-notification-icon:hover {
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active,
#alert-plugins-notification-icon:active,
#blocked-plugins-notification-icon:active {
#plugins-notification-icon:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
@ -3238,29 +3232,23 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://browser/skin/notification-pluginNormal@2x.png);
}
#alert-plugins-notification-icon {
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert@2x.png);
}
#blocked-plugins-notification-icon {
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked@2x.png);
}
#plugins-notification-icon,
#alert-plugins-notification-icon,
#blocked-plugins-notification-icon {
#plugins-notification-icon {
-moz-image-region: rect(0, 32px, 32px, 0);
}
#plugins-notification-icon:hover,
#alert-plugins-notification-icon:hover,
#blocked-plugins-notification-icon:hover {
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 64px, 32px, 32px);
}
#plugins-notification-icon:active,
#alert-plugins-notification-icon:active,
#blocked-plugins-notification-icon:active {
#plugins-notification-icon:active {
-moz-image-region: rect(0, 96px, 32px, 64px);
}
}
@ -3281,7 +3269,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
visibility: collapse;
}
#blocked-plugins-notification-icon[showing] {
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}

View File

@ -26,8 +26,11 @@
-moz-border-end: 1px solid #222426; /* Match the sources list's dark margin. */
}
#sources-toolbar .devtools-toolbarbutton {
min-width: 32px;
}
#pretty-print {
min-width: 0;
font-weight: bold;
}

View File

@ -2568,30 +2568,23 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
#plugins-notification-icon {
list-style-image: url(chrome://browser/skin/notification-pluginNormal.png);
}
#alert-plugins-notification-icon {
#plugins-notification-icon.plugin-hidden {
list-style-image: url(chrome://browser/skin/notification-pluginAlert.png);
}
#blocked-plugins-notification-icon {
#plugins-notification-icon.plugin-blocked {
list-style-image: url(chrome://browser/skin/notification-pluginBlocked.png);
}
#plugins-notification-icon,
#alert-plugins-notification-icon,
#blocked-plugins-notification-icon {
#plugins-notification-icon {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#plugins-notification-icon:hover,
#alert-plugins-notification-icon:hover,
#blocked-plugins-notification-icon:hover {
#plugins-notification-icon:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
#plugins-notification-icon:active,
#alert-plugins-notification-icon:active,
#blocked-plugins-notification-icon:active {
#plugins-notification-icon {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
@ -2606,7 +2599,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
visibility: collapse;
}
#blocked-plugins-notification-icon[showing] {
#plugins-notification-icon.plugin-blocked[showing] {
animation: pluginBlockedNotification 500ms ease 0s 5 alternate both;
}

View File

@ -24,8 +24,11 @@
-moz-border-end: 1px solid #222426; /* Match the sources list's dark margin. */
}
#sources-toolbar .devtools-toolbarbutton {
min-width: 32px;
}
#pretty-print {
min-width: 0;
font-weight: bold;
}

View File

@ -47,7 +47,9 @@
['build_with_mozilla==1', {
'include_dirs': [
'$(DIST)/include',
'$(DIST)/include/nspr',
],
'cflags_mozilla': [
'$(NSPR_CFLAGS)',
],
}],
['OS=="linux" or include_alsa_audio==1 or include_pulse_audio==1', {