Bug 754472 - Implement multiple plugin click-to-play UI. r=jaws r=margaret r=dietrich

This commit is contained in:
David Keeler 2012-08-28 09:23:10 -07:00
parent a99f377d4a
commit 14ceb60a79
25 changed files with 612 additions and 41 deletions

View File

@ -7,6 +7,7 @@ function getPluginInfo(pluginElement)
{
var tagMimetype;
var pluginsPage;
var pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
if (pluginElement instanceof HTMLAppletElement) {
tagMimetype = "application/x-java-vm";
} else {
@ -35,7 +36,17 @@ function getPluginInfo(pluginElement)
}
}
return {mimetype: tagMimetype, pluginsPage: pluginsPage};
if (tagMimetype) {
let navMimeType = navigator.mimeTypes[tagMimetype];
if (navMimeType && navMimeType.enabledPlugin) {
pluginName = navMimeType.enabledPlugin.name;
pluginName = gPluginHandler.makeNicePluginName(pluginName);
}
}
return { mimetype: tagMimetype,
pluginsPage: pluginsPage,
pluginName: pluginName };
}
var gPluginHandler = {
@ -49,13 +60,16 @@ var gPluginHandler = {
#endif
// Map the plugin's name to a filtered version more suitable for user UI.
makeNicePluginName : function (aName, aFilename) {
makeNicePluginName : function (aName) {
if (aName == "Shockwave Flash")
return "Adobe Flash";
// Clean up the plugin name by stripping off any trailing version numbers
// or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar"
let newName = aName.replace(/\bplug-?in\b/i, "").replace(/[\s\d\.\-\_\(\)]+$/, "");
// Do this by first stripping the numbers, etc. off the end, and then
// removing "Plugin" (and then trimming to get rid of any whitespace).
// (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled)
let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim();
return newName;
},
@ -148,6 +162,17 @@ var gPluginHandler = {
case "PluginVulnerableNoUpdate":
case "PluginClickToPlay":
self._handleClickToPlayEvent(plugin);
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let pluginName = getPluginInfo(plugin).pluginName;
let messageString = gNavigatorBundle.getFormattedString("PluginClickToPlay", [pluginName]);
let overlayText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
overlayText.textContent = messageString;
if (event.type == "PluginVulnerableUpdatable" ||
event.type == "PluginVulnerableNoUpdate") {
let vulnerabilityString = gNavigatorBundle.getString(event.type);
let vulnerabilityText = doc.getAnonymousElementByAttribute(plugin, "anonid", "vulnerabilityStatus");
vulnerabilityText.textContent = vulnerabilityString;
}
break;
case "PluginPlayPreview":
@ -197,16 +222,16 @@ var gPluginHandler = {
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let haveUnplayedPlugins = cwu.plugins.some(function(plugin) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
return (plugin != aPlugin && gPluginHandler.canActivatePlugin(objLoadingContent));
});
let pluginNeedsActivation = gPluginHandler._pluginNeedsActivationExceptThese([aPlugin]);
let browser = gBrowser.getBrowserForDocument(aContentWindow.document);
let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
if (notification && !haveUnplayedPlugins) {
if (notification) {
browser._clickToPlayDoorhangerShown = false;
notification.remove();
}
if (pluginNeedsActivation) {
gPluginHandler._showClickToPlayNotification(browser);
}
},
stopPlayPreview: function PH_stopPlayPreview(aPlugin, aPlayPlugin) {
@ -360,17 +385,78 @@ var gPluginHandler = {
if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION)
return;
let contentWindow = browser.contentWindow;
if (gPluginHandler._pluginNeedsActivationExceptThese([]))
gPluginHandler._showClickToPlayNotification(browser);
},
// returns true if there is a plugin on this page that needs activation
// and isn't in the "except these" list
_pluginNeedsActivationExceptThese: function PH_pluginNeedsActivationExceptThese(aExceptThese) {
let contentWindow = gBrowser.selectedBrowser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let pluginNeedsActivation = cwu.plugins.some(function(plugin) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
return gPluginHandler.canActivatePlugin(objLoadingContent);
return (gPluginHandler.canActivatePlugin(objLoadingContent) &&
aExceptThese.indexOf(plugin) < 0);
});
if (pluginNeedsActivation)
gPluginHandler._showClickToPlayNotification(browser);
return pluginNeedsActivation;
},
/* Gets all plugins currently in the page of the given name */
_getPluginsByName: function PH_getPluginsByName(aDOMWindowUtils, aName) {
let plugins = [];
for (let plugin of aDOMWindowUtils.plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let pluginName = getPluginInfo(plugin).pluginName;
if (aName == pluginName) {
plugins.push(objLoadingContent);
}
}
}
return plugins;
},
_makeCenterActions: function PH_makeCenterActions(aBrowser) {
let contentWindow = aBrowser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let pluginsDictionary = {};
for (let plugin of cwu.plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let pluginName = getPluginInfo(plugin).pluginName;
if (!pluginsDictionary[pluginName]) pluginsDictionary[pluginName] = [];
pluginsDictionary[pluginName].push(objLoadingContent);
}
}
let centerActions = [];
for (let pluginName in pluginsDictionary) {
let action = {
message: pluginName,
label: gNavigatorBundle.getString("activateSinglePlugin"),
callback: function() {
let plugins = gPluginHandler._getPluginsByName(cwu, this.message);
for (let objLoadingContent of plugins) {
objLoadingContent.playPlugin();
}
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
if (notification &&
!gPluginHandler._pluginNeedsActivationExceptThese(plugins)) {
notification.remove();
}
}
};
centerActions.push(action);
}
return centerActions;
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser) {
aBrowser._clickToPlayDoorhangerShown = true;
let contentWindow = aBrowser.contentWindow;
@ -381,6 +467,7 @@ var gPluginHandler = {
accessKey: gNavigatorBundle.getString("activatePluginsMessage.accesskey"),
callback: function() { gPluginHandler.activatePlugins(contentWindow); }
};
let centerActions = gPluginHandler._makeCenterActions(aBrowser);
let secondaryActions = [{
label: gNavigatorBundle.getString("activatePluginsMessage.always"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.always.accesskey"),
@ -399,7 +486,7 @@ var gPluginHandler = {
gPluginHandler._removeClickToPlayOverlays(contentWindow);
}
}];
let options = { dismissed: true };
let options = { dismissed: true, centerActions: centerActions };
PopupNotifications.show(aBrowser, "click-to-play-plugins",
messageString, "plugins-notification-icon",
mainAction, secondaryActions, options);
@ -620,12 +707,11 @@ var gPluginHandler = {
let doPrompt = true; // XXX followup for .getData("doPrompt");
let submitReports = true; // XXX followup for .getData("submitReports");
let pluginName = aEvent.getData("pluginName");
let pluginFilename = aEvent.getData("pluginFilename");
let pluginDumpID = aEvent.getData("pluginDumpID");
let browserDumpID = aEvent.getData("browserDumpID");
// Remap the plugin name to a more user-presentable form.
pluginName = this.makeNicePluginName(pluginName, pluginFilename);
pluginName = this.makeNicePluginName(pluginName);
let messageString = gNavigatorBundle.getFormattedString("crashedpluginsMessage.title", [pluginName]);

View File

@ -490,6 +490,14 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#identity-request-notification");
}
#click-to-play-plugins-notification {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
}
popupnotification-centeritem {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#center-item");
}
/* override hidden="true" for the status bar compatibility shim
in case it was persisted for the real status bar */
#status-bar {

View File

@ -236,6 +236,7 @@ _BROWSER_FILES = \
plugin_clickToPlayDeny.html \
plugin_bug749455.html \
plugin_hidden_to_visible.html \
plugin_two_types.html \
alltabslistener.html \
zoom_test.html \
dummy_page.html \

View File

@ -223,7 +223,9 @@ function test9a() {
ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9a, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9a, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 9a, Should not be a missing plugin list");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9a, Should have a click-to-play notification");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 9a, Should have a click-to-play notification");
ok(notification.options.centerActions.length == 1, "Test 9a, Should have only one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin1 = doc.getElementById("test1");
@ -252,7 +254,9 @@ function test9b() {
ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9b, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9b, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 9b, Should not be a missing plugin list");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9b, Click to play notification should not be removed now");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 9b, Click to play notification should not be removed now");
ok(notification.options.centerActions.length == 1, "Test 9b, Should have only one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin1 = doc.getElementById("test1");
@ -774,5 +778,138 @@ function test20c() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 20c, plugin should be activated");
prepareTest(test21a, gTestRoot + "plugin_two_types.html");
}
// Test having multiple different types of plugin on one page
function test21a() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 21a, Should have a click-to-play notification");
ok(notification.options.centerActions.length == 2, "Test 21a, Should have two types of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var ids = ["test", "secondtestA", "secondtestB"];
for (var id of ids) {
var plugin = doc.getElementById(id);
var rect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 200, "Test 21a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being clicked");
ok(rect.height == 200, "Test 21a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being clicked");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 21a, Plugin with id=" + plugin.id + " should not be activated");
}
// we have to actually show the panel to get the bindings to instantiate
notification.options.dismissed = false;
notification.options.eventCallback = test21b;
PopupNotifications._showPanel([notification], notification.anchorElement);
}
function test21b() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
notification.options.eventCallback = null;
var centerAction = null;
for (var action of notification.options.centerActions) {
if (action.message == "Test") {
centerAction = action;
break;
}
}
ok(centerAction, "Test 21b, found center action for the Test plugin");
var centerItem = null;
for (var item of centerAction.popupnotification.childNodes) {
if (item.action == centerAction) {
centerItem = item;
break;
}
}
ok(centerItem, "Test 21b, found center item for the Test plugin");
// "click" the button to activate the Test plugin
centerItem.runCallback.apply(centerItem);
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test21c, "Test 21b, Waited too long for plugin to activate");
}
function test21c() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 21c, Should have a click-to-play notification");
ok(notification.options.centerActions.length == 1, "Test 21c, Should have one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var rect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 0, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 0px width after being clicked");
ok(rect.height == 0, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 0px height after being clicked");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 21c, Plugin with id=" + plugin.id + " should be activated");
var ids = ["secondtestA", "secondtestB"];
for (var id of ids) {
var plugin = doc.getElementById(id);
var rect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 200, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being clicked");
ok(rect.height == 200, "Test 21c, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being clicked");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 21c, Plugin with id=" + plugin.id + " should not be activated");
}
// we have to actually show the panel to get the bindings to instantiate
notification.options.dismissed = false;
notification.options.eventCallback = test21d;
PopupNotifications._showPanel([notification], notification.anchorElement);
}
function test21d() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
notification.options.eventCallback = null;
var centerAction = null;
for (var action of notification.options.centerActions) {
if (action.message == "Second Test") {
centerAction = action;
break;
}
}
ok(centerAction, "Test 21d, found center action for the Second Test plugin");
var centerItem = null;
for (var item of centerAction.popupnotification.childNodes) {
if (item.action == centerAction) {
centerItem = item;
break;
}
}
ok(centerItem, "Test 21d, found center item for the Second Test plugin");
// "click" the button to activate the Second Test plugins
centerItem.runCallback.apply(centerItem);
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("secondtestA");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test21e, "Test 21d, Waited too long for plugin to activate");
}
function test21e() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 21e, Should not have a click-to-play notification");
var doc = gTestBrowser.contentDocument;
var ids = ["test", "secondtestA", "secondtestB"];
for (var id of ids) {
var plugin = doc.getElementById(id);
var rect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 0, "Test 21e, Plugin with id=" + plugin.id + " overlay rect should have 0px width after being clicked");
ok(rect.height == 0, "Test 21e, Plugin with id=" + plugin.id + " overlay rect should have 0px height after being clicked");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 21e, Plugin with id=" + plugin.id + " should be activated");
}
finishTest();
}

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body>
<embed id="test" style="width: 200px; height: 200px" type="application/x-test"/>
<embed id="secondtestA" style="width: 200px; height: 200px" type="application/x-second-test"/>
<embed id="secondtestB" style="width: 200px; height: 200px" type="application/x-second-test"/>
</body>
</html>

View File

@ -1418,6 +1418,102 @@
</implementation>
</binding>
<binding id="center-item">
<content align="center">
<xul:hbox flex="1" align="center" class="center-item-box"
xbl:inherits="padbottom">
<xul:image class="center-item-icon"
xbl:inherits="src=itemicon"/>
<xul:description class="center-item-label"
xbl:inherits="xbl:text=itemtext"/>
<xul:spacer flex="1"/>
<xul:button class="popup-notification-menubutton center-item-button"
oncommand="document.getBindingParent(this).runCallback();"
xbl:inherits="label=buttonlabel"/>
</xul:hbox>
</content>
<resources>
<stylesheet src="chrome://global/skin/notification.css"/>
</resources>
<implementation>
<field name="action"></field>
<method name="runCallback">
<body><![CDATA[
let action = this.action;
action.callback();
let cas = action.popupnotification.notification.options.centerActions;
cas.splice(cas.indexOf(action), 1);
PopupNotifications._dismiss();
]]></body>
</method>
</implementation>
</binding>
<binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
<content align="start" class="click-to-play-plugins-notification-content">
<xul:hbox flex="1">
<xul:vbox class="click-to-play-plugins-notification-icon-box" flex="1">
<xul:image class="popup-notification-icon"
xbl:inherits="popupid,src=icon"/>
<xul:spacer flex="1"/>
</xul:vbox>
<xul:spacer class="click-to-play-plugins-notification-separator"/>
<xul:vbox flex="1" class="popup-notification-main-box"
xbl:inherits="popupid">
<xul:box class="click-to-play-plugins-notification-description-box" flex="1">
<xul:description xbl:inherits="xbl:text=label"/>
</xul:box>
<xul:spacer class="click-to-play-plugins-notification-separator"/>
<xul:vbox class="click-to-play-plugins-notification-center-box">
<children includes="popupnotification-centeritem"/>
</xul:vbox>
<xul:spacer class="click-to-play-plugins-notification-separator"/>
<xul:hbox class="click-to-play-plugins-notification-button-container"
pack="end" align="center">
<xul:button anonid="button"
class="popup-notification-menubutton"
type="menu-button"
xbl:inherits="oncommand=buttoncommand,label=buttonlabel,accesskey=buttonaccesskey">
<xul:menupopup anonid="menupopup"
xbl:inherits="oncommand=menucommand">
<children/>
<xul:menuitem class="menuitem-iconic popup-notification-closeitem"
label="&closeNotificationItem.label;"
xbl:inherits="oncommand=closeitemcommand"/>
</xul:menupopup>
</xul:button>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
<resources>
<stylesheet src="chrome://global/skin/notification.css"/>
</resources>
<implementation>
<field name="button" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "button");
</field>
<field name="menupopup" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menupopup");
</field>
<constructor><![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let popupnotification = this;
let item = null;
this.notification.options.centerActions.forEach(function(action) {
action.popupnotification = popupnotification;
item = document.createElementNS(XUL_NS, "popupnotification-centeritem");
item.action = action;
item.setAttribute("itemtext", action.message);
item.setAttribute("buttonlabel", action.label);
popupnotification.appendChild(item);
});
if (item != null) {
item.setAttribute("padbottom", "true");
}
]]></constructor>
</implementation>
</binding>
<binding id="splitmenu">
<content>

View File

@ -120,12 +120,17 @@ carbonFailurePluginsMessage.message=This page asks to use a plugin that can only
carbonFailurePluginsMessage.restartButton.label=Restart in 32-bit mode
carbonFailurePluginsMessage.restartButton.accesskey=R
activatePluginsMessage.message=Would you like to activate the plugins on this page?
activatePluginsMessage.label=Activate plugins
activatePluginsMessage.label=Activate All Plugins
activatePluginsMessage.accesskey=A
activatePluginsMessage.always=Always activate plugins for this site
activatePluginsMessage.always.accesskey=c
activatePluginsMessage.never=Never activate plugins for this site
activatePluginsMessage.never.accesskey=N
activateSinglePlugin=Activate
PluginClickToPlay=Click here to activate the %S plugin.
PluginVulnerableUpdatable=This plugin is vulnerable and should be updated.
PluginVulnerableNoUpdate=This plugin has security vulnerabilities.
pluginInfo.unknownPlugin=Unknown
# Sanitize
# LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to

View File

@ -1159,9 +1159,7 @@ toolbar[iconsize="small"] #feed-button {
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
width: 32px;
height: 32px;
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.addon-progress-description {
@ -2827,3 +2825,68 @@ chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="top"],
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="bottom"] {
list-style-image: url("chrome://global/skin/icons/panelarrow-light-vertical.svg");
}
.click-to-play-plugins-notification-content {
margin: -10px;
}
.click-to-play-plugins-notification-icon-box {
background: hsla(0,0%,100%,.4);
-moz-border-end: 1px solid hsla(0,0%,100%,.2);
padding-top: 16px;
-moz-padding-start: 16px;
-moz-padding-end: 6px;
}
.click-to-play-plugins-notification-separator {
-moz-border-start: 1px solid hsla(211,79%,6%,.1);
border-top: 1px solid hsla(211,79%,6%,.1);
}
.click-to-play-plugins-notification-description-box {
border-bottom: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
padding: 14px 10px 9px 10px;
}
.click-to-play-plugins-notification-center-box {
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,100%,.2);
background-color: hsla(211,79%,6%,.05);
}
.click-to-play-plugins-notification-button-container {
border-top: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
margin: 0px;
padding: 15px 11px 14px 11px;
}
.center-item-box {
padding-top: 11px;
-moz-padding-start: 16px;
-moz-padding-end: 11px;
margin-bottom: -2px;
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
}
.center-item-box[padbottom="true"] {
padding-bottom: 12px;
}
.center-item-icon {
background-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
background-repeat: no-repeat;
height: 16px;
width: 16px;
margin-bottom: 4px;
}
.center-item-button {
min-width: 0;
}

View File

@ -3055,9 +3055,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
width: 32px;
height: 32px;
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.addon-progress-description {
@ -4251,3 +4249,81 @@ chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="top"],
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="bottom"] {
list-style-image: url("chrome://global/skin/arrow/panelarrow-light-vertical.png");
}
.click-to-play-plugins-notification-content {
margin: -16px;
border-radius: 5px;
}
.click-to-play-plugins-notification-icon-box {
background: hsla(0,0%,100%,.4);
-moz-border-end: 1px solid hsla(0,0%,100%,.2);
padding-top: 16px;
-moz-padding-end: 12px;
-moz-padding-start: 20px;
}
.click-to-play-plugins-notification-icon-box:-moz-locale-dir(ltr) {
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
}
.click-to-play-plugins-notification-icon-box:-moz-locale-dir(rtl) {
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
}
.click-to-play-plugins-notification-separator {
-moz-border-start: 1px solid hsla(211,79%,6%,.1);
border-top: 1px solid hsla(211,79%,6%,.1);
}
.click-to-play-plugins-notification-description-box {
border-bottom: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
max-width: 28em;
padding: 14px 16px 9px 16px;
}
.click-to-play-plugins-notification-center-box {
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,100%,.2);
background-color: hsla(211,79%,6%,.05);
}
.click-to-play-plugins-notification-button-container {
border-top: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
margin: 0px;
padding: 16px 16px 17px 16px;
}
.center-item-box {
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
padding-top: 7px;
-moz-padding-end: 11px;
-moz-padding-start: 16px;
margin-bottom: -3px;
}
.center-item-box[padbottom="true"] {
padding-bottom: 12px;
}
.center-item-icon {
background-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
background-repeat: no-repeat;
height: 16px;
width: 16px;
margin-bottom: 4px;
-moz-margin-end: 6px;
}
.center-item-button {
min-width: 0;
}

View File

@ -2282,9 +2282,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
}
.popup-notification-icon[popupid="click-to-play-plugins"] {
list-style-image: url(chrome://mozapps/skin/plugins/pluginGeneric.png);
width: 32px;
height: 32px;
list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
}
.addon-progress-description {
@ -3518,3 +3516,74 @@ chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
.click-to-play-plugins-notification-content {
margin: -10px;
border-radius: 4px;
}
.click-to-play-plugins-notification-icon-box {
background: hsla(0,0%,100%,.4);
-moz-border-end: 1px solid hsla(0,0%,100%,.2);
padding-top: 16px;
-moz-padding-end: 16px;
-moz-padding-start: 24px;
}
.click-to-play-plugins-notification-icon-box:-moz-locale-dir(ltr) {
border-bottom-left-radius: 4px;
border-top-left-radius: 4px;
}
.click-to-play-plugins-notification-icon-box:-moz-locale-dir(rtl) {
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
}
.click-to-play-plugins-notification-separator {
-moz-border-start: 1px solid hsla(211,79%,6%,.1);
border-top: 1px solid hsla(211,79%,6%,.1);
}
.click-to-play-plugins-notification-description-box {
border-bottom: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
padding-top: 12px;
-moz-padding-end: 11px;
padding-bottom: 9px;
-moz-padding-start: 10px;
}
.click-to-play-plugins-notification-center-box {
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
background-color: hsla(211,79%,6%,.05);
}
.click-to-play-plugins-notification-button-container {
border-top: 1px solid hsla(0,0%,100%,.2);
-moz-border-start: 1px solid hsla(0,0%,100%,.2);
margin: 0px;
padding: 16px;
}
.center-item-box {
padding: 12px 16px 0px 16px;
}
.center-item-box[padbottom="true"] {
padding-bottom: 12px;
}
.center-item-icon {
background-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
background-repeat: no-repeat;
height: 16px;
width: 16px;
margin-bottom: 4px;
}
.center-item-button {
min-width: 0;
}

View File

@ -471,6 +471,9 @@ PopupNotifications.prototype = {
this._currentAnchorElement = anchorElement;
// On OS X and Linux we need a different panel arrow color for
// click-to-play plugins, so copy the popupid and use css.
this.panel.setAttribute("popupid", this.panel.firstChild.getAttribute("popupid"));
this.panel.openPopup(anchorElement, "bottomcenter topleft");
notificationsToShow.forEach(function (n) {
this._fireCallback(n, NOTIFICATION_EVENT_SHOWN);

View File

@ -206,7 +206,7 @@ notification {
/*********** popup notification ************/
popupnotification {
-moz-binding: url("chrome://global/content/bindings/notification.xml#popup-notification")
-moz-binding: url("chrome://global/content/bindings/notification.xml#popup-notification");
}
.popup-notification-menubutton:not([label]) {

View File

@ -36,8 +36,6 @@
<!-- LOCALIZATION NOTE (tapToPlayPlugin): Mobile (used for touch interfaces) only has one type of plugin possible. -->
<!ENTITY tapToPlayPlugin "Tap here to activate plugin.">
<!ENTITY clickToPlayPlugin "Click here to activate plugin.">
<!ENTITY clickToPlayPluginVulnerableUpdateAvailable "Click here to activate vulnerable plugin.">
<!ENTITY clickToPlayPluginVulnerableNoUpdate "Click here to activate vulnerable plugin (no update available).">
<!ENTITY checkForUpdates "Check for updates…">
<!ENTITY disabledPlugin "This plugin is disabled.">
<!ENTITY blockedPlugin.label "This plugin has been blocked for your protection.">

View File

@ -28,10 +28,9 @@
<html:div class="msg msgUnsupported">&missingPlugin;</html:div>
<html:div class="msg msgUnsupportedPlatform">&unsupportedPlatform.pre;<html:a class="unsupportedLearnMoreLink" href="" target="_blank">&unsupportedPlatform.learnMore;</html:a>&unsupportedPlatform.post;</html:div>
<html:div class="msg msgTapToPlay">&tapToPlayPlugin;</html:div>
<html:div class="msg msgClickToPlay">&clickToPlayPlugin;</html:div>
<html:div class="msg msgVulnerableUpdatable">&clickToPlayPluginVulnerableUpdateAvailable;</html:div>
<html:div class="msg msgVulnerableNoUpdate">&clickToPlayPluginVulnerableNoUpdate;</html:div>
<html:div class="msg msgVulnerabilityStatus" anonid="vulnerabilityStatus"><!-- set at runtime --></html:div>
<html:div class="msg msgCheckForUpdates"><html:a class="checkForUpdatesLink" href="">&checkForUpdates;</html:a></html:div>
<html:div class="msg msgClickToPlay">&clickToPlayPlugin;</html:div>
<html:div class="msg msgDisabled">&disabledPlugin;</html:div>
<html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>

View File

@ -75,9 +75,11 @@ html|applet:not([height]), html|applet[height=""] {
:-moz-type-unsupported .msgUnsupported,
:-moz-type-unsupported-platform .msgUnsupportedPlatform,
:-moz-handler-clicktoplay .msgClickToPlay,
:-moz-handler-vulnerable-updatable .msgVulnerableUpdatable,
:-moz-handler-vulnerable-updatable .msgVulnerabilityStatus,
:-moz-handler-vulnerable-updatable .msgCheckForUpdates,
:-moz-handler-vulnerable-no-update .msgVulnerableNoUpdate,
:-moz-handler-vulnerable-updatable .msgClickToPlay,
:-moz-handler-vulnerable-no-update .msgVulnerabilityStatus,
:-moz-handler-vulnerable-no-update .msgClickToPlay,
:-moz-handler-clicktoplay .msgTapToPlay,
:-moz-handler-disabled .msgDisabled,
:-moz-handler-disabled .msgManagePlugins,

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="20"
height="10">
<path d="M 0,10 L 10,0 20,10 z"
fill="-moz-Dialog"/>
<path d="M 0,10 L 10,0 20,10 z"
fill="hsla(0,0%,100%,.4)"/>
</svg>

After

Width:  |  Height:  |  Size: 466 B

View File

@ -47,6 +47,7 @@ toolkit.jar:
+ skin/classic/global/icons/notloading_16.png (icons/notloading_16.png)
+ skin/classic/global/icons/panelarrow-horizontal.svg (icons/panelarrow-horizontal.svg)
+ skin/classic/global/icons/panelarrow-vertical.svg (icons/panelarrow-vertical.svg)
+ skin/classic/global/icons/panelarrow-light-vertical.svg (icons/panelarrow-light-vertical.svg)
+ skin/classic/global/icons/resizer.png (icons/resizer.png)
+ skin/classic/global/icons/sslWarning.png (icons/sslWarning.png)
+ skin/classic/global/icons/wrap.png (icons/wrap.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

View File

@ -79,6 +79,7 @@ toolkit.jar:
skin/classic/global/arrow/arrow-up.gif (arrow/arrow-up.gif)
skin/classic/global/arrow/panelarrow-horizontal.png (arrow/panelarrow-horizontal.png)
skin/classic/global/arrow/panelarrow-vertical.png (arrow/panelarrow-vertical.png)
skin/classic/global/arrow/panelarrow-light-vertical.png (arrow/panelarrow-light-vertical.png)
skin/classic/global/checkbox/cbox-check.gif (checkbox/cbox-check.gif)
skin/classic/global/checkbox/cbox-check-dis.gif (checkbox/cbox-check-dis.gif)
skin/classic/global/console/console-error-caret.gif (console/console-error-caret.gif)

View File

@ -121,6 +121,7 @@ notification[type="critical"] {
-moz-appearance: none;
}
.popup-notification-menubutton:not([type="menu-button"]):-moz-focusring,
.popup-notification-menubutton:-moz-focusring > .button-menubutton-dropmarker,
.popup-notification-menubutton > .button-menubutton-button:-moz-focusring {
box-shadow: @focusRingShadow@;
@ -143,10 +144,6 @@ notification[type="critical"] {
padding: 2px 6px;
}
.popup-notification-menubutton:not([type="menu-button"]) {
padding: 2px 9px;
}
.popup-notification-menubutton > .button-menubutton-button {
-moz-appearance: none;
margin: 0;

View File

@ -68,6 +68,7 @@ toolkit.jar:
skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png)
skin/classic/mozapps/plugins/pluginDisabled.png (plugins/pluginDisabled.png)
skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png)
skin/classic/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png)
skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png)
skin/classic/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png)
skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -76,7 +76,7 @@ notification[type="critical"] {
XXX: apply styles to all themes until bug 509642 is fixed
@media (-moz-windows-default-theme) {
*/
.popup-notification-menubutton[type="menu-button"] {
.popup-notification-menubutton {
-moz-appearance: none;
border-radius: 3px;
padding: 0;
@ -85,10 +85,11 @@ XXX: apply styles to all themes until bug 509642 is fixed
%endif
}
.popup-notification-menubutton[type="menu-button"]:hover:active {
.popup-notification-menubutton:hover:active {
border-color: rgba(0,0,0,.5);
}
.popup-notification-menubutton:not([type="menu-button"]),
.popup-notification-menubutton > .button-menubutton-button,
.popup-notification-menubutton > .button-menubutton-dropmarker {
-moz-appearance: none;
@ -111,6 +112,7 @@ XXX: apply styles to all themes until bug 509642 is fixed
-moz-border-end: none;
}
.popup-notification-menubutton:not([type="menu-button"]),
.popup-notification-menubutton > .button-menubutton-button > .button-box {
-moz-padding-start: 8px;
-moz-padding-end: 5px;
@ -140,6 +142,7 @@ XXX: apply styles to all themes until bug 509642 is fixed
}
%endif
.popup-notification-menubutton:not([type="menu-button"]):hover,
.popup-notification-menubutton > .button-menubutton-button:hover,
.popup-notification-menubutton > .button-menubutton-dropmarker:hover {
%ifdef WINSTRIPE_AERO
@ -151,6 +154,7 @@ XXX: apply styles to all themes until bug 509642 is fixed
%endif
}
.popup-notification-menubutton:not([type="menu-button"]):hover:active,
.popup-notification-menubutton > .button-menubutton-button:hover:active,
.popup-notification-menubutton > .button-menubutton-dropmarker:hover:active,
.popup-notification-menubutton[open="true"] > .button-menubutton-dropmarker {

View File

@ -72,6 +72,7 @@ toolkit.jar:
skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png)
skin/classic/mozapps/plugins/pluginDisabled.png (plugins/pluginDisabled.png)
skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png)
skin/classic/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png)
skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png)
skin/classic/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png)
skin/classic/mozapps/plugins/pluginInstallerWizard.css (plugins/pluginInstallerWizard.css)
@ -151,6 +152,7 @@ toolkit.jar:
skin/classic/aero/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric-aero.png)
skin/classic/aero/mozapps/plugins/pluginDisabled.png (plugins/pluginDisabled-aero.png)
skin/classic/aero/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked-aero.png)
skin/classic/aero/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png)
skin/classic/aero/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16-aero.png)
skin/classic/aero/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png)
skin/classic/aero/mozapps/plugins/pluginInstallerWizard.css (plugins/pluginInstallerWizard.css)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB