This commit is contained in:
Ryan VanderMeulen 2013-06-24 14:02:59 -04:00
Родитель ea2954182f 566d5e6ac3
Коммит d5c5ff5f07
61 изменённых файлов: 1494 добавлений и 1924 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{
"revision": "d816bb323b9c9d7e59b3c8dfc2c62d3901864b46",
"revision": "c18a9987518a11d34217823633aace14f0384322",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -4,6 +4,8 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
const kPrefNotifyMissingFlash = "plugins.notifyMissingFlash";
const kPrefSessionPersistMinutes = "plugin.sessionPermissionNow.intervalInMinutes";
const kPrefPersistentDays = "plugin.persistentPermissionAlways.intervalInDays";
var gPluginHandler = {
PLUGIN_SCRIPTED_STATE_NONE: 0,
@ -24,48 +26,49 @@ var gPluginHandler = {
#endif
_getPluginInfo: function (pluginElement) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
pluginElement.QueryInterface(Ci.nsIObjectLoadingContent);
let tagMimetype;
let pluginsPage;
let pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
let pluginTag = null;
let permissionString = null;
let fallbackType = null;
let blocklistState = null;
if (pluginElement instanceof HTMLAppletElement) {
tagMimetype = "application/x-java-vm";
} else {
if (pluginElement instanceof HTMLObjectElement) {
pluginsPage = pluginElement.getAttribute("codebase");
} else {
pluginsPage = pluginElement.getAttribute("pluginspage");
}
// only attempt if a pluginsPage is defined.
if (pluginsPage) {
let doc = pluginElement.ownerDocument;
let docShell = findChildShell(doc, gBrowser.docShell, null);
try {
pluginsPage = makeURI(pluginsPage, doc.characterSet, docShell.currentURI).spec;
} catch (ex) {
pluginsPage = "";
}
}
tagMimetype = pluginElement.QueryInterface(Ci.nsIObjectLoadingContent)
.actualType;
tagMimetype = pluginElement.actualType;
if (tagMimetype == "") {
tagMimetype = pluginElement.type;
}
}
if (tagMimetype) {
let navMimeType = navigator.mimeTypes.namedItem(tagMimetype);
if (navMimeType && navMimeType.enabledPlugin) {
pluginName = navMimeType.enabledPlugin.name;
pluginName = gPluginHandler.makeNicePluginName(pluginName);
if (gPluginHandler.isKnownPlugin(pluginElement)) {
pluginTag = pluginHost.getPluginTagForType(pluginElement.actualType);
pluginName = gPluginHandler.makeNicePluginName(pluginTag.name);
permissionString = pluginHost.getPermissionStringForType(pluginElement.actualType);
fallbackType = pluginElement.defaultFallbackType;
blocklistState = pluginHost.getBlocklistStateForType(pluginElement.actualType);
// Make state-softblocked == state-notblocked for our purposes,
// they have the same UI. STATE_OUTDATED should not exist for plugin
// items, but let's alias it anyway, just in case.
if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
}
}
return { mimetype: tagMimetype,
pluginsPage: pluginsPage,
pluginName: pluginName };
pluginName: pluginName,
pluginTag: pluginTag,
permissionString: permissionString,
fallbackType: fallbackType,
blocklistState: blocklistState,
};
},
// Map the plugin's name to a filtered version more suitable for user UI.
@ -240,6 +243,8 @@ var gPluginHandler = {
}
}
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
switch (eventType) {
case "PluginCrashed":
this.pluginInstanceCrashed(plugin, event);
@ -263,7 +268,7 @@ var gPluginHandler = {
case "PluginBlocklisted":
case "PluginOutdated":
this.pluginUnavailable(plugin, eventType);
this._showClickToPlayNotification(browser);
break;
case "PluginVulnerableUpdatable":
@ -285,6 +290,7 @@ var gPluginHandler = {
let vulnerabilityText = doc.getAnonymousElementByAttribute(plugin, "anonid", "vulnerabilityStatus");
vulnerabilityText.textContent = vulnerabilityString;
}
this._showClickToPlayNotification(browser);
break;
case "PluginPlayPreview":
@ -294,16 +300,11 @@ var gPluginHandler = {
case "PluginDisabled":
let manageLink = doc.getAnonymousElementByAttribute(plugin, "class", "managePluginsLink");
this.addLinkClickCallback(manageLink, "managePlugins");
this._showClickToPlayNotification(browser);
break;
case "PluginScripted":
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
if (browser._pluginScriptedState == this.PLUGIN_SCRIPTED_STATE_NONE) {
browser._pluginScriptedState = this.PLUGIN_SCRIPTED_STATE_FIRED;
setTimeout(function() {
gPluginHandler.handlePluginScripted(this);
}.bind(browser), 500);
}
case "PluginInstantiated":
this._showClickToPlayNotification(browser);
break;
}
@ -315,45 +316,6 @@ var gPluginHandler = {
}
},
_notificationDisplayedOnce: false,
handlePluginScripted: function PH_handlePluginScripted(aBrowser) {
let contentWindow = aBrowser.contentWindow;
if (!contentWindow)
return;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let plugins = cwu.plugins.filter(function(plugin) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
return gPluginHandler.canActivatePlugin(objLoadingContent);
});
let haveVisibleCTPPlugin = plugins.some(function(plugin) {
let doc = plugin.ownerDocument;
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
if (!overlay)
return false;
// if the plugin's style is 240x200, it's a good bet we set that in
// toolkit/mozapps/plugins/content/pluginProblemContent.css
// (meaning this plugin was never actually given a size, so it's really
// not part of visible content)
let computedStyle = contentWindow.getComputedStyle(plugin);
let isInvisible = ((computedStyle.width == "240px" &&
computedStyle.height == "200px") ||
gPluginHandler.isTooSmall(plugin, overlay));
return !isInvisible;
});
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
if (notification && plugins.length > 0 && !haveVisibleCTPPlugin && !this._notificationDisplayedOnce) {
notification.reshow();
this._notificationDisplayedOnce = true;
}
aBrowser._pluginScriptedState = this.PLUGIN_SCRIPTED_STATE_DONE;
},
isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
return (objLoadingContent.getContentTypeForMIMEType(objLoadingContent.actualType) ==
Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
@ -386,40 +348,6 @@ var gPluginHandler = {
isFallbackTypeValid;
},
activatePlugins: function PH_activatePlugins(aContentWindow) {
let browser = gBrowser.getBrowserForDocument(aContentWindow.document);
browser._clickToPlayAllPluginsActivated = true;
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let plugins = cwu.plugins;
for (let plugin of plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent))
objLoadingContent.playPlugin();
}
let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
if (notification)
notification.remove();
},
activateSinglePlugin: function PH_activateSinglePlugin(aContentWindow, aPlugin) {
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent))
objLoadingContent.playPlugin();
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let pluginNeedsActivation = gPluginHandler._pluginNeedsActivationExceptThese([aPlugin]);
let browser = gBrowser.getBrowserForDocument(aContentWindow.document);
let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
if (notification) {
notification.remove();
}
if (pluginNeedsActivation) {
gPluginHandler._showClickToPlayNotification(browser);
}
},
hideClickToPlayOverlay: function(aPlugin) {
let overlay = aPlugin.ownerDocument.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
if (overlay)
@ -577,13 +505,6 @@ var gPluginHandler = {
return;
}
let pluginInfo = this._getPluginInfo(aPlugin);
if (browser._clickToPlayAllPluginsActivated ||
browser._clickToPlayPluginsActivated.get(pluginInfo.pluginName)) {
objLoadingContent.playPlugin();
return;
}
if (overlay) {
overlay.addEventListener("click", gPluginHandler._overlayClickListener, true);
let closeIcon = doc.getAnonymousElementByAttribute(aPlugin, "anonid", "closeIcon");
@ -592,8 +513,6 @@ var gPluginHandler = {
gPluginHandler.hideClickToPlayOverlay(aPlugin);
}, true);
}
gPluginHandler._showClickToPlayNotification(browser);
},
_overlayClickListener: {
@ -617,13 +536,7 @@ var gPluginHandler = {
if (!(aEvent.originalTarget instanceof HTMLAnchorElement) &&
(aEvent.originalTarget.getAttribute('anonid') != 'closeIcon') &&
aEvent.button == 0 && aEvent.isTrusted) {
if (objLoadingContent.pluginFallbackType ==
Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE ||
objLoadingContent.pluginFallbackType ==
Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE)
gPluginHandler._showClickToPlayNotification(browser, true);
else
gPluginHandler.activateSinglePlugin(contentWindow, plugin);
gPluginHandler._showClickToPlayNotification(browser, plugin);
aEvent.stopPropagation();
aEvent.preventDefault();
}
@ -637,16 +550,6 @@ var gPluginHandler = {
let pluginInfo = this._getPluginInfo(aPlugin);
let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
if (!playPreviewInfo.ignoreCTP) {
// if click-to-play rules used, play plugin at once if plugins were
// activated for this window
if (browser._clickToPlayAllPluginsActivated ||
browser._clickToPlayPluginsActivated.get(pluginInfo.pluginName)) {
objLoadingContent.playPlugin();
return;
}
}
let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent");
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
if (!iframe) {
@ -684,10 +587,6 @@ var gPluginHandler = {
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
let browser = gBrowser.selectedBrowser;
if (!browser._clickToPlayPluginsActivated)
browser._clickToPlayPluginsActivated = new Map();
if (!browser._pluginScriptedState)
browser._pluginScriptedState = gPluginHandler.PLUGIN_SCRIPTED_STATE_NONE;
let contentWindow = browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
@ -701,259 +600,189 @@ var gPluginHandler = {
if (gPluginHandler.canActivatePlugin(objLoadingContent))
gPluginHandler._handleClickToPlayEvent(plugin);
}
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;
_clickToPlayNotificationEventCallback: function PH_ctpEventCallback(event) {
if (event == "showing") {
gPluginHandler._makeCenterActions(this);
}
else if (event == "dismissed") {
// Once the popup is dismissed, clicking the icon should show the full
// list again
this.options.primaryPlugin = null;
}
},
_makeCenterActions: function PH_makeCenterActions(notification) {
let browser = notification.browser;
let contentWindow = browser.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) &&
aExceptThese.indexOf(plugin) < 0);
});
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 = this._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 = new Map();
for (let plugin of cwu.plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let pluginName = this._getPluginInfo(plugin).pluginName;
if (!pluginsDictionary.has(pluginName))
pluginsDictionary.set(pluginName, []);
pluginsDictionary.get(pluginName).push(objLoadingContent);
}
}
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(browser.currentURI);
let centerActions = [];
for (let [pluginName, namedPluginArray] of pluginsDictionary) {
let plugin = namedPluginArray[0];
let warn = false;
let warningText = "";
let updateLink = Services.urlFormatter.formatURLPref("plugins.update.url");
if (plugin.pluginFallbackType) {
if (plugin.pluginFallbackType ==
Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE) {
warn = true;
warningText = gNavigatorBundle.getString("vulnerableUpdatablePluginWarning");
}
else if (plugin.pluginFallbackType ==
Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE) {
warn = true;
warningText = gNavigatorBundle.getString("vulnerableNoUpdatePluginWarning");
updateLink = "";
}
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 action = {
message: pluginName,
warn: warn,
warningText: warningText,
updateLink: updateLink,
label: gNavigatorBundle.getString("activateSinglePlugin"),
callback: function() {
let plugins = gPluginHandler._getPluginsByName(cwu, this.message);
for (let objLoadingContent of plugins) {
objLoadingContent.playPlugin();
let pluginInfo = this._getPluginInfo(plugin);
if (pluginInfo.permissionString === null) {
Components.utils.reportError("No permission string for active plugin.");
continue;
}
aBrowser._clickToPlayPluginsActivated.set(this.message, true);
if (pluginsFound.has(pluginInfo.permissionString)) {
continue;
}
pluginsFound.add(pluginInfo.permissionString);
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
if (notification &&
!gPluginHandler._pluginNeedsActivationExceptThese(plugins)) {
notification.remove();
// 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;
}
}
};
centerActions.push(action);
else {
pluginInfo.pluginPermissionHost = browser.currentURI.host;
pluginInfo.pluginPermissionType = undefined;
}
return centerActions;
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);
}
pluginInfo.detailsLink = url;
centerActions.push(pluginInfo);
}
centerActions.sort(function(a, b) {
return a.pluginName.localeCompare(b.pluginName);
});
notification.options.centerActions = centerActions;
},
_setPermissionForPlugins: function PH_setPermissionForPlugins(aBrowser, aPermission, aPluginList) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
for (let plugin of aPluginList) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// canActivatePlugin will return false if this isn't a known plugin type,
// so the pluginHost.getPermissionStringForType call is protected
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let permissionString = pluginHost.getPermissionStringForType(objLoadingContent.actualType);
Services.perms.add(aBrowser.currentURI, permissionString, aPermission);
}
}
},
/**
* Called from the plugin doorhanger to set the new permissions for a plugin
* and activate plugins if necessary.
* aNewState should be either "allownow" "allowalways" or "block"
*/
_updatePluginPermission: function PH_setPermissionForPlugins(aNotification, aPluginInfo, aNewState) {
let permission;
let expireType;
let expireTime;
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aForceOpenNotification) {
let contentWindow = aBrowser.contentWindow;
let messageString = gNavigatorBundle.getString("activatePluginsMessage.message");
let mainAction = {
label: gNavigatorBundle.getString("activateAllPluginsMessage.label"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.accesskey"),
callback: function() { gPluginHandler.activatePlugins(contentWindow); }
};
let centerActions = gPluginHandler._makeCenterActions(aBrowser);
switch (aNewState) {
case "allownow":
if (aPluginInfo.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
return;
}
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_SESSION;
expireTime = Date.now() + Services.prefs.getIntPref(kPrefSessionPersistMinutes) * 60 * 1000;
break;
case "allowalways":
if (aPluginInfo.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
return;
}
permission = Ci.nsIPermissionManager.ALLOW_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_TIME;
expireTime = Date.now() +
Services.prefs.getIntPref(kPrefPersistentDays) * 24 * 60 * 60 * 1000;
break;
case "block":
if (aPluginInfo.fallbackType != Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
return;
}
permission = Ci.nsIPermissionManager.PROMPT_ACTION;
expireType = Ci.nsIPermissionManager.EXPIRE_NEVER;
expireTime = 0;
break;
default:
Cu.reportError(Error("Unexpected plugin state: " + aNewState));
return;
}
let browser = aNotification.browser;
Services.perms.add(browser.currentURI, aPluginInfo.permissionString,
permission, expireType, expireTime);
if (aNewState == "block") {
return;
}
// Manually activate the plugins that would have been automatically
// activated.
let contentWindow = browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let haveVulnerablePlugin = cwu.plugins.some(function(plugin) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
return (gPluginHandler.canActivatePlugin(objLoadingContent) &&
(objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE ||
objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE));
let plugins = cwu.plugins;
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
for (let plugin of plugins) {
plugin.QueryInterface(Ci.nsIObjectLoadingContent);
// canActivatePlugin will return false if this isn't a known plugin type,
// so the pluginHost.getPermissionStringForType call is protected
if (gPluginHandler.canActivatePlugin(plugin) &&
aPluginInfo.permissionString == pluginHost.getPermissionStringForType(plugin.actualType)) {
plugin.playPlugin();
}
}
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser, aPrimaryPlugin) {
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let contentWindow = aBrowser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let plugins = cwu.plugins;
if (plugins.length == 0) {
if (notification) {
PopupNotifications.remove(notification);
}
return;
}
let haveVulnerablePlugin = plugins.some(function(plugin) {
let fallbackType = plugin.pluginFallbackType;
return fallbackType == plugin.PLUGIN_VULNERABLE_UPDATABLE ||
fallbackType == plugin.PLUGIN_VULNERABLE_NO_UPDATE ||
fallbackType == plugin.PLUGIN_BLOCKLISTED;
});
if (haveVulnerablePlugin) {
messageString = gNavigatorBundle.getString("vulnerablePluginsMessage");
}
let secondaryActions = [{
label: gNavigatorBundle.getString("activatePluginsMessage.always"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.always.accesskey"),
callback: function () {
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.ALLOW_ACTION, cwu.plugins);
gPluginHandler.activatePlugins(contentWindow);
}
},{
label: gNavigatorBundle.getString("activatePluginsMessage.never"),
accessKey: gNavigatorBundle.getString("activatePluginsMessage.never.accesskey"),
callback: function () {
gPluginHandler._setPermissionForPlugins(aBrowser, Ci.nsIPermissionManager.DENY_ACTION, cwu.plugins);
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
if (notification)
notification.remove();
gPluginHandler._removeClickToPlayOverlays(contentWindow);
}
}];
let notification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser);
let dismissed = notification ? notification.dismissed : true;
// Always show the doorhanger if the anchor is not available.
if (!isElementVisible(gURLBar) || aForceOpenNotification)
if (!isElementVisible(gURLBar) || aPrimaryPlugin)
dismissed = false;
let options = { dismissed: dismissed, centerActions: centerActions };
let icon = haveVulnerablePlugin ? "blocked-plugins-notification-icon" : "plugins-notification-icon"
PopupNotifications.show(aBrowser, "click-to-play-plugins",
messageString, icon,
mainAction, secondaryActions, options);
},
_removeClickToPlayOverlays: function PH_removeClickToPlayOverlays(aContentWindow) {
let doc = aContentWindow.document;
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
for (let plugin of cwu.plugins) {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
// for already activated plugins, there will be no overlay
if (overlay)
overlay.style.visibility = "hidden";
}
},
// event listener for blocklisted/outdated plugins.
pluginUnavailable: function (plugin, eventType) {
let browser = gBrowser.getBrowserForDocument(plugin.ownerDocument
.defaultView.top.document);
if (!browser.missingPlugins)
browser.missingPlugins = new Map();
var pluginInfo = this._getPluginInfo(plugin);
browser.missingPlugins.set(pluginInfo.mimetype, pluginInfo);
var notificationBox = gBrowser.getNotificationBox(browser);
// Should only display one of these warnings per page.
// In order of priority, they are: outdated > missing > blocklisted
let outdatedNotification = notificationBox.getNotificationWithValue("outdated-plugins");
let blockedNotification = notificationBox.getNotificationWithValue("blocked-plugins");
function showBlocklistInfo() {
var url = formatURL("extensions.blocklist.detailsURL", true);
gBrowser.loadOneTab(url, {inBackground: false});
return true;
let primaryPluginPermission = null;
if (aPrimaryPlugin) {
primaryPluginPermission = this._getPluginInfo(aPrimaryPlugin).permissionString;
}
function showOutdatedPluginsInfo() {
gPrefService.setBoolPref("plugins.update.notifyUser", false);
var url = formatURL("plugins.update.url", true);
gBrowser.loadOneTab(url, {inBackground: false});
return true;
}
let notifications = {
PluginBlocklisted : {
barID : "blocked-plugins",
iconURL : "chrome://mozapps/skin/plugins/notifyPluginBlocked.png",
message : gNavigatorBundle.getString("blockedpluginsMessage.title"),
buttons : [{
label : gNavigatorBundle.getString("blockedpluginsMessage.infoButton.label"),
accessKey : gNavigatorBundle.getString("blockedpluginsMessage.infoButton.accesskey"),
popup : null,
callback : showBlocklistInfo
},
{
label : gNavigatorBundle.getString("blockedpluginsMessage.searchButton.label"),
accessKey : gNavigatorBundle.getString("blockedpluginsMessage.searchButton.accesskey"),
popup : null,
callback : showOutdatedPluginsInfo
}],
},
PluginOutdated : {
barID : "outdated-plugins",
iconURL : "chrome://mozapps/skin/plugins/notifyPluginOutdated.png",
message : gNavigatorBundle.getString("outdatedpluginsMessage.title"),
buttons : [{
label : gNavigatorBundle.getString("outdatedpluginsMessage.updateButton.label"),
accessKey : gNavigatorBundle.getString("outdatedpluginsMessage.updateButton.accesskey"),
popup : null,
callback : showOutdatedPluginsInfo
}],
},
let options = {
dismissed: dismissed,
eventCallback: this._clickToPlayNotificationEventCallback,
primaryPlugin: primaryPluginPermission
};
// If there is already an outdated plugin notification then do nothing
if (outdatedNotification)
return;
if (eventType == "PluginBlocklisted") {
if (gPrefService.getBoolPref("plugins.hide_infobar_for_blocked_plugin"))
return;
if (blockedNotification)
return;
}
else if (eventType == "PluginOutdated") {
if (gPrefService.getBoolPref("plugins.hide_infobar_for_outdated_plugin"))
return;
// Cancel any notification about blocklisting/missing plugins
if (blockedNotification)
blockedNotification.close();
}
let notify = notifications[eventType];
notificationBox.appendNotification(notify.message, notify.barID, notify.iconURL,
notificationBox.PRIORITY_WARNING_MEDIUM,
notify.buttons);
let icon = haveVulnerablePlugin ? "blocked-plugins-notification-icon" : "plugins-notification-icon";
PopupNotifications.show(aBrowser, "click-to-play-plugins",
"", icon,
null, null, options);
},
// Crashed-plugin observer. Notified once per plugin crash, before events

Просмотреть файл

@ -506,8 +506,8 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
-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");
.plugin-popupnotification-centeritem {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
}
/* override hidden="true" for the status bar compatibility shim

Просмотреть файл

@ -752,9 +752,9 @@ var gBrowserInit = {
// Note that the XBL binding is untrusted
gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true);
gBrowser.addEventListener("PluginScripted", gPluginHandler, true);
gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
gBrowser.addEventListener("PluginInstantiated", gPluginHandler, true);
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);

Просмотреть файл

@ -299,7 +299,7 @@ function clearPluginPermissionTemplate() {
}
function initPluginsRow() {
var vulnerableLabel = document.getElementById("browserBundle").getString("vulnerableNoUpdatePluginWarning");
let vulnerableLabel = document.getElementById("browserBundle").getString("pluginActivateVulnerable.label");
let pluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
let permissionMap = Map();

Просмотреть файл

@ -191,7 +191,6 @@ MOCHITEST_BROWSER_FILES = \
browser_plainTextLinks.js \
browser_pluginnotification.js \
browser_plugins_added_dynamically.js \
browser_CTPScriptPlugin.js \
browser_CTP_drag_drop.js \
browser_pluginplaypreview.js \
browser_pluginplaypreview2.js \
@ -265,13 +264,6 @@ MOCHITEST_BROWSER_FILES = \
plugin_test.html \
plugin_test2.html \
plugin_test3.html \
plugin_test_noScriptNoPopup.html \
plugin_test_scriptedPopup1.html \
plugin_test_scriptedPopup2.html \
plugin_test_scriptedPopup3.html \
plugin_test_scriptedNoPopup1.html \
plugin_test_scriptedNoPopup2.html \
plugin_test_scriptedNoPopup3.html \
plugin_alternate_content.html \
plugin_both.html \
plugin_both2.html \
@ -283,7 +275,6 @@ MOCHITEST_BROWSER_FILES = \
plugin_bug752516.html \
plugin_bug787619.html \
plugin_bug797677.html \
plugin_bug818009.html \
plugin_bug820497.html \
plugin_hidden_to_visible.html \
plugin_two_types.html \
@ -313,7 +304,6 @@ MOCHITEST_BROWSER_FILES = \
browser_bug744745.js \
browser_bug787619.js \
browser_bug812562.js \
browser_bug818009.js \
browser_bug818118.js \
browser_bug820497.js \
blockPluginVulnerableUpdatable.xml \

Просмотреть файл

@ -1,159 +0,0 @@
const gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
const EXPECTED_PLUGINSCRIPTED_EVENT_COUNT = 6;
var gTestBrowser = null;
var gNextTestList = [];
var gNextTest = null;
var gPluginScriptedFired = false;
var gPluginScriptedFiredCount = 0;
Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("plugins.click_to_play");
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
gTestBrowser.removeEventListener("load", pageLoad, true);
gTestBrowser.removeEventListener("PluginScripted", pluginScripted, true);
});
Services.prefs.setBoolPref("plugins.click_to_play", true);
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
gBrowser.selectedTab = gBrowser.addTab();
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.addEventListener("PluginScripted", pluginScripted, true);
// This list is iterated in reverse order, since it uses Array.pop to get the next test.
gNextTestList = [
// Doesn't show a popup since not the first instance of a small plugin
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup1.html" },
// Doesn't show a popup since not the first instance of a small plugin
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup2.html" },
// Shows a popup since it is the first instance of a small plugin
{ func: testExpectPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedPopup3.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup1.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup2.html" },
{ func: testExpectNoPopupPart1,
url: gHttpTestRoot + "plugin_test_scriptedNoPopup3.html" }
];
prepareTest(testNoEventFired, gHttpTestRoot + "plugin_test_noScriptNoPopup.html");
}
function getCurrentTestLocation() {
var loc = gTestBrowser.contentWindow.location.toString();
return loc.replace(gHttpTestRoot, "");
}
function runNextTest() {
var nextTest = gNextTestList.pop();
if (nextTest) {
gPluginScriptedFired = false;
prepareTest(nextTest.func, nextTest.url);
}
else {
finishTest();
}
}
function finishTest() {
is(gPluginScriptedFiredCount, EXPECTED_PLUGINSCRIPTED_EVENT_COUNT, "PluginScripted event count is correct");
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function pluginScripted() {
gPluginScriptedFired = true;
gPluginScriptedFiredCount++;
}
function pageLoad() {
// 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;
}
function testNoEventFired() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have a click-to-play notification (" + getCurrentTestLocation() + ")");
ok(notification.dismissed, "notification should not be showing (" + getCurrentTestLocation() + ")");
ok(!gPluginScriptedFired, "PluginScripted should not have fired (" + getCurrentTestLocation() + ")");
prepareTest(testDenyPermissionPart1, gHttpTestRoot + "plugin_test_noScriptNoPopup.html");
}
function testDenyPermissionPart1() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "test deny permission: should have a click-to-play notification");
// Simulate clicking the "Deny Always" button.
notification.secondaryActions[1].callback();
gPluginScriptedFired = false;
prepareTest(testDenyPermissionPart2, gHttpTestRoot + "plugin_test_scriptedPopup1.html");
}
function testDenyPermissionPart2() {
var condition = function() XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).gScriptingFinished;
waitForCondition(condition, testDenyPermissionPart3, "test deny permission: waited too long for PluginScripted event");
}
function testDenyPermissionPart3() {
ok(!gPluginScriptedFired, "Should not fire plugin-scripted event for disabled plugins");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "test deny permission: should not have a click-to-play notification");
var pluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
Services.perms.remove("127.0.0.1:8888", pluginHost.getPermissionStringForType("application/x-test"));
runNextTest();
}
function testExpectNoPopupPart1() {
var condition = function() gPluginScriptedFired;
waitForCondition(condition, testExpectNoPopupPart2, "waited too long for PluginScripted event (" + getCurrentTestLocation() + ")");
}
function testExpectNoPopupPart2() {
var condition = function() gTestBrowser._pluginScriptedState == gPluginHandler.PLUGIN_SCRIPTED_STATE_DONE;
waitForCondition(condition, testExpectNoPopupPart3, "waited too long for PluginScripted event handling (" + getCurrentTestLocation() + ")");
}
function testExpectNoPopupPart3() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have a click-to-play notification (" + getCurrentTestLocation() + ")");
ok(notification.dismissed, "notification should not be showing (" + getCurrentTestLocation() + ")");
runNextTest();
}
function testExpectPopupPart1() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have a click-to-play notification (" + getCurrentTestLocation() + ")");
var condition = function() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
return !notification.dismissed;
};
waitForCondition(condition, testExpectPopupPart2, "waited too long for popup notification to show (" + getCurrentTestLocation() + ")");
}
function testExpectPopupPart2() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification.dismissed, "notification should be showing (" + getCurrentTestLocation() + ")");
runNextTest();
}

Просмотреть файл

@ -11,6 +11,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
clearAllPluginPermissions();
Services.prefs.clearUserPref("plugins.click_to_play");
let plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
@ -86,91 +87,18 @@ function part7() {
ok(!objLoadingContent.activated, "plugin should not be activated");
EventUtils.synthesizeMouseAtCenter(plugin, {}, gNewWindow.gBrowser.selectedBrowser.contentWindow);
let condition = function() objLoadingContent.activated;
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser).dismissed;
waitForCondition(condition, part8, "waited too long for plugin to activate");
}
function part8() {
ok(!PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should not have a click-to-play notification in the tab in the new window now");
// Click the activate button on doorhanger to make sure it works
gNewWindow.PopupNotifications.panel.firstChild._primaryButton.click();
let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "plugin should be activated now");
gNewWindow.close();
gBrowser.selectedTab = gBrowser.addTab();
gNextTest = part9;
gBrowser.selectedBrowser.addEventListener("PluginBindingAttached", handleEvent, true, true);
// This test page contains an "invisible" plugin. It doesn't script it,
// but when we do later in this test, it will trigger the popup notification.
gBrowser.selectedBrowser.contentDocument.location = gHttpTestRoot + "plugin_test_noScriptNoPopup.html";
}
function part9() {
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 = part10;
gNewWindow = gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
gNewWindow.addEventListener("load", handleEvent, true);
}
function part10() {
gNewWindow.removeEventListener("load", handleEvent);
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
waitForCondition(condition, part11, "Waited too long for click-to-play notification");
}
function part11() {
ok(!PopupNotifications.getNotification("click-to-play-plugins", gBrowser.selectedBrowser), "Should not have a click-to-play notification in the old window now");
let notification = PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
ok(notification, "Should have a click-to-play notification in the tab in the new window");
// we have to actually show the panel to get the bindings to instantiate
notification.options.eventCallback = part12;
// this scripts the plugin, triggering the popup notification
try {
gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test").wrappedJSObject.getObjectValue();
} catch (e) {}
}
function part12(type) {
if (type != "shown") {
return;
}
let notification = PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser);
notification.options.eventCallback = null;
let centerAction = null;
for (let action of notification.options.centerActions) {
if (action.message == "Test") {
centerAction = action;
break;
}
}
ok(centerAction, "Found center action for the Test plugin");
let centerItem = null;
for (let item of centerAction.popupnotification.childNodes) {
if (item.action == centerAction) {
centerItem = item;
break;
}
}
ok(centerItem, "Found center item for the Test plugin");
// "click" the button to activate the Test plugin
centerItem.runCallback.apply(centerItem);
let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
let condition = function() objLoadingContent.activated;
waitForCondition(condition, part13, "Waited too long for plugin to activate via center action");
}
function part13() {
ok(!PopupNotifications.getNotification("click-to-play-plugins", gNewWindow.gBrowser.selectedBrowser), "Should not have a click-to-play notification in the tab in the new window");
let plugin = gNewWindow.gBrowser.selectedBrowser.contentDocument.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Plugin should be activated via center action");
gNewWindow.close();
finish();
}

Просмотреть файл

@ -1,5 +1,4 @@
var rootDir = getRootDirectory(gTestPath);
const gTestRoot = rootDir;
const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/";
var gTestBrowser = null;
var gNextTest = null;
@ -9,6 +8,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
clearAllPluginPermissions();
Services.prefs.clearUserPref("plugins.click_to_play");
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
@ -46,7 +46,7 @@ function prepareTest(nextTest, url) {
function test1a() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 1a, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin());
var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin notification");
@ -59,14 +59,19 @@ function test1b() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
popupNotification.mainAction.callback();
// Click the activate button on doorhanger to make sure it works
popupNotification.reshow();
PopupNotifications.panel.firstChild._primaryButton.click();
ok(objLoadingContent.activated, "Test 1b, Doorhanger should activate plugin");
test1c();
}
function test1c() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 1c, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
ok(popupNotification, "Test 1c, Should still have a click-to-play notification");
var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin());
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
@ -74,8 +79,6 @@ function test1c() {
}
function test1d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 1d, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[1];
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 1d, Plugin should be activated");
@ -87,9 +90,8 @@ function test1d() {
function test1e() {
gTestBrowser.contentWindow.removeEventListener("hashchange", test1e, false);
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 1e, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin());
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
@ -97,22 +99,18 @@ function test1e() {
}
function test1f() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 1f, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[2];
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 1f, Plugin should be activated");
gTestBrowser.contentWindow.history.replaceState({}, "", "replacedState");
var plugin = gTestBrowser.contentWindow.addPlugin();
var plugin = new XPCNativeWrapper(XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addPlugin());
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test1g, "Test 1f, Waited too long for plugin activation");
}
function test1g() {
var popupNotification2 = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification2, "Test 1g, Should not have a click-to-play notification after replaceState");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[3];
var objLoadingContent2 = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent2.activated, "Test 1g, Plugin should be activated");

Просмотреть файл

@ -37,10 +37,10 @@ function tabLoad() {
function actualTest() {
let doc = gTestBrowser.contentDocument;
let plugin = doc.getElementById("test");
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Plugin should not be activated");
ok(!plugin.activated, "Plugin should not be activated");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Doorhanger should not be open");
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
let condition = function() objLoadingContent.activated;
waitForCondition(condition, finish, "Waited too long for plugin to activate");
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, finish, "Waited too long for plugin doorhanger to activate");
}

Просмотреть файл

@ -30,11 +30,12 @@ function part1() {
let plugin = gTestBrowser.contentDocument.getElementById('plugin');
ok(plugin, 'got plugin element');
let objLC = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLC.activated, 'plugin should not be activated');
ok(!plugin.activated, 'plugin should not be activated');
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Doorhanger should not be open");
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
waitForCondition(function() objLC.activated, part2,
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, part2,
'waited too long for plugin to activate');
}

Просмотреть файл

@ -1,51 +0,0 @@
var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
var gTestBrowser = null;
Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("plugins.click_to_play");
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
gTestBrowser.removeEventListener("load", pageLoad, true);
});
Services.prefs.setBoolPref("plugins.click_to_play", true);
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
gBrowser.selectedTab = gBrowser.addTab();
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug818009.html";
}
function pageLoad() {
// 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(actualTest);
}
function actualTest() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have a click-to-play notification");
is(notification.options.centerActions.length, 1, "should have only one type of plugin in the notification");
is(notification.options.centerActions[0].message, "Test", "the one type of plugin should be the 'Test' plugin");
var doc = gTestBrowser.contentDocument;
var inner = doc.getElementById("inner");
ok(inner, "should have 'inner' plugin");
var innerObjLC = inner.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!innerObjLC.activated, "inner plugin shouldn't be activated");
is(innerObjLC.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "inner plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
var outer = doc.getElementById("outer");
ok(outer, "should have 'outer' plugin");
var outerObjLC = outer.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!outerObjLC.activated, "outer plugin shouldn't be activated");
is(outerObjLC.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_ALTERNATE, "outer plugin fallback type should be PLUGIN_ALTERNATE");
gBrowser.removeCurrentTab();
window.focus();
finish();
}

Просмотреть файл

@ -40,7 +40,10 @@ function pluginBindingAttached() {
ok(!secondtestplugin, "should not yet have second test plugin");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
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");
XPCNativeWrapper.unwrap(gTestBrowser.contentWindow).addSecondPlugin();
} else if (gNumPluginBindingsAttached == 2) {
var doc = gTestBrowser.contentDocument;
var testplugin = doc.getElementById("test");
@ -49,6 +52,7 @@ function pluginBindingAttached() {
ok(secondtestplugin, "should have second test plugin");
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");
finish();
} else {

Просмотреть файл

@ -4,8 +4,6 @@ const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://12
var gTestBrowser = null;
var gNextTest = null;
var gClickToPlayPluginActualEvents = 0;
var gClickToPlayPluginExpectedEvents = 5;
var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
Components.utils.import("resource://gre/modules/Services.jsm");
@ -60,12 +58,11 @@ function test() {
waitForExplicitFinish();
requestLongerTimeout(2);
registerCleanupFunction(function() {
clearAllPluginPermissions();
Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
Services.prefs.clearUserPref("plugins.click_to_play");
getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
});
Services.prefs.setBoolPref("plugins.click_to_play", false);
Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
var plugin = getTestPlugin();
@ -75,24 +72,17 @@ function test() {
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
prepareTest(test1, gTestRoot + "plugin_unknown.html");
}
function finishTest() {
clearAllPluginPermissions();
gTestBrowser.removeEventListener("load", pageLoad, true);
gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function handleBindingAttached(evt) {
evt.target instanceof Ci.nsIObjectLoadingContent;
if (evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY)
gClickToPlayPluginActualEvents++;
}
function pageLoad() {
// 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
@ -106,9 +96,7 @@ function prepareTest(nextTest, url) {
// Tests a page with an unknown plugin in it.
function test1() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 1, Should have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1, Should not have displayed the blocked plugin notification");
ok(gTestBrowser.missingPlugins, "Test 1, Should be a missing plugin list");
ok(gTestBrowser.missingPlugins.has("application/x-unknown"), "Test 1, Should know about application/x-unknown");
ok(!gTestBrowser.missingPlugins.has("application/x-test"), "Test 1, Should not know about application/x-test");
@ -126,9 +114,7 @@ function test1() {
// Tests a page with a working plugin in it.
function test2() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 2, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 2, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 2, Should not be a missing plugin list");
var plugin = getTestPlugin();
@ -139,9 +125,7 @@ function test2() {
// Tests a page with a disabled plugin in it.
function test3() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 3, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 3, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 3, Should not be a missing plugin list");
new TabOpenListener("about:addons", test4, prepareTest5);
@ -175,12 +159,16 @@ function prepareTest5() {
// Tests a page with a blocked plugin in it.
function test5() {
info("test5");
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 5, Should not have displayed the missing plugin notification");
ok(notificationBox.getNotificationWithValue("blocked-plugins"), "Test 5, Should have displayed the blocked plugin notification");
ok(gTestBrowser.missingPlugins, "Test 5, Should be a missing plugin list");
ok(gTestBrowser.missingPlugins.has("application/x-test"), "Test 5, Should know about application/x-test");
ok(!gTestBrowser.missingPlugins.has("application/x-unknown"), "Test 5, Should not know about application/x-unknown");
let notification = PopupNotifications.getNotification("click-to-play-plugins");
ok(notification, "Test 5: There should be a plugin notification for blocked plugins");
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");
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");
var pluginNode = gTestBrowser.contentDocument.getElementById("test");
ok(pluginNode, "Test 5, Found plugin in page");
var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent);
@ -191,26 +179,21 @@ function test5() {
// Tests a page with a blocked and unknown plugin in it.
function test6() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 6, Should have displayed the missing plugin notification");
ok(notificationBox.getNotificationWithValue("blocked-plugins"), "Test 6, Should have displayed the blocked plugin notification");
ok(gTestBrowser.missingPlugins, "Test 6, Should be a missing plugin list");
ok(gTestBrowser.missingPlugins.has("application/x-unknown"), "Test 6, Should know about application/x-unknown");
ok(gTestBrowser.missingPlugins.has("application/x-test"), "Test 6, Should know about application/x-test");
ok(!gTestBrowser.missingPlugins.has("application/x-test"), "Test 6, application/x-test should not be a missing plugin");
prepareTest(test7, gTestRoot + "plugin_both2.html");
}
// Tests a page with a blocked and unknown plugin in it (alternate order to above).
function test7() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 7, Should have displayed the missing plugin notification");
ok(notificationBox.getNotificationWithValue("blocked-plugins"), "Test 7, Should have displayed the blocked plugin notification");
ok(gTestBrowser.missingPlugins, "Test 7, Should be a missing plugin list");
ok(gTestBrowser.missingPlugins.has("application/x-unknown"), "Test 7, Should know about application/x-unknown");
ok(gTestBrowser.missingPlugins.has("application/x-test"), "Test 7, Should know about application/x-test");
ok(!gTestBrowser.missingPlugins.has("application/x-test"), "Test 7, application/x-test should not be a missing plugin");
Services.prefs.setBoolPref("plugins.click_to_play", true);
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
@ -222,9 +205,7 @@ function test7() {
// Tests a page with a working plugin that is click-to-play
function test8() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 8, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 8, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 8, Should not be a missing plugin list");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 8, Should have a click-to-play notification");
@ -233,124 +214,11 @@ function test8() {
var objLoadingContent = pluginNode.QueryInterface(Ci.nsIObjectLoadingContent);
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 8, plugin fallback type should be PLUGIN_CLICK_TO_PLAY");
prepareTest(test9a, gTestRoot + "plugin_test2.html");
}
// Tests that activating one click-to-play plugin will activate only that plugin (part 1/3)
function test9a() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "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");
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");
var rect = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 200, "Test 9a, Plugin with id=" + plugin1.id + " overlay rect should have 200px width before being clicked");
ok(rect.height == 200, "Test 9a, Plugin with id=" + plugin1.id + " overlay rect should have 200px height before being clicked");
var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin1.id + " should not be activated");
var plugin2 = doc.getElementById("test2");
var rect = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
ok(rect.width == 200, "Test 9a, Plugin with id=" + plugin2.id + " overlay rect should have 200px width before being clicked");
ok(rect.height == 200, "Test 9a, Plugin with id=" + plugin2.id + " overlay rect should have 200px height before being clicked");
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 9a, Plugin with id=" + plugin2.id + " should not be activated");
EventUtils.synthesizeMouseAtCenter(plugin1, {}, gTestBrowser.contentWindow);
var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test9b, "Test 9a, Waited too long for plugin to activate");
}
// Tests that activating one click-to-play plugin will activate only that plugin (part 2/3)
function test9b() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "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");
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");
var pluginRect1 = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
ok(pluginRect1.width == 0, "Test 9b, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero width");
ok(pluginRect1.height == 0, "Test 9b, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero height");
var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin1.id + " should be activated");
var plugin2 = doc.getElementById("test2");
var pluginRect2 = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
ok(pluginRect2.width != 0, "Test 9b, Plugin with id=" + plugin2.id + " should not have click-to-play overlay with zero width");
ok(pluginRect2.height != 0, "Test 9b, Plugin with id=" + plugin2.id + " should not have click-to-play overlay with zero height");
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 9b, Plugin with id=" + plugin2.id + " should not be activated");
EventUtils.synthesizeMouseAtCenter(plugin2, {}, gTestBrowser.contentWindow);
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test9c, "Test 9b, Waited too long for plugin to activate");
}
//
// Tests that activating one click-to-play plugin will activate only that plugin (part 3/3)
function test9c() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 9c, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9c, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 9c, Should not be a missing plugin list");
ok(!PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9c, Click to play notification should be removed now");
var doc = gTestBrowser.contentDocument;
var plugin1 = doc.getElementById("test1");
var pluginRect1 = doc.getAnonymousElementByAttribute(plugin1, "class", "mainBox").getBoundingClientRect();
ok(pluginRect1.width == 0, "Test 9c, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero width");
ok(pluginRect1.height == 0, "Test 9c, Plugin with id=" + plugin1.id + " should have click-to-play overlay with zero height");
var objLoadingContent = plugin1.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 9c, Plugin with id=" + plugin1.id + " should be activated");
var plugin2 = doc.getElementById("test1");
var pluginRect2 = doc.getAnonymousElementByAttribute(plugin2, "class", "mainBox").getBoundingClientRect();
ok(pluginRect2.width == 0, "Test 9c, Plugin with id=" + plugin2.id + " should have click-to-play overlay with zero width");
ok(pluginRect2.height == 0, "Test 9c, Plugin with id=" + plugin2.id + " should have click-to-play overlay with zero height");
var objLoadingContent = plugin2.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 9c, Plugin with id=" + plugin2.id + " should be activated");
prepareTest(test10a, gTestRoot + "plugin_test3.html");
}
// Tests that activating a hidden click-to-play plugin through the notification works (part 1/2)
function test10a() {
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
ok(!PopupNotifications.getNotification("plugins-not-found", gTestBrowser), "Test 10a, Should not have displayed the missing plugin notification");
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 10a, Should not have displayed the blocked plugin notification");
ok(!gTestBrowser.missingPlugins, "Test 10a, Should not be a missing plugin list");
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 10a, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 10a, Plugin should not be activated");
popupNotification.mainAction.callback();
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test10b, "Test 10a, Waited too long for plugin to activate");
}
// Tests that activating a hidden click-to-play plugin through the notification works (part 2/2)
function test10b() {
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 10b, Plugin should be activated");
prepareTest(test11a, gTestRoot + "plugin_test3.html");
}
// Tests 9 & 10 removed
// Tests that the going back will reshow the notification for click-to-play plugins (part 1/4)
function test11a() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
@ -379,14 +247,11 @@ function test11c() {
function test11d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 11d, Should have a click-to-play notification");
is(gClickToPlayPluginActualEvents, gClickToPlayPluginExpectedEvents,
"There should be a PluginClickToPlay event for each plugin that was " +
"blocked due to the plugins.click_to_play pref");
prepareTest(test12a, gHttpTestRoot + "plugin_clickToPlayAllow.html");
}
// Tests that the "Allow Always" permission works for click-to-play plugins (part 1/3)
// Tests that the "Allow Always" permission works for click-to-play plugins
function test12a() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 12a, Should have a click-to-play notification");
@ -395,156 +260,45 @@ function test12a() {
ok(!objLoadingContent.activated, "Test 12a, Plugin should not be activated");
// Simulate clicking the "Allow Always" button.
popupNotification.secondaryActions[0].callback();
popupNotification.reshow();
PopupNotifications.panel.firstChild._primaryButton.click();
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test12b, "Test 12a, Waited too long for plugin to activate");
}
// Tests that the "Always" permission works for click-to-play plugins (part 2/3)
function test12b() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 12b, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 12b, Plugin should be activated");
prepareTest(test12c, gHttpTestRoot + "plugin_clickToPlayAllow.html");
}
// Tests that the "Always" permission works for click-to-play plugins (part 3/3)
function test12c() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 12c, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 12c, Plugin should be activated");
prepareTest(test12d, gHttpTestRoot + "plugin_two_types.html");
ok(popupNotification, "Test 12d, Should have a click-to-play notification");
prepareTest(test12c, gHttpTestRoot + "plugin_two_types.html");
}
// Test that the "Always" permission, when set for just the Test plugin,
// does not also allow the Second Test plugin.
function test12d() {
function test12c() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 12d, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 12d, Test plugin should be activated");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (A) should not be activated");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (B) should not be activated");
ok(test.activated, "Test 12d, Test plugin should be activated");
ok(!secondtestA.activated, "Test 12d, Second Test plugin (A) should not be activated");
ok(!secondtestB.activated, "Test 12d, Second Test plugin (B) should not be activated");
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
prepareTest(test13a, gHttpTestRoot + "plugin_clickToPlayDeny.html");
}
// Tests that the "Deny Always" permission works for click-to-play plugins (part 1/3)
function test13a() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 13a, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 13a, Plugin should not be activated");
// Simulate clicking the "Deny Always" button.
popupNotification.secondaryActions[1].callback();
test13b();
}
// Tests that the "Deny Always" permission works for click-to-play plugins (part 2/3)
function test13b() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 13b, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 13b, Plugin should not be activated");
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
ok(overlay.style.visibility == "hidden", "Test 13b, Plugin should not have visible overlay");
gNextTest = test13c;
gTestBrowser.reload();
}
// Tests that the "Deny Always" permission works for click-to-play plugins (part 3/3)
function test13c() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 13c, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 13c, Plugin should not be activated");
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED, "Test 13c, Plugin should be disabled");
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
ok(overlay.style.visibility != "visible", "Test 13c, Plugin should have visible overlay");
prepareTest(test13d, gHttpTestRoot + "plugin_two_types.html");
}
// Test that the "Deny Always" permission, when set for just the Test plugin,
// does not also block the Second Test plugin (i.e. it gets an overlay and
// there's a notification and everything).
function test13d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 13d, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(test, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Test plugin should not be activated");
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED, "Test 13d, Test plugin should be disabled");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestA, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (A) should not be activated");
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY, "Test 13d, Test plugin should be disabled");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtestB, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 13d, Test plugin should have visible overlay");
ok(!objLoadingContent.activated, "Test 13d, Second Test plugin (B) should not be activated");
var condition = function() objLoadingContent.activated;
// "click" "Activate All Plugins"
popupNotification.mainAction.callback();
waitForCondition(condition, test13e, "Test 13d, Waited too long for plugin to activate");
}
// Test that clicking "Activate All Plugins" won't activate plugins that
// have previously been "Deny Always"-ed.
function test13e() {
var test = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 13e, Test plugin should not be activated");
var secondtestA = gTestBrowser.contentDocument.getElementById("secondtestA");
var objLoadingContent = secondtestA.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (A) should be activated");
var secondtestB = gTestBrowser.contentDocument.getElementById("secondtestB");
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (B) should be activated");
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
Services.prefs.setBoolPref("plugins.click_to_play", false);
clearAllPluginPermissions();
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_ENABLED;
prepareTest(test14, gTestRoot + "plugin_test2.html");
}
// Test 13 removed
// Tests that the plugin's "activated" property is true for working plugins with click-to-play disabled.
function test14() {
var plugin = gTestBrowser.contentDocument.getElementById("test1");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 14, Plugin should be activated");
Services.prefs.setBoolPref("plugins.click_to_play", true);
var plugin = getTestPlugin();
plugin.enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
@ -559,54 +313,11 @@ function test15() {
var mainBox = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
ok(mainBox, "Test 15, Plugin with id=" + plugin.id + " overlay should exist");
prepareTest(test16a, gTestRoot + "plugin_add_dynamically.html");
}
// Tests that a plugin dynamically added to a page after one plugin is clicked
// to play (which removes the notification) gets its own notification (1/4)
function test16a() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 16a, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentWindow.addPlugin();
var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, test16b, "Test 16a, Waited too long for click-to-play-plugin notification");
}
// 2/4
function test16b() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 16b, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 16b, Plugin should not be activated");
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test16c, "Test 16b, Waited too long for plugin to activate");
}
// 3/4
function test16c() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 16c, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 16c, Plugin should be activated");
var plugin = gTestBrowser.contentWindow.addPlugin();
var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, test16d, "Test 16c, Waited too long for click-to-play-plugin notification");
}
// 4/4
function test16d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "Test 16d, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[1];
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 16d, Plugin should not be activated");
prepareTest(test17, gTestRoot + "plugin_bug749455.html");
}
// Test 16 removed
// Tests that mContentType is used for click-to-play plugins, and not the
// inspected type.
function test17() {
@ -680,15 +391,15 @@ function test18c() {
ok(updateLink.style.display != "block", "Test 18c, Plugin should not have an update link");
// check that click "Always allow" works with blocklisted plugins
clickToPlayNotification.secondaryActions[0].callback();
clickToPlayNotification.reshow();
PopupNotifications.panel.firstChild._primaryButton.click();
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test18d, "Test 18d, Waited too long for plugin to activate");
}
// continue testing "Always allow"
function test18d() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 18d, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 18d, Plugin should be activated");
@ -698,13 +409,11 @@ function test18d() {
// continue testing "Always allow"
function test18e() {
var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "Test 18e, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 18e, Plugin should be activated");
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
clearAllPluginPermissions();
prepareTest(test18f, gHttpTestRoot + "plugin_test.html");
}
@ -741,25 +450,21 @@ function test18g() {
});
}
// Tests that clicking the icon of the overlay activates the plugin
// Tests that clicking the icon of the overlay activates the doorhanger
function test19a() {
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 19a, Plugin should not be activated");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19a, Doorhanger should start out dismissed");
var icon = doc.getAnonymousElementByAttribute(plugin, "class", "icon");
EventUtils.synthesizeMouseAtCenter(icon, {}, gTestBrowser.contentWindow);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test19b, "Test 19a, Waited too long for plugin to activate");
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, test19b, "Test 19a, Waited too long for doorhanger to activate");
}
function test19b() {
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 19b, Plugin should be activated");
prepareTest(test19c, gTestRoot + "plugin_test.html");
}
@ -770,22 +475,19 @@ function test19c() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 19c, Plugin should not be activated");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19c, Doorhanger should start out dismissed");
var text = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
EventUtils.synthesizeMouseAtCenter(text, {}, gTestBrowser.contentWindow);
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test19d, "Test 19c, Waited too long for plugin to activate");
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, test19d, "Test 19c, Waited too long for doorhanger to activate");
}
function test19d() {
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 19d, Plugin should be activated");
prepareTest(test19e, gTestRoot + "plugin_test.html");
}
// Tests that clicking the box of the overlay activates the plugin
// Tests that clicking the box of the overlay activates the doorhanger
// (just to be thorough)
function test19e() {
var doc = gTestBrowser.contentDocument;
@ -793,17 +495,14 @@ function test19e() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 19e, Plugin should not be activated");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 19e, Doorhanger should start out dismissed");
EventUtils.synthesizeMouse(plugin, 50, 50, {}, gTestBrowser.contentWindow);
var condition = function() objLoadingContent.activated;
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, test19f, "Test 19e, Waited too long for plugin to activate");
}
function test19f() {
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 19f, Plugin should be activated");
prepareTest(test20a, gTestRoot + "plugin_hidden_to_visible.html");
}
@ -843,19 +542,31 @@ function test20b() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 20b, plugin should not be activated");
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Test 20b, Doorhanger should start out dismissed");
EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
var condition = function() objLoadingContent.activated;
let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
waitForCondition(condition, test20c, "Test 20b, Waited too long for plugin to activate");
}
function test20c() {
PopupNotifications.panel.firstChild._primaryButton.click();
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("plugin");
let condition = function() plugin.activated;
waitForCondition(condition, test20d, "Test 20c", "Waiting for plugin to activate");
}
function test20d() {
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("plugin");
var pluginRect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();
ok(pluginRect.width == 0, "Test 20c, plugin should have click-to-play overlay with zero width");
ok(pluginRect.height == 0, "Test 20c, plugin should have click-to-play overlay with zero height");
ok(pluginRect.width == 0, "Test 20d, plugin should have click-to-play overlay with zero width");
ok(pluginRect.height == 0, "Test 20d, plugin should have click-to-play overlay with zero height");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 20c, plugin should be activated");
ok(objLoadingContent.activated, "Test 20d, plugin should be activated");
clearAllPluginPermissions();
prepareTest(test21a, gTestRoot + "plugin_two_types.html");
}
@ -864,7 +575,6 @@ function test20c() {
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"];
@ -878,19 +588,12 @@ function test21a() {
}
// we have to actually show the panel to get the bindings to instantiate
notification.options.eventCallback = test21b;
notification.reshow();
}
is(notification.options.centerActions.length, 2, "Test 21a, Should have two types of plugin in the notification");
function test21b(type) {
if (type != "shown") {
return;
}
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") {
if (action.pluginName == "Test") {
centerAction = action;
break;
}
@ -898,7 +601,8 @@ function test21b(type) {
ok(centerAction, "Test 21b, found center action for the Test plugin");
var centerItem = null;
for (var item of centerAction.popupnotification.childNodes) {
for (var item of PopupNotifications.panel.firstChild.childNodes) {
is(item.value, "block", "Test 21b, all plugins should start out blocked");
if (item.action == centerAction) {
centerItem = item;
break;
@ -907,7 +611,8 @@ function test21b(type) {
ok(centerItem, "Test 21b, found center item for the Test plugin");
// "click" the button to activate the Test plugin
centerItem.runCallback.apply(centerItem);
centerItem.value = "allownow";
PopupNotifications.panel.firstChild._primaryButton.click();
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
@ -919,7 +624,9 @@ function test21b(type) {
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");
notification.reshow();
ok(notification.options.centerActions.length == 2, "Test 21c, Should have one type of plugin in the notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("test");
@ -939,21 +646,9 @@ function test21c() {
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.eventCallback = test21d;
notification.reshow();
}
function test21d(type) {
if (type != "shown") {
return;
}
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") {
if (action.pluginName == "Second Test") {
centerAction = action;
break;
}
@ -961,16 +656,21 @@ function test21d(type) {
ok(centerAction, "Test 21d, found center action for the Second Test plugin");
var centerItem = null;
for (var item of centerAction.popupnotification.childNodes) {
for (var item of PopupNotifications.panel.firstChild.childNodes) {
if (item.action == centerAction) {
is(item.value, "block", "Test 21d, test plugin 2 should start blocked");
centerItem = item;
break;
}
else {
is(item.value, "allownow", "Test 21d, test plugin should be enabled");
}
}
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);
centerItem.value = "allownow";
PopupNotifications.panel.firstChild._primaryButton.click();
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("secondtestA");
@ -980,9 +680,6 @@ function test21d(type) {
}
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) {
@ -994,9 +691,11 @@ function test21e() {
ok(objLoadingContent.activated, "Test 21e, Plugin with id=" + plugin.id + " should be activated");
}
Services.prefs.setBoolPref("plugins.click_to_play", true);
getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_CLICKTOPLAY;
clearAllPluginPermissions();
prepareTest(test22, gTestRoot + "plugin_test.html");
}
@ -1074,14 +773,13 @@ function test24a() {
ok(!objLoadingContent.activated, "Test 24a, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
notification.reshow();
PopupNotifications.panel.firstChild._primaryButton.click();
prepareTest(test24b, gHttpTestRoot + "plugin_test.html");
}
// did the "always allow" work as intended?
function test24b() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 24b, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24b, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
@ -1103,86 +801,25 @@ function test24c() {
ok(!objLoadingContent.activated, "Test 24c, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
notification.reshow();
PopupNotifications.panel.firstChild._primaryButton.click();
prepareTest(test24d, gHttpTestRoot + "plugin_test.html");
}
// We should still be able to always allow a plugin after we've seen that it's
// blocklisted.
function test24d() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 24d, Should not have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 24d, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 24d, plugin should be activated");
// this resets the vulnerable plugin permission
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml",
function() {
// this resets the normal plugin permission
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
clearAllPluginPermissions();
resetBlocklist();
prepareTest(test25a, gHttpTestRoot + "plugin_test.html");
finishTest();
});
}
// Test that clicking "always allow" or "always deny" doesn't affect plugins
// that already have permission given to them
function test25a() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 25a, Should have a click-to-play notification");
var plugin = gTestBrowser.contentDocument.getElementById("test");
ok(plugin, "Test 25a, Found plugin in page");
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25a, plugin should not be activated");
// simulate "always allow"
notification.secondaryActions[0].callback();
prepareTest(test25b, gHttpTestRoot + "plugin_two_types.html");
}
function test25b() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "Test 25b, Should have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
ok(test, "Test 25b, Found test plugin in page");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 25b, test plugin should be activated");
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
ok(secondtest, "Test 25b, Found second test plugin in page");
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25b, second test plugin should not be activated");
// simulate "always deny"
notification.secondaryActions[1].callback();
prepareTest(test25c, gHttpTestRoot + "plugin_two_types.html");
}
// we should have one plugin allowed to activate and the other plugin(s) denied
// (so it should have an invisible overlay)
function test25c() {
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!notification, "Test 25c, Should not have a click-to-play notification");
var test = gTestBrowser.contentDocument.getElementById("test");
ok(test, "Test 25c, Found test plugin in page");
var objLoadingContent = test.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 25c, test plugin should be activated");
var secondtest = gTestBrowser.contentDocument.getElementById("secondtestA");
ok(secondtest, "Test 25c, Found second test plugin in page");
var objLoadingContent = secondtest.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 25c, second test plugin should not be activated");
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_DISABLED, "Test 25c, second test plugin should be disabled");
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtest, "class", "mainBox");
ok(overlay.style.visibility != "hidden", "Test 25c, second test plugin should have visible overlay");
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-second-test"));
finishTest();
}

Просмотреть файл

@ -1,4 +1,4 @@
const gTestRoot = getRootDirectory(gTestPath);
const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/";
let gTestBrowser = null;
let gNextTest = null;
@ -6,9 +6,16 @@ let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Co
Components.utils.import("resource://gre/modules/Services.jsm");
// Let's do the XPCNativeWrapper dance!
function addPlugin(browser, type) {
let contentWindow = XPCNativeWrapper.unwrap(browser.contentWindow);
contentWindow.addPlugin(type);
}
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
clearAllPluginPermissions();
Services.prefs.clearUserPref("plugins.click_to_play");
getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
@ -21,7 +28,7 @@ function test() {
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
prepareTest(testActivateAllPart1, gTestRoot + "plugin_add_dynamically.html");
prepareTest(testActivateAddSameTypePart1, gTestRoot + "plugin_add_dynamically.html");
}
function finishTest() {
@ -42,62 +49,12 @@ function prepareTest(nextTest, url) {
gTestBrowser.contentWindow.location = url;
}
// "Activate All Plugins" -> plugin of any type dynamically added to the page
// should automatically play
function testActivateAllPart1() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "testActivateAllPart1: should not have a click-to-play notification");
gTestBrowser.contentWindow.addPlugin();
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, testActivateAllPart2, "testActivateAllPart1: waited too long for click-to-play-plugin notification");
}
function testActivateAllPart2() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "testActivateAllPart2: should have a click-to-play notification");
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "testActivateAllPart2: plugin should not be activated");
// "click" "Activate All Plugins"
popupNotification.mainAction.callback();
let condition = function() objLoadingContent.activated;
waitForCondition(condition, testActivateAllPart3, "testActivateAllPart2: waited too long for plugin to activate");
}
function testActivateAllPart3() {
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "testActivateAllPart3: plugin should be activated");
gTestBrowser.contentWindow.addPlugin("application/x-second-test");
let condition = function() {
let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed");
for (let embed of embeds) {
let objLoadingContent = embed.QueryInterface(Ci.nsIObjectLoadingContent);
if (embed.type == "application/x-second-test" && objLoadingContent.activated)
return true;
}
return false;
};
waitForCondition(condition, testActivateAllPart4, "testActivateAllPart3: waited too long for second plugin to activate");
}
function testActivateAllPart4() {
let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed");
for (let embed of embeds) {
let objLoadingContent = embed.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "testActivateAllPart4: all plugins should be activated");
}
prepareTest(testActivateAddSameTypePart1, gTestRoot + "plugin_add_dynamically.html");
}
// "Activate" of a given type -> plugins of that type dynamically added should
// automatically play.
function testActivateAddSameTypePart1() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "testActivateAddSameTypePart1: should not have a click-to-play notification");
gTestBrowser.contentWindow.addPlugin();
addPlugin(gTestBrowser);
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, testActivateAddSameTypePart2, "testActivateAddSameTypePart1: waited too long for click-to-play-plugin notification");
}
@ -106,20 +63,15 @@ function testActivateAddSameTypePart2() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(popupNotification, "testActivateAddSameTypePart2: should have a click-to-play notification");
// we have to actually show the panel to get the bindings to instantiate
popupNotification.options.eventCallback = testActivateAddSameTypePart3;
popupNotification.reshow();
testActivateAddSameTypePart3();
}
function testActivateAddSameTypePart3(type) {
if (type != "shown") {
return;
}
function testActivateAddSameTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
popupNotification.options.eventCallback = null;
let centerAction = null;
for (let action of popupNotification.options.centerActions) {
if (action.message == "Test") {
if (action.pluginName == "Test") {
centerAction = action;
break;
}
@ -127,7 +79,7 @@ function testActivateAddSameTypePart3(type) {
ok(centerAction, "testActivateAddSameTypePart3: found center action for the Test plugin");
let centerItem = null;
for (let item of centerAction.popupnotification.childNodes) {
for (let item of PopupNotifications.panel.firstChild.childNodes) {
if (item.action && item.action == centerAction) {
centerItem = item;
break;
@ -136,28 +88,26 @@ function testActivateAddSameTypePart3(type) {
ok(centerItem, "testActivateAddSameTypePart3: found center item for the Test plugin");
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "testActivateAddSameTypePart3: plugin should not be activated");
ok(!plugin.activated, "testActivateAddSameTypePart3: plugin should not be activated");
// "click" the button to activate the Test plugin
centerItem.runCallback.apply(centerItem);
// Change the state and click the ok button to activate the Test plugin
centerItem.value = "allownow";
PopupNotifications.panel.firstChild._primaryButton.click();
let condition = function() objLoadingContent.activated;
let condition = function() plugin.activated;
waitForCondition(condition, testActivateAddSameTypePart4, "testActivateAddSameTypePart3: waited too long for plugin to activate");
}
function testActivateAddSameTypePart4() {
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "testActivateAddSameTypePart4: plugin should be activated");
ok(plugin.activated, "testActivateAddSameTypePart4: plugin should be activated");
gTestBrowser.contentWindow.addPlugin();
addPlugin(gTestBrowser);
let condition = function() {
let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed");
let allActivated = true;
for (let embed of embeds) {
let objLoadingContent = embed.QueryInterface(Ci.nsIObjectLoadingContent);
if (!objLoadingContent.activated)
if (!embed.activated)
allActivated = false;
}
return allActivated && embeds.length == 2;
@ -167,9 +117,9 @@ function testActivateAddSameTypePart4() {
function testActivateAddSameTypePart5() {
let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed");
for (let embed of embeds) {
let objLoadingContent = embed.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "testActivateAddSameTypePart5: all plugins should be activated");
ok(embed.activated, "testActivateAddSameTypePart5: all plugins should be activated");
}
clearAllPluginPermissions();
prepareTest(testActivateAddDifferentTypePart1, gTestRoot + "plugin_add_dynamically.html");
}
@ -178,7 +128,7 @@ function testActivateAddSameTypePart5() {
function testActivateAddDifferentTypePart1() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(!popupNotification, "testActivateAddDifferentTypePart1: should not have a click-to-play notification");
gTestBrowser.contentWindow.addPlugin();
addPlugin(gTestBrowser);
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, testActivateAddDifferentTypePart2, "testActivateAddDifferentTypePart1: waited too long for click-to-play-plugin notification");
}
@ -188,51 +138,29 @@ function testActivateAddDifferentTypePart2() {
ok(popupNotification, "testActivateAddDifferentTypePart2: should have a click-to-play notification");
// we have to actually show the panel to get the bindings to instantiate
popupNotification.options.eventCallback = testActivateAddDifferentTypePart3;
popupNotification.reshow();
testActivateAddDifferentTypePart3();
}
function testActivateAddDifferentTypePart3(type) {
if (type != "shown") {
return;
}
function testActivateAddDifferentTypePart3() {
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
popupNotification.options.eventCallback = null;
let centerAction = null;
for (let action of popupNotification.options.centerActions) {
if (action.message == "Test") {
centerAction = action;
break;
}
}
ok(centerAction, "testActivateAddDifferentTypePart3: found center action for the Test plugin");
let centerItem = null;
for (let item of centerAction.popupnotification.childNodes) {
if (item.action && item.action == centerAction) {
centerItem = item;
break;
}
}
ok(centerItem, "testActivateAddDifferentTypePart3: found center item for the Test plugin");
is(popupNotification.options.centerActions.length, 1, "Should be one plugin action");
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "testActivateAddDifferentTypePart3: plugin should not be activated");
ok(!plugin.activated, "testActivateAddDifferentTypePart3: plugin should not be activated");
// "click" the button to activate the Test plugin
centerItem.runCallback.apply(centerItem);
PopupNotifications.panel.firstChild._primaryButton.click();
let condition = function() objLoadingContent.activated;
let condition = function() plugin.activated;
waitForCondition(condition, testActivateAddDifferentTypePart4, "testActivateAddDifferentTypePart3: waited too long for plugin to activate");
}
function testActivateAddDifferentTypePart4() {
let plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "testActivateAddDifferentTypePart4: plugin should be activated");
ok(plugin.activated, "testActivateAddDifferentTypePart4: plugin should be activated");
gTestBrowser.contentWindow.addPlugin("application/x-second-test");
addPlugin(gTestBrowser);
let condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
waitForCondition(condition, testActivateAddDifferentTypePart5, "testActivateAddDifferentTypePart5: waited too long for popup notification");
}
@ -241,11 +169,10 @@ function testActivateAddDifferentTypePart5() {
ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "testActivateAddDifferentTypePart5: should have popup notification");
let embeds = gTestBrowser.contentDocument.getElementsByTagName("embed");
for (let embed of embeds) {
let objLoadingContent = embed.QueryInterface(Ci.nsIObjectLoadingContent);
if (embed.type == "application/x-test")
ok(objLoadingContent.activated, "testActivateAddDifferentTypePart5: Test plugin should be activated");
ok(embed.activated, "testActivateAddDifferentTypePart5: Test plugin should be activated");
else if (embed.type == "application/x-second-test")
ok(!objLoadingContent.activated, "testActivateAddDifferentTypePart5: Second Test plugin should not be activated");
ok(!embed.activated, "testActivateAddDifferentTypePart5: Second Test plugin should not be activated");
}
finishTest();

Просмотреть файл

@ -111,6 +111,18 @@ function getTestPlugin(aName) {
return null;
}
// after a test is done using the plugin doorhanger, we should just clear
// any permissions that may have crept in
function clearAllPluginPermissions() {
let perms = Services.perms.enumerator;
while (perms.hasMoreElements()) {
let perm = perms.getNext();
if (perm.type.startsWith('plugin')) {
Services.perms.remove(perm.host, perm.type);
}
}
}
function updateBlocklist(aCallback) {
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);

Просмотреть файл

@ -1,8 +0,0 @@
<!DOCTYPE html>
<head><meta charset="utf8"/></head>
<body>
<object id="outer" width="200" height="200">
<embed id="inner" width="200" height="200" type="application/x-test"/>
</object>
</body>
</html>

Просмотреть файл

@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body onload="addSecondPlugin()">
<body>
<object id="test" type="application/x-test" width=200 height=200></object>
<script>
function addSecondPlugin() {

Просмотреть файл

@ -1,7 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<embed id="test" type="application/x-test"/>
</body>
</html>

Просмотреть файл

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<embed id="test" type="application/x-test"/>
<embed id="test-visible" type="application/x-test" width=200 height=200/>
<script>
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {}
}
</script>
</body>
</html>

Просмотреть файл

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<div style="width: 200px; height: 200px;">
<embed id="test" style="width: inherit; height: inherit;" type="application/x-test"/>
</div>
<script>
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {}
}
</script>
</body>
</html>

Просмотреть файл

@ -1,23 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<div id="container" style="width: 0px; height: 0px;">
<embed id="test" style="width: inherit; height: inherit;" type="application/x-test"/>
</div>
<script>
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {}
setTimeout(function() {
var container = document.getElementById("container");
container.style.width = "200px";
container.style.height = "200px";
}, 10);
}
</script>
</body>
</html>

Просмотреть файл

@ -1,18 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<embed id="test" type="application/x-test"/>
<script>
var gScriptingFinished = false;
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {
setTimeout(function() { gScriptingFinished = true; }, 0);
}
}
</script>
</body>
</html>

Просмотреть файл

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<embed id="test" type="application/x-test" width=0 height=0/>
<embed id="test2" type="application/x-test" width=1 height=1/>
<script>
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {}
}
</script>
</body>
</html>

Просмотреть файл

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body onload="scriptPlugin()">
<div id="container" style="width: 0px; height: 0px;">
<embed id="test" style="width: inherit; height: inherit;" type="application/x-test"/>
</div>
<script>
function scriptPlugin() {
try {
document.getElementById("test").getObjectValue();
}
catch (e) {}
}
</script>
</body>
</html>

Просмотреть файл

@ -8,6 +8,8 @@
<!DOCTYPE bindings [
<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
%notificationDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
]>
<bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl"
@ -1376,122 +1378,477 @@
</implementation>
</binding>
<binding id="center-item">
<binding id="plugin-popupnotification-center-item">
<content align="center">
<xul:vbox flex="1" class="center-item-box"
xbl:inherits="warn,showseparator,padbottom">
<xul:hbox flex="1" align="center">
<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>
<xul:hbox flex="1" align="center" class="center-item-warning">
<xul:image class="center-item-warning-icon"/>
<xul:label class="center-item-warning-description" xbl:inherits="xbl:text=warningText"/>
<xul:label xbl:inherits="href=updateLink" value="&checkForUpdates;" class="text-link"/>
<xul:spacer flex="1"/>
<xul:vbox pack="center" anonid="itemBox" class="itemBox">
<xul:description anonid="center-item-label" class="center-item-label" />
<xul:hbox flex="1" pack="start" align="center" anonid="center-item-warning">
<xul:image anonid="center-item-warning-icon" class="center-item-warning-icon"/>
<xul:label anonid="center-item-warning-label"/>
<xul:label anonid="center-item-link" value="&checkForUpdates;" class="text-link"/>
</xul:hbox>
</xul:vbox>
<xul:vbox pack="center">
<xul:menulist class="center-item-menulist"
anonid="center-item-menulist">
<xul:menupopup>
<xul:menuitem anonid="allownow" value="allownow"
label="&pluginActivateNow.label;" />
<xul:menuitem anonid="allowalways" value="allowalways"
label="&pluginActivateAlways.label;" />
<xul:menuitem anonid="block" value="block"
label="&pluginBlockNow.label;" />
</xul:menupopup>
</xul:menulist>
</xul:vbox>
</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>
<constructor><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid", "center-item-label").value = this.action.pluginName;
let curState = "block";
if (this.action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
if (this.action.pluginPermissionType == Ci.nsIPermissionManager.EXPIRE_SESSION) {
curState = "allownow";
}
else {
curState = "allowalways";
}
}
document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").value = curState;
let warningString = "";
let linkString = "";
let link = document.getAnonymousElementByAttribute(this, "anonid", "center-item-link");
let url;
let linkHandler;
if (this.action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED) {
document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").hidden = true;
warningString = gNavigatorBundle.getString("pluginActivateDisabled.label");
linkString = gNavigatorBundle.getString("pluginActivateDisabled.manage");
linkHandler = function(event) {
event.preventDefault();
gPluginHandler.managePlugins();
};
document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning-icon").hidden = true;
}
else {
url = this.action.detailsLink;
switch (this.action.blocklistState) {
case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning").hidden = true;
break;
case Ci.nsIBlocklistService.STATE_BLOCKED:
document.getAnonymousElementByAttribute(this, "anonid", "center-item-menulist").hidden = true;
warningString = gNavigatorBundle.getString("pluginActivateBlocked.label");
linkString = gNavigatorBundle.getString("pluginActivate.learnMore");
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
warningString = gNavigatorBundle.getString("pluginActivateOutdated.label");
linkString = gNavigatorBundle.getString("pluginActivate.updateLabel");
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
warningString = gNavigatorBundle.getString("pluginActivateVulnerable.label");
linkString = gNavigatorBundle.getString("pluginActivate.riskLabel");
break;
}
}
document.getAnonymousElementByAttribute(this, "anonid", "center-item-warning-label").value = warningString;
if (url || linkHandler) {
link.value = linkString;
if (url) {
link.href = url;
}
if (linkHandler) {
link.addEventListener("click", linkHandler, false);
}
}
else {
link.hidden = true;
}
]]></constructor>
<property name="value">
<getter>
return document.getAnonymousElementByAttribute(this, "anonid",
"center-item-menulist").value;
</getter>
<setter><!-- This should be used only in automated tests -->
document.getAnonymousElementByAttribute(this, "anonid",
"center-item-menulist").value = val;
</setter>
</property>
</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"
<xul:vbox flex="1" align="stretch" 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">
<xul:hbox class="click-to-play-plugins-notification-description-box" flex="1" align="start">
<xul:description class="click-to-play-plugins-outer-description" flex="1">
<html:span anonid="click-to-play-plugins-notification-description" />
<xul:label class="text-link click-to-play-plugins-notification-link" anonid="click-to-play-plugins-notification-link" />
</xul:description>
<xul:toolbarbutton anonid="closebutton"
class="messageCloseButton popup-notification-closebutton tabbable"
xbl:inherits="oncommand=closebuttoncommand"
tooltiptext="&closeNotification.tooltip;"/>
</xul:hbox>
<xul:grid anonid="click-to-play-plugins-notification-center-box"
class="click-to-play-plugins-notification-center-box">
<xul:columns>
<xul:column flex="1"/>
<xul:column/>
</xul:columns>
<xul:rows>
<children includes="row"/>
<xul:hbox pack="start" anonid="plugin-notification-showbox">
<xul:button label="&pluginNotification.showAll.label;"
accesskey="&pluginNotification.showAll.accesskey;"
class="plugin-notification-showbutton"
oncommand="document.getBindingParent(this)._setState(2)"/>
</xul:hbox>
</xul:rows>
</xul:grid>
<xul:hbox anonid="button-container"
class="click-to-play-plugins-notification-button-container"
pack="center" align="center">
<xul:button anonid="primarybutton"
class="click-to-play-popup-button primary-button"
oncommand="document.getBindingParent(this)._onButton(this)"
flex="1"/>
<xul:button anonid="secondarybutton"
class="click-to-play-popup-button"
oncommand="document.getBindingParent(this)._onButton(this);"
flex="1"/>
</xul:hbox>
<xul:box hidden="true">
<children/>
<xul:menuitem class="menuitem-iconic popup-notification-closeitem"
label="&closeNotificationItem.label;"
xbl:inherits="oncommand=closeitemcommand"/>
</xul:menupopup>
</xul:button>
</xul:hbox>
</xul:box>
</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 name="_states">
({SINGLE: 0, MULTI_COLLAPSED: 1, MULTI_EXPANDED: 2})
</field>
<field name="menupopup" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menupopup");
<field name="_primaryButton">
document.getAnonymousElementByAttribute(this, "anonid", "primarybutton");
</field>
<field name="_secondaryButton">
document.getAnonymousElementByAttribute(this, "anonid", "secondarybutton")
</field>
<field name="_buttonContainer">
document.getAnonymousElementByAttribute(this, "anonid", "button-container")
</field>
<field name="_brandShortName">
document.getElementById("bundle_brand").getString("brandShortName")
</field>
<field name="_items">[]</field>
<constructor><![CDATA[
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let popupnotification = this;
let item = null;
let prev = null;
this.notification.options.centerActions.forEach(function(action) {
action.popupnotification = popupnotification;
item = document.createElementNS(XUL_NS, "popupnotification-centeritem");
for (let action of this.notification.options.centerActions) {
let item = document.createElementNS(XUL_NS, "row");
item.setAttribute("class", "plugin-popupnotification-centeritem");
item.action = action;
item.setAttribute("itemtext", action.message);
item.setAttribute("buttonlabel", action.label);
item.setAttribute("warn", action.warn);
item.setAttribute("warningText", action.warningText);
item.setAttribute("updateLink", action.updateLink);
if (prev &&
(prev.getAttribute("warn") == "true" ||
item.getAttribute("warn") == "true")) {
item.setAttribute("showseparator", true);
if (prev.getAttribute("warn") != "true") {
prev.setAttribute("padbottom", true);
this.appendChild(item);
this._items.push(item);
}
}
popupnotification.appendChild(item);
prev = item;
});
if (item != null) {
item.setAttribute("padbottom", "true");
if (this.notification.options.centerActions.length == 1) {
this._setState(this._states.SINGLE);
} else if (this.notification.options.primaryPlugin) {
this._setState(this._states.MULTI_COLLAPSED);
} else {
this._setState(this._states.MULTI_EXPANDED);
}
]]></constructor>
<method name="_setState">
<parameter name="state" />
<body><![CDATA[
var grid = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-center-box");
if (this._states.SINGLE == state) {
grid.hidden = true;
this._setupSingleState();
return;
}
this._setupDescription("pluginActivateMultiple.message");
var showBox = document.getAnonymousElementByAttribute(this, "anonid", "plugin-notification-showbox");
var dialogStrings = Services.strings.createBundle("chrome://global/locale/dialog.properties");
this._primaryButton.label = dialogStrings.GetStringFromName("button-accept");
this._primaryButton.setAttribute("default", "true");
this._secondaryButton.label = dialogStrings.GetStringFromName("button-cancel");
this._primaryButton.setAttribute("action", "_multiAccept");
this._secondaryButton.setAttribute("action", "_cancel");
grid.hidden = false;
if (this._states.MULTI_COLLAPSED == state) {
for (let child of this.childNodes) {
if (child.tagName != "row") {
continue;
}
child.hidden = this.notification.options.primaryPlugin !=
child.action.permissionString;
}
showBox.hidden = false;
}
else {
for (let child of this.childNodes) {
if (child.tagName != "row") {
continue;
}
child.hidden = false;
}
showBox.hidden = true;
}
this._setupLink(null);
]]></body>
</method>
<method name="_setupSingleState">
<body><![CDATA[
var action = this.notification.options.centerActions[0];
var host = action.pluginPermissionHost;
let label, linkLabel, linkUrl, button1, button2;
if (action.fallbackType == Ci.nsIObjectLoadingContent.PLUGIN_ACTIVE) {
button1 = {
label: "pluginBlockNow.label",
accesskey: "pluginBlockNow.accesskey",
action: "_singleBlock"
};
button2 = {
label: "pluginContinue.label",
accesskey: "pluginContinue.accesskey",
action: "_cancel",
default: true
};
switch (action.blocklistState) {
case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
label = "pluginEnabled.message";
linkLabel = "pluginActivate.learnMore";
break;
case Ci.nsIBlocklistService.STATE_BLOCKED:
Cu.reportError(Error("Cannot happen!"));
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
label = "pluginEnabledOutdated.message";
linkLabel = "pluginActivate.updateLabel";
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
label = "pluginEnabledVulnerable.message";
linkLabel = "pluginActivate.riskLabel"
break;
default:
Cu.reportError(Error("Unexpected blocklist state"));
}
}
else if (action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED) {
let linkElement =
document.getAnonymousElementByAttribute(
this, "anonid", "click-to-play-plugins-notification-link");
linkElement.textContent = gNavigatorBundle.getString("pluginActivateDisabled.manage");
linkElement.setAttribute("onclick", "gPluginHandler.managePlugins()");
let descElement = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
descElement.textContent = gNavigatorBundle.getFormattedString(
"pluginActivateDisabled.message", [action.pluginName, this._brandShortName]) + " ";
this._buttonContainer.hidden = true;
return;
}
else if (action.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
let descElement = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
descElement.textContent = gNavigatorBundle.getFormattedString(
"pluginActivateBlocked.message", [action.pluginName, this._brandShortName]) + " ";
this._setupLink("pluginActivate.learnMore", action.detailsLink);
this._buttonContainer.hidden = true;
return;
}
else {
button1 = {
label: "pluginActivateNow.label",
accesskey: "pluginActivateNow.accesskey",
action: "_singleActivateNow"
};
button2 = {
label: "pluginActivateAlways.label",
accesskey: "pluginActivateAlways.accesskey",
action: "_singleActivateAlways"
};
switch (action.blocklistState) {
case Ci.nsIBlocklistService.STATE_NOT_BLOCKED:
label = "pluginActivateNew.message";
linkLabel = "pluginActivate.learnMore";
button2.default = true;
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE:
label = "pluginActivateOutdated.label";
linkLabel = "pluginActivate.updateLabel";
button1.default = true;
break;
case Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE:
label = "pluginActivateVulnerable.message";
linkLabel = "pluginActivate.riskLabel"
button1.default = true;
break;
default:
Cu.reportError(Error("Unexpected blocklist state"));
}
}
this._setupDescription(label, action.pluginName, host);
this._setupLink(linkLabel, action.detailsLink);
this._primaryButton.label = gNavigatorBundle.getString(button1.label);
this._primaryButton.accesskey = gNavigatorBundle.getString(button1.accesskey);
this._primaryButton.setAttribute("action", button1.action);
this._secondaryButton.label = gNavigatorBundle.getString(button2.label);
this._secondaryButton.accesskey = gNavigatorBundle.getString(button2.accesskey);
this._secondaryButton.setAttribute("action", button2.action);
if (button1.default) {
this._primaryButton.setAttribute("default", "true");
}
else if (button2.default) {
this._secondaryButton.setAttribute("default", "true");
}
]]></body>
</method>
<method name="_setupDescription">
<parameter name="baseString" />
<parameter name="pluginName" /> <!-- null for the multiple-plugin case -->
<parameter name="host" />
<body><![CDATA[
var bsn = this._brandShortName;
var span = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-description");
while (span.lastChild) {
span.removeChild(span.lastChild);
}
if (!host) {
host = this.notification.browser.currentURI.host;
}
var args = ["__host__", this._brandShortName];
if (pluginName) {
args.unshift(pluginName);
}
var bases = gNavigatorBundle.getFormattedString(baseString, args).
split("__host__", 2);
span.appendChild(document.createTextNode(bases[0]));
var hostSpan = document.createElementNS("http://www.w3.org/1999/xhtml", "em");
hostSpan.appendChild(document.createTextNode(host));
span.appendChild(hostSpan);
span.appendChild(document.createTextNode(bases[1] + " "));
]]></body>
</method>
<method name="_setupLink">
<parameter name="linkString"/>
<parameter name="linkUrl" />
<body><![CDATA[
var link = document.getAnonymousElementByAttribute(this, "anonid", "click-to-play-plugins-notification-link");
if (!linkString || !linkUrl) {
link.hidden = true;
return;
}
link.hidden = false;
link.textContent = gNavigatorBundle.getString(linkString);
link.href = linkUrl;
]]></body>
</method>
<method name="_onButton">
<parameter name="aButton" />
<body><![CDATA[
let methodName = aButton.getAttribute("action");
this[methodName]();
]]></body>
</method>
<method name="_singleActivateNow">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
"allownow");
this._cancel();
]]></body>
</method>
<method name="_singleBlock">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
"block");
this._cancel();
]]></body>
</method>
<method name="_singleActivateAlways">
<body><![CDATA[
gPluginHandler._updatePluginPermission(this.notification,
this.notification.options.centerActions[0],
"allowalways");
this._cancel();
]]></body>
</method>
<method name="_multiAccept">
<body><![CDATA[
for (let item of this._items) {
let action = item.action;
if (action.pluginTag.enabledState == Ci.nsIPluginTag.STATE_DISABLED ||
action.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
continue;
}
gPluginHandler._updatePluginPermission(this.notification,
item.action, item.value);
}
this._cancel();
]]></body>
</method>
<method name="_cancel">
<body><![CDATA[
PopupNotifications._dismiss();
]]></body>
</method>
<method name="_accept">
<parameter name="aEvent" />
<body><![CDATA[
if (aEvent.defaultPrevented)
return;
aEvent.preventDefault();
if (this._primaryButton.getAttribute("default") == "true") {
this._primaryButton.click();
}
else if (this._secondaryButton.getAttribute("default") == "true") {
this._secondaryButton.click();
}
]]></body>
</method>
</implementation>
<handlers>
<!-- The _accept method checks for .defaultPrevented so that if focus is in a button,
enter activates the button and not this default action -->
<handler event="keypress" keycode="VK_ENTER" group="system" action="this._accept(event);"/>
<handler event="keypress" keycode="VK_RETURN" group="system" action="this._accept(event);"/>
</handlers>
</binding>
<binding id="splitmenu">

Просмотреть файл

@ -681,3 +681,11 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
<!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
<!ENTITY pluginNotification.showAll.label "Show All">
<!ENTITY pluginNotification.showAll.accesskey "S">
<!-- LOCALIZATION NOTE (pluginActivateNow.label, pluginActivateAlways.label, pluginBlockNow.label): These should be the same as the matching strings in browser.properties -->
<!ENTITY pluginActivateNow.label "Allow Now">
<!ENTITY pluginActivateAlways.label "Allow and Remember">
<!ENTITY pluginBlockNow.label "Block Plugin">

Просмотреть файл

@ -104,38 +104,65 @@ installPlugin.button.label=Install %S
installPlugin.button.accesskey=I
installPlugin.ignoreButton.label=Don't ask again
installPlugin.ignoreButton.accesskey=N
outdatedpluginsMessage.title=Some plugins used by this page are out of date.
outdatedpluginsMessage.updateButton.label=Update Plugins…
outdatedpluginsMessage.updateButton.accesskey=U
blockedpluginsMessage.title=Some plugins required by this page have been blocked for your protection.
blockedpluginsMessage.infoButton.label=Details…
blockedpluginsMessage.infoButton.accesskey=D
blockedpluginsMessage.searchButton.label=Update Plugins…
blockedpluginsMessage.searchButton.accesskey=U
crashedpluginsMessage.title=The %S plugin has crashed.
crashedpluginsMessage.reloadButton.label=Reload page
crashedpluginsMessage.reloadButton.accesskey=R
crashedpluginsMessage.submitButton.label=Submit a crash report
crashedpluginsMessage.submitButton.accesskey=S
crashedpluginsMessage.learnMore=Learn More…
activatePluginsMessage.message=Would you like to activate the plugins on this page?
activateAllPluginsMessage.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
PluginClickToActivate=Activate %S.
# LOCALIZATION NOTE - "vulnerable" indicates there is a security bug in the
# plugin that is being exploited by attackers.
PluginVulnerableUpdatable=This plugin is vulnerable and should be updated.
PluginVulnerableNoUpdate=This plugin has security vulnerabilities.
vulnerableUpdatablePluginWarning=Outdated Version!
vulnerableNoUpdatePluginWarning=Vulnerable Plugin!
vulnerablePluginsMessage=Some plugins have been deactivated for your safety.
## Plugin doorhanger strings
# LOCALIZATION NOTE (pluginActivateNw.message): Used for newly-installed
# plugins which are not known to be unsafe. %1$S is the plugin name and %2$S
# is the site domain.
pluginActivateNew.message=Allow %2$S to run "%1$S"?
pluginActivateMultiple.message=Allow %S to run plugins?
pluginActivate.learnMore=Learn More…
# LOCALIZATION NOTE (pluginActivateOutdated.message, pluginActivateOutdated.label):
# These strings are used when an unsafe plugin has an update available.
# %1$S is the plugin name, %2$S is the domain, and %3$S is brandShortName.
pluginActivateOutdated.message=%3$S has prevented the outdated plugin "%1$S" from running on %2$S.
pluginActivateOutdated.label=Outdated plugin
pluginActivate.updateLabel=Update now…
# LOCALIZATION NOTE (pluginActivateVulnerable.message, pluginActivateVulnerable.label):
# These strings are used when an unsafe plugin has no update available.
# %1$S is the plugin name, %2$S is the domain, and %3$S is brandShortName.
pluginActivateVulnerable.message=%3$S has prevented the unsafe plugin "%1$S" from running on %2$S.
pluginActivateVulnerable.label=Vulnerable plugin!
pluginActivate.riskLabel=What's the risk?
# LOCALIZATION NOTE (pluginActivateBlocked.message): %1$S is the plugin name, %2$S is brandShortName
pluginActivateBlocked.message=%2$S has blocked "%1$S" for your protection.
pluginActivateBlocked.label=Blocked for your protection
pluginActivateDisabled.message="%S" is disabled.
pluginActivateDisabled.label=Disabled
pluginActivateDisabled.manage=Manage plugins…
pluginEnabled.message="%S" is enabled on %S.
pluginEnabledOutdated.message=Outdated plugin "%S" is enabled on %S.
pluginEnabledVulnerable.message=Insecure plugin "%S" is enabled on %S.
pluginInfo.unknownPlugin=Unknown
# LOCALIZATION NOTE (pluginActivateNow.label, pluginActivateAlways.label, pluginBlockNow.label): These should be the same as the matching strings in browser.dtd
# LOCALIZATION NOTE (pluginActivateNow.label): This button will enable the
# plugin in the current session for an short time (about an hour), auto-renewed
# if the site keeps using the plugin.
pluginActivateNow.label=Allow Now
pluginActivateNow.accesskey=N
# LOCALIZATION NOTE (pluginActivateAlways.label): This button will enable the
# plugin for a long while (90 days), auto-renewed if the site keeps using the
# plugin.
pluginActivateAlways.label=Allow and Remember
pluginActivateAlways.accesskey=R
pluginBlockNow.label=Block Plugin
pluginBlockNow.accesskey=B
pluginContinue.label=Continue Allowing
pluginContinue.accesskey=C
# in-page UI
PluginClickToActivate=Activate %S.
PluginVulnerableUpdatable=Thus plugin is vulnerable and should be updated.
PluginVulnerableNoUpdate=This plugin has security vulnerabilities.
# Sanitize
# LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to
# clear" is set to "Everything", the Clear Recent History dialog's title is

Просмотреть файл

@ -2073,6 +2073,7 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css
.gcli-panel {
padding: 0;
@ -2214,106 +2215,6 @@ chatbox {
border-top-right-radius: 2.5px;
}
.click-to-play-plugins-notification-content {
margin: -10px;
}
.click-to-play-plugins-notification-icon-box {
-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-box[warn="true"] {
background-image: url("chrome://browser/skin/click-to-play-warning-stripes.png");
background-repeat: repeat-x;
padding-top: 7px;
-moz-padding-end: 11px;
padding-bottom: 9px;
-moz-padding-start: 16px;
}
.center-item-box[padbottom="true"][warn="true"] {
padding-bottom: 7px;
}
.center-item-box[showseparator="true"] {
border-top: 1px solid hsla(211,79%,6%,.1);
}
.center-item-box[warn="false"] > .center-item-warning {
display: none;
}
.center-item-warning > .text-link {
color: #3d8cd7;
}
.center-item-warning > .text-link[href=""] {
display: none;
}
.center-item-warning-icon {
background-image: url("chrome://mozapps/skin/extensions/alerticon-info-negative.png");
background-repeat: no-repeat;
width: 16px;
height: 15px;
margin-bottom: 4px;
}
.center-item-warning-description {
color: #828282;
}
.center-item-button {
min-width: 0;
}
#main-window[privatebrowsingmode=temporary] #TabsToolbar::before {
display: -moz-box;
content: "";

Просмотреть файл

@ -3575,6 +3575,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css
.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
color: hsl(210,11%,16%);
@ -3867,120 +3868,6 @@ panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .
}
}
.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-box[warn="true"] {
background-image: url("chrome://browser/skin/click-to-play-warning-stripes.png");
background-repeat: repeat-x;
padding-top: 3px;
-moz-padding-end: 11px;
padding-bottom: 9px;
-moz-padding-start: 16px;
}
.center-item-box[padbottom="true"][warn="true"] {
padding-bottom: 7px;
}
.center-item-box[showseparator="true"] {
border-top: 1px solid hsla(211,79%,6%,.1);
}
.center-item-box[warn="false"] > .center-item-warning {
display: none;
}
.center-item-warning > .text-link {
color: #3d8cd7;
}
.center-item-warning > .text-link[href=""] {
display: none;
}
.center-item-warning-icon {
background-image: url("chrome://mozapps/skin/extensions/alerticon-info-negative.png");
background-repeat: no-repeat;
width: 16px;
height: 15px;
margin-bottom: 4px;
}
.center-item-warning-description {
color: #828282;
}
.center-item-button {
min-width: 0;
}
#main-window[privatebrowsingmode=temporary] {
background-image: url("chrome://browser/skin/privatebrowsing-mask.png");
background-position: top right;

Просмотреть файл

@ -0,0 +1,56 @@
#notification-popup[popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0px;
}
.click-to-play-plugins-notification-content {
width: 28em;
}
.click-to-play-plugins-notification-center-box {
background-color: rgba(255,255,255,0.3);
}
.plugin-popupnotification-centeritem {
border-top: 1px solid ThreeDShadow;
}
.center-item-label {
margin-bottom: 0;
text-overflow: ellipsis;
}
.center-item-warning-icon {
background-image: url("chrome://mozapps/skin/extensions/alerticon-info-negative.png");
background-repeat: no-repeat;
width: 16px;
height: 15px;
-moz-margin-start: 6px;
}
.click-to-play-plugins-notification-button-container {
border-top: 1px solid ThreeDShadow;
}
.click-to-play-popup-button {
width: 50%;
}
.click-to-play-plugins-notification-description-box {
margin-left: 10px;
margin-right: 10px;
margin-top: 2px;
padding-bottom: 2px;
}
.click-to-play-plugins-outer-description {
margin-top: 8px;
}
.click-to-play-plugins-notification-description-box > .popup-notification-closebutton {
margin: 0;
}
.click-to-play-plugins-notification-link,
.center-item-link {
margin: 0;
}

Просмотреть файл

@ -2804,6 +2804,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
%include ../shared/plugin-doorhanger.inc.css
/* Error counter */
@ -2990,114 +2991,6 @@ chatbox {
border-top-right-radius: 2.5px;
}
.click-to-play-plugins-notification-content {
margin: -10px;
border-radius: 4px;
}
.click-to-play-plugins-notification-icon-box {
-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-box[warn="true"] {
background-image: url("chrome://browser/skin/click-to-play-warning-stripes.png");
background-repeat: repeat-x;
padding: 8px 16px 6px 16px;
}
.center-item-box[padbottom="true"][warn="true"] {
padding-bottom: 4px;
}
.center-item-box[showseparator="true"] {
border-top: 1px solid hsla(211,79%,6%,.1);
}
.center-item-box[warn="false"] > .center-item-warning {
display: none;
}
.center-item-warning > .text-link {
color: #3d8cd7;
}
.center-item-warning > .text-link[href=""] {
display: none;
}
.center-item-warning-icon {
background-image: url("chrome://mozapps/skin/extensions/alerticon-info-negative.png");
background-repeat: no-repeat;
width: 16px;
height: 15px;
margin-bottom: 4px;
}
.center-item-warning-description {
color: #828282;
}
.center-item-button {
min-width: 0;
}
#main-window[privatebrowsingmode=temporary] #toolbar-menubar {
background-image: url("chrome://browser/skin/privatebrowsing-dark.png");
background-position: top right;

Просмотреть файл

@ -714,7 +714,7 @@ case "$target" in
AC_DEFINE_UNQUOTED(MOZ_WINSDK_TARGETVER,0x$MOZ_WINSDK_TARGETVER)
# Definitions matching sdkddkver.h
AC_DEFINE_UNQUOTED(MOZ_NTDDI_WIN7, 0x06010000)
AC_DEFINE_UNQUOTED(MOZ_WINSDK_MAXVER,0x$MOZ_WINSDK_MAXVER)
AC_DEFINE_UNQUOTED(MOZ_WINSDK_MAXVER,$MOZ_WINSDK_MAXVER)
AC_SUBST(MOZ_WINSDK_MAXVER)
;;
esac

Просмотреть файл

@ -37,6 +37,8 @@ interface nsIObjectLoadingContent : nsISupports
const unsigned long TYPE_DOCUMENT = 3;
const unsigned long TYPE_NULL = 4;
const unsigned long PLUGIN_ACTIVE = 0xFF;
// The content type is not supported (e.g. plugin not installed)
const unsigned long PLUGIN_UNSUPPORTED = 0;
// Showing alternate content
@ -155,6 +157,10 @@ interface nsIObjectLoadingContent : nsISupports
*/
readonly attribute nsIURI srcURI;
/**
* The plugin's current state of fallback content. This property
* only makes sense if the plugin is not activated.
*/
readonly attribute unsigned long pluginFallbackType;
/**

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsStyleUtil.h"
#include "nsGUIEvent.h"
#include "nsUnicharUtils.h"
#include "mozilla/Preferences.h"
// Concrete classes
#include "nsFrameLoader.h"
@ -843,6 +844,10 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
}
}
nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(thisContent,
NS_LITERAL_STRING("PluginInstantiated"));
NS_DispatchToCurrentThread(ev);
return NS_OK;
}
@ -1830,8 +1835,8 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
// will not be checked for previews, as well as invalid plugins
// (they will not have the mContentType set).
FallbackType clickToPlayReason;
if ((mType == eType_Null || mType == eType_Plugin) &&
!ShouldPlay(clickToPlayReason)) {
if (!mActivated && (mType == eType_Null || mType == eType_Plugin) &&
!ShouldPlay(clickToPlayReason, false)) {
LOG(("OBJLC [%p]: Marking plugin as click-to-play", this));
mType = eType_Null;
fallbackType = clickToPlayReason;
@ -2718,6 +2723,17 @@ nsObjectLoadingContent::GetPluginFallbackType(uint32_t* aPluginFallbackType)
return NS_OK;
}
uint32_t
nsObjectLoadingContent::DefaultFallbackType()
{
FallbackType reason;
bool go = ShouldPlay(reason, true);
if (go) {
return PLUGIN_ACTIVE;
}
return reason;
}
NS_IMETHODIMP
nsObjectLoadingContent::GetHasRunningPlugin(bool *aHasPlugin)
{
@ -2742,11 +2758,23 @@ nsObjectLoadingContent::CancelPlayPreview()
return NS_OK;
}
static bool sPrefsInitialized;
static uint32_t sSessionTimeoutMinutes;
static uint32_t sPersistentTimeoutDays;
bool
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType)
{
nsresult rv;
if (!sPrefsInitialized) {
Preferences::AddUintVarCache(&sSessionTimeoutMinutes,
"plugin.sessionPermissionNow.intervalInMinutes", 60);
Preferences::AddUintVarCache(&sPersistentTimeoutDays,
"plugin.persistentPermissionAlways.intervalInDays", 90);
sPrefsInitialized = true;
}
nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
nsCOMPtr<nsIPluginPlayPreviewInfo> playPreviewInfo;
@ -2756,7 +2784,7 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
if (isPlayPreviewSpecified) {
playPreviewInfo->GetIgnoreCTP(&ignoreCTP);
}
if (isPlayPreviewSpecified && !mPlayPreviewCanceled && !mActivated &&
if (isPlayPreviewSpecified && !mPlayPreviewCanceled &&
ignoreCTP) {
// play preview in ignoreCTP mode is shown even if the native plugin
// is not present/installed
@ -2764,13 +2792,13 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
return false;
}
// at this point if it's not a plugin, we let it play/fallback
if (mType != eType_Plugin) {
if (!aIgnoreCurrentType && mType != eType_Plugin) {
return true;
}
// Order of checks:
// * Already activated? Then ok
// * Assume a default of click-to-play
// * If globally disabled, per-site permissions cannot override.
// * If blocklisted, override the reason with the blocklist reason
// * If not blocklisted but playPreview, override the reason with the
// playPreview reason.
@ -2779,26 +2807,31 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
// * Blocklisted plugins are forced to CtP
// * Check per-plugin permission and follow that.
if (mActivated) {
return true;
aReason = eFallbackClickToPlay;
uint32_t enabledState = nsIPluginTag::STATE_DISABLED;
pluginHost->GetStateForType(mContentType, &enabledState);
if (nsIPluginTag::STATE_DISABLED == enabledState) {
aReason = eFallbackDisabled;
return false;
}
// Before we check permissions, get the blocklist state of this plugin to set
// the fallback reason correctly.
aReason = eFallbackClickToPlay;
uint32_t blocklistState = nsIBlocklistService::STATE_NOT_BLOCKED;
pluginHost->GetBlocklistStateForType(mContentType.get(), &blocklistState);
if (blocklistState == nsIBlocklistService::STATE_BLOCKED) {
// no override possible
aReason = eFallbackBlocklisted;
return false;
}
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) {
aReason = eFallbackVulnerableUpdatable;
}
else if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
aReason = eFallbackVulnerableNoUpdate;
}
else if (blocklistState == nsIBlocklistService::STATE_BLOCKED) {
// no override possible
aReason = eFallbackBlocklisted;
return false;
}
if (aReason == eFallbackClickToPlay && isPlayPreviewSpecified &&
!mPlayPreviewCanceled && !ignoreCTP) {
@ -2842,6 +2875,13 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
permissionString.Data(),
&permission);
NS_ENSURE_SUCCESS(rv, false);
if (permission != nsIPermissionManager::UNKNOWN_ACTION) {
uint64_t nowms = PR_Now() / 1000;
permissionManager->UpdateExpireTime(
topDoc->NodePrincipal(), permissionString.Data(), false,
nowms + sSessionTimeoutMinutes * 60 * 1000,
nowms / 1000 + uint64_t(sPersistentTimeoutDays) * 24 * 60 * 60 * 1000);
}
switch (permission) {
case nsIPermissionManager::ALLOW_ACTION:
return true;
@ -2858,13 +2898,6 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
}
}
uint32_t enabledState = nsIPluginTag::STATE_DISABLED;
pluginHost->GetStateForType(mContentType, &enabledState);
if (nsIPluginTag::STATE_DISABLED == enabledState) {
aReason = eFallbackDisabled;
return false;
}
// No site-specific permissions. Vulnerable plugins are automatically CtP
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {

Просмотреть файл

@ -177,6 +177,13 @@ class nsObjectLoadingContent : public nsImageLoadingContent
{
return mURI;
}
/**
* The default state that this plugin would be without manual activation.
* @returns PLUGIN_ACTIVE if the default state would be active.
*/
uint32_t DefaultFallbackType();
uint32_t PluginFallbackType() const
{
return mFallbackType;
@ -363,8 +370,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
* If this object is allowed to play plugin content, or if it would display
* click-to-play instead.
* NOTE that this does not actually check if the object is a loadable plugin
* NOTE This ignores the current activated state. The caller should check this if appropriate.
*/
bool ShouldPlay(FallbackType &aReason);
bool ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType);
/**
* Helper to check if our current URI passes policy

Просмотреть файл

@ -508,7 +508,17 @@ this.AlarmService = {
case "webapps-clear-data":
let params =
aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams);
if (!params) {
debug("Error! Fail to remove alarms for an uninstalled app.");
return;
}
let manifestURL = appsService.getManifestURLByLocalId(params.appId);
if (!manifestURL) {
debug("Error! Fail to remove alarms for an uninstalled app.");
return;
}
this._db.getAll(
manifestURL,
function getAllSuccessCb(aAlarms) {

Просмотреть файл

@ -27,9 +27,15 @@ function debug(aMsg) {
// Implementation of the DOM API for system messages
function SystemMessageManager() {
// Message handlers for this page.
// We can have only one handler per message type.
this._handlers = {};
// If we have a system message handler registered for messages of type
// |type|, this._dispatchers[type] equals {handler, messages, isHandling},
// where
// - |handler| is the message handler that the page registered,
// - |messages| is a list of messages which we've received while
// dispatching messages to the handler, but haven't yet sent, and
// - |isHandling| indicates whether we're currently dispatching messages
// to this handler.
this._dispatchers = {};
// Pending messages for this page, keyed by message type.
this._pendings = {};
@ -52,7 +58,21 @@ function SystemMessageManager() {
SystemMessageManager.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
_dispatchMessage: function sysMessMgr_dispatchMessage(aType, aHandler, aMessage) {
_dispatchMessage: function sysMessMgr_dispatchMessage(aType, aDispatcher, aMessage) {
if (aDispatcher.isHandling) {
// Queue up the incomming message if we're currently dispatching a
// message; we'll send the message once we finish with the current one.
//
// _dispatchMethod is reentrant because a page can spin up a nested
// event loop from within a system message handler (e.g. via alert()),
// and we can then try to send the page another message while it's
// inside this nested event loop.
aDispatcher.messages.push(aMessage);
return;
}
aDispatcher.isHandling = true;
// We get a json blob, but in some cases we want another kind of object
// to be dispatched.
// To do so, we check if we have a with a contract ID of
@ -72,8 +92,22 @@ SystemMessageManager.prototype = {
}
}
aHandler.handleMessage(wrapped ? aMessage
aDispatcher.handler
.handleMessage(wrapped ? aMessage
: ObjectWrapper.wrap(aMessage, this._window));
// We need to notify the parent one of the system messages has been handled,
// so the parent can release the CPU wake lock it took on our behalf.
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessagesDone",
{ type: aType,
manifest: this._manifest,
uri: this._uri,
handledCount: 1 });
aDispatcher.isHandling = false;
if (aDispatcher.messages.length > 0) {
this._dispatchMessage(aType, aDispatcher, aDispatcher.messages.shift());
}
},
mozSetMessageHandler: function sysMessMgr_setMessageHandler(aType, aHandler) {
@ -90,16 +124,16 @@ SystemMessageManager.prototype = {
return;
}
let handlers = this._handlers;
let dispatchers = this._dispatchers;
if (!aHandler) {
// Setting the handler to null means we don't want to receive messages
// of this type anymore.
delete handlers[aType];
// Setting the dispatcher to null means we don't want to handle messages
// for this type anymore.
delete dispatchers[aType];
return;
}
// Last registered handler wins.
handlers[aType] = aHandler;
dispatchers[aType] = { handler: aHandler, messages: [], isHandling: false };
// Ask for the list of currently pending messages.
cpmm.sendAsyncMessage("SystemMessageManager:GetPendingMessages",
@ -118,7 +152,7 @@ SystemMessageManager.prototype = {
}
// If we have a handler for this type, we can't have any pending message.
if (aType in this._handlers) {
if (aType in this._dispatchers) {
return false;
}
@ -129,7 +163,7 @@ SystemMessageManager.prototype = {
},
uninit: function sysMessMgr_uninit() {
this._handlers = null;
this._dispatchers = null;
this._pendings = null;
if (this._isParentProcess) {
@ -187,25 +221,28 @@ SystemMessageManager.prototype = {
: msg.msgQueue;
// We only dispatch messages when a handler is registered.
let handler = this._handlers[msg.type];
if (handler) {
let dispatcher = this._dispatchers[msg.type];
if (dispatcher) {
messages.forEach(function(aMsg) {
this._dispatchMessage(msg.type, handler, aMsg);
this._dispatchMessage(msg.type, dispatcher, aMsg);
}, this);
}
// We need to notify the parent the system messages have been handled,
// even if there are no handlers registered for them, so the parent can
// release the CPU wake lock it took on our behalf.
} else {
// We need to notify the parent that all the queued system messages have
// been handled (notice |handledCount: messages.length|), so the parent
// can release the CPU wake lock it took on our behalf.
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessagesDone",
{ type: msg.type,
manifest: this._manifest,
uri: this._uri,
handledCount: messages.length });
}
if (!dispatcher || !dispatcher.isHandling) {
// TODO: Bug 874353 - Remove SystemMessageHandledListener in ContentParent
Services.obs.notifyObservers(/* aSubject */ null,
"handle-system-messages-done",
/* aData */ null);
}
},
// nsIDOMGlobalPropertyInitializer implementation.
@ -272,7 +309,8 @@ SystemMessageManager.prototype = {
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsIObserver]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
classInfo: XPCOMUtils.generateCI({
classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
contractID: "@mozilla.org/system-message-manager;1",
interfaces: [Ci.nsIDOMNavigatorSystemMessages],
flags: Ci.nsIClassInfo.DOM_OBJECT,

Просмотреть файл

@ -1454,7 +1454,7 @@ MmsService.prototype = {
send: function send(aParams, aRequest) {
if (DEBUG) debug("send: aParams: " + JSON.stringify(aParams));
if (aParams.receivers.length == 0) {
aRequest.notifySendMmsMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
aRequest.notifySendMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR);
return;
}
@ -1497,14 +1497,14 @@ MmsService.prototype = {
if (DEBUG) debug("Saving sending message is done. Start to send.");
// For radio disabled error.
if(gMmsConnection.radioDisabled) {
if (gMmsConnection.radioDisabled) {
if (DEBUG) debug("Error! Radio is disabled when sending MMS.");
sendTransactionCb(aDomMessage.id, Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR);
return;
}
// For SIM card is not ready.
if(gRIL.rilContext.cardState != "ready") {
if (gRIL.rilContext.cardState != "ready") {
if (DEBUG) debug("Error! SIM card is not ready when sending MMS.");
sendTransactionCb(aDomMessage.id, Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR);
return;

Просмотреть файл

@ -20,7 +20,7 @@ interface nsIPluginPlayPreviewInfo : nsISupports
readonly attribute AUTF8String redirectURL;
};
[scriptable, uuid(15f97490-7bdf-4947-885c-9258072af878)]
[scriptable, uuid(e8fe94f0-b877-46d0-931a-090967fb1e83)]
interface nsIPluginHost : nsISupports
{
/**
@ -97,9 +97,24 @@ interface nsIPluginHost : nsISupports
ACString getPermissionStringForType(in AUTF8String mimeType);
/**
* Get the nsIPluginTag for this MIME type. This method works with both
* enabled and disabled/blocklisted plugins, but an enabled plugin will
* always be returned if available.
*
* @throws NS_ERROR_NOT_AVAILABLE if no plugin is available for this MIME
* type.
*/
nsIPluginTag getPluginTagForType(in AUTF8String mimeType);
/**
* Get the nsIPluginTag state for this MIME type.
*/
unsigned long getStateForType(in AUTF8String mimeType);
/**
* Get the blocklist state for a MIME type.
*/
uint32_t getBlocklistStateForType(in string aMimeType);
};

Просмотреть файл

@ -1051,10 +1051,28 @@ nsPluginHost::PluginExistsForType(const char* aMimeType)
return nullptr != plugin;
}
NS_IMETHODIMP
nsPluginHost::GetPluginTagForType(const nsACString& aMimeType,
nsIPluginTag** aResult)
{
nsPluginTag* plugin = FindPluginForType(aMimeType.Data(), true);
if (!plugin) {
plugin = FindPluginForType(aMimeType.Data(), false);
}
if (!plugin) {
return NS_ERROR_NOT_AVAILABLE;
}
NS_ADDREF(*aResult = plugin);
return NS_OK;
}
NS_IMETHODIMP
nsPluginHost::GetStateForType(const nsACString &aMimeType, uint32_t* aResult)
{
nsPluginTag *plugin = FindPluginForType(aMimeType.Data(), true);
if (!plugin) {
plugin = FindPluginForType(aMimeType.Data(), false);
}
if (!plugin) {
return NS_ERROR_UNEXPECTED;
}
@ -1062,7 +1080,7 @@ nsPluginHost::GetStateForType(const nsACString &aMimeType, uint32_t* aResult)
return plugin->GetEnabledState(aResult);
}
nsresult
NS_IMETHODIMP
nsPluginHost::GetBlocklistStateForType(const char *aMimeType, uint32_t *aState)
{
nsPluginTag *plugin = FindPluginForType(aMimeType, true);

Просмотреть файл

@ -82,7 +82,6 @@ public:
bool PluginExistsForType(const char* aMimeType);
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
nsresult GetBlocklistStateForType(const char *aMimeType, uint32_t *state);
nsresult GetPluginCount(uint32_t* aPluginCount);
nsresult GetPlugins(uint32_t aPluginCount, nsIDOMPlugin** aPluginArray);

Просмотреть файл

@ -63,8 +63,9 @@
function afterWindowFocus() {
var plugin = document.getElementById('plugin');
var objLoadingContent = SpecialPowers.wrap(plugin);
synthesizeMouseAtCenter(plugin, {});
objLoadingContent.playPlugin();
var condition = function() plugin.setColor !== undefined;
waitForCondition(condition, afterPluginActivation, "Waited too long for plugin to activate");
}

Просмотреть файл

@ -2840,6 +2840,30 @@ RadioInterfaceLayer.prototype = {
// TODO bug 832140 handle !Components.isSuccessCode(rv)
Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null);
// If the radio is disabled or the SIM card is not ready, just directly
// return with the corresponding error code.
let errorCode;
if (!this._radioEnabled) {
debug("Error! Radio is disabled when sending SMS.");
errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
} else if (this.rilContext.cardState != "ready") {
debug("Error! SIM card is not ready when sending SMS.");
errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
}
if (errorCode) {
gMobileMessageDatabaseService
.setMessageDelivery(domMessage.id,
null,
DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
function notifyResult(rv, domMessage) {
// TODO bug 832140 handle !Components.isSuccessCode(rv)
request.notifySendMessageFailed(errorCode);
Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
});
return;
}
// Keep current SMS message info for sent/delivered notifications
options.envelopeId = this.createSmsEnvelope({
request: request,

Просмотреть файл

@ -176,6 +176,9 @@ interface MozObjectLoadingContent {
[ChromeOnly]
readonly attribute URI? srcURI;
[ChromeOnly]
readonly attribute unsigned long defaultFallbackType;
[ChromeOnly]
readonly attribute unsigned long pluginFallbackType;

Просмотреть файл

@ -85,6 +85,7 @@ DOMWifiManager.prototype = {
"WifiManager:forget:Return:OK", "WifiManager:forget:Return:NO",
"WifiManager:wps:Return:OK", "WifiManager:wps:Return:NO",
"WifiManager:setPowerSavingMode:Return:OK", "WifiManager:setPowerSavingMode:Return:NO",
"WifiManager:setStaticIpMode:Return:OK", "WifiManager:setStaticIpMode:Return:NO",
"WifiManager:wifiDown", "WifiManager:wifiUp",
"WifiManager:onconnecting", "WifiManager:onassociate",
"WifiManager:onconnect", "WifiManager:ondisconnect",
@ -191,6 +192,16 @@ DOMWifiManager.prototype = {
Services.DOMRequest.fireError(request, msg.data);
break;
case "WifiManager:setStaticIpMode:Return:OK":
request = this.takeRequest(msg.rid);
Services.DOMRequest.fireSuccess(request, exposeReadOnly(msg.data));
break;
case "WifiManager:setStaticIpMode:Return:NO":
request = this.takeRequest(msg.rid);
Services.DOMRequest.fireError(request, msg.data);
break;
case "WifiManager:wifiDown":
this._enabled = false;
this._currentNetwork = null;
@ -347,6 +358,14 @@ DOMWifiManager.prototype = {
return request;
},
setStaticIpMode: function nsIDOMWifiManager_setStaticIpMode(network, info) {
if (!this._hasPrivileges)
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);
var request = this.createRequest();
this._sendMessageForRequest("WifiManager:setStaticIpMode", {network: network,info: info}, request);
return request;
},
get enabled() {
if (!this._hasPrivileges)
throw new Components.Exception("Denied", Cr.NS_ERROR_FAILURE);

Просмотреть файл

@ -11,7 +11,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
var DEBUG = false; // set to true to show debug messages
var DEBUG = false; // set to true to show debug messages.
const WIFIWORKER_CONTRACTID = "@mozilla.org/wifi/worker;1";
const WIFIWORKER_CID = Components.ID("{a14e8977-d259-433a-a88d-58dd44657e5b}");
@ -137,7 +137,7 @@ var WifiManager = (function() {
// Polling the status worker
var recvErrors = 0;
eventWorker.onmessage = function(e) {
// process the event and tell the event worker to listen for more events
// Process the event and tell the event worker to listen for more events.
if (handleEvent(e.data.event))
waitForEvent();
};
@ -146,7 +146,7 @@ var WifiManager = (function() {
eventWorker.postMessage({ cmd: "wait_for_event" });
}
// Commands to the control worker
// Commands to the control worker.
function voidControlMessage(cmd, callback) {
controlMessage({ cmd: cmd }, function (data) {
@ -616,11 +616,77 @@ var WifiManager = (function() {
});
}
var staticIpConfig = Object.create(null);
function setStaticIpMode(network, info, callback) {
let setNetworkKey = getNetworkKey(network);
let curNetworkKey = null;
let currentNetwork = Object.create(null);
currentNetwork.netId = manager.connectionInfo.id;
manager.getNetworkConfiguration(currentNetwork, function (){
curNetworkKey = getNetworkKey(currentNetwork);
// Add additional information to static ip configuration
// It is used to compatiable with information dhcp callback.
info.ipaddr = stringToIp(info.ipaddr_str);
info.gateway = stringToIp(info.gateway_str);
info.mask_str = makeMask(info.maskLength);
// Optional
info.dns1 = stringToIp("dns1_str" in info ? info.dns1_str : "");
info.dns2 = stringToIp("dns2_str" in info ? info.dns2_str : "");
info.proxy = stringToIp("proxy_str" in info ? info.proxy_str : "");
staticIpConfig[setNetworkKey] = info;
// If the ssid of current connection is the same as configured ssid
// It means we need update current connection to use static IP address.
if (setNetworkKey == curNetworkKey) {
// Use configureInterface directly doesn't work, the network iterface
// and routing table is changed but still cannot connect to network
// so the workaround here is disable interface the enable again to
// trigger network reconnect with static ip.
disableInterface(manager.ifname, function (ok) {
enableInterface(manager.ifname, function (ok) {
});
});
}
});
}
var dhcpInfo = null;
function runDhcp(ifname, callback) {
function runDhcp(ifname) {
debug("Run Dhcp");
controlMessage({ cmd: "dhcp_do_request", ifname: ifname }, function(data) {
dhcpInfo = data.status ? null : data;
callback(dhcpInfo);
runIpConfig(ifname, dhcpInfo);
});
}
function runStaticIp(ifname, key) {
debug("Run static ip");
// Read static ip information from settings.
let staticIpInfo;
if (!(key in staticIpConfig))
return;
staticIpInfo = staticIpConfig[key];
// Stop dhcpd when use static IP
if (dhcpInfo != null) {
stopDhcp(manager.ifname, function() {});
}
// Set ip, mask length, gateway, dns to network interface
configureInterface(ifname,
staticIpInfo.ipaddr,
staticIpInfo.maskLength,
staticIpInfo.gateway,
staticIpInfo.dns1,
staticIpInfo.dns2, function (data) {
runIpConfig(ifname, staticIpInfo);
});
}
@ -767,7 +833,7 @@ var WifiManager = (function() {
return;
}
if (connectTries++ < 3) {
// try again in 5 seconds
// Try again in 5 seconds.
if (!retryTimer)
retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@ -803,32 +869,48 @@ var WifiManager = (function() {
function onconnected() {
// For now we do our own DHCP. In the future, this should be handed
// off to the Network Manager.
runDhcp(manager.ifname, function (data) {
if (!data) {
debug("DHCP failed to run");
notify("dhcpconnected", { info: data });
let currentNetwork = Object.create(null);
currentNetwork.netId = manager.connectionInfo.id;
manager.getNetworkConfiguration(currentNetwork, function (){
let key = getNetworkKey(currentNetwork);
if (staticIpConfig &&
(key in staticIpConfig) &&
staticIpConfig[key].enabled) {
debug("Run static ip");
runStaticIp(manager.ifname, key);
return;
}
setProperty("net." + manager.ifname + ".dns1", ipToString(data.dns1),
runDhcp(manager.ifname);
});
}
function runIpConfig(name, data) {
if (!data) {
debug("IP config failed to run");
notify("networkconnected", { info: data });
return;
}
setProperty("net." + name + ".dns1", ipToString(data.dns1),
function(ok) {
if (!ok) {
debug("Unable to set net.<ifname>.dns1");
return;
}
setProperty("net." + manager.ifname + ".dns2", ipToString(data.dns2),
setProperty("net." + name + ".dns2", ipToString(data.dns2),
function(ok) {
if (!ok) {
debug("Unable to set net.<ifname>.dns2");
return;
}
setProperty("net." + manager.ifname + ".gw", ipToString(data.gateway),
setProperty("net." + name + ".gw", ipToString(data.gateway),
function(ok) {
if (!ok) {
debug("Unable to set net.<ifname>.gw");
return;
}
notify("dhcpconnected", { info: data });
});
notify("networkconnected", { info: data });
});
});
});
@ -865,7 +947,7 @@ var WifiManager = (function() {
});
}
// handle events sent to us by the event worker
// Handle events sent to us by the event worker.
function handleEvent(event) {
debug("Event coming in: " + event);
if (event.indexOf("CTRL-EVENT-") !== 0 && event.indexOf("WPS") !== 0) {
@ -898,7 +980,7 @@ var WifiManager = (function() {
var space = event.indexOf(" ");
var eventData = event.substr(0, space + 1);
if (eventData.indexOf("CTRL-EVENT-STATE-CHANGE") === 0) {
// Parse the event data
// Parse the event data.
var fields = {};
var tokens = event.substr(space + 1).split(" ");
for (var n = 0; n < tokens.length; ++n) {
@ -938,7 +1020,7 @@ var WifiManager = (function() {
}
// As long we haven't seen too many recv errors yet, we
// will keep going for a bit longer
// will keep going for a bit longer.
if (eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
return true;
@ -976,8 +1058,11 @@ var WifiManager = (function() {
if (eventData.indexOf("CTRL-EVENT-CONNECTED") === 0) {
// Format: CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]
var bssid = event.split(" ")[4];
var id = event.substr(event.indexOf("id=")).split(" ")[0];
var keyword = "id=";
var id = event.substr(event.indexOf(keyword) + keyword.length).split(" ")[0];
// Read current BSSID here, it will always being provided.
manager.connectionInfo.id = id;
manager.connectionInfo.bssid = bssid;
return true;
}
@ -1002,7 +1087,7 @@ var WifiManager = (function() {
notifyStateChange({ state: "WPS_OVERLAP_DETECTED", BSSID: null, id: -1 });
return true;
}
// unknown event
// Unknown event.
return true;
}
@ -1065,7 +1150,7 @@ var WifiManager = (function() {
});
}
// Initial state
// Initial state.
manager.state = "UNINITIALIZED";
manager.tetheringState = "UNINITIALIZED";
manager.enabled = false;
@ -1089,7 +1174,7 @@ var WifiManager = (function() {
Ci.nsITimer.TYPE_ONE_SHOT);
};
// Public interface of the wifi service
// Public interface of the wifi service.
manager.setWifiEnabled = function(enable, callback) {
if (enable === manager.enabled) {
callback("no change");
@ -1241,7 +1326,7 @@ var WifiManager = (function() {
var networkConfigurationFields = [
"ssid", "bssid", "psk", "wep_key0", "wep_key1", "wep_key2", "wep_key3",
"wep_tx_keyidx", "priority", "key_mgmt", "scan_ssid", "disabled",
"identity", "password", "auth_alg"
"identity", "password", "auth_alg", "phase1", "phase2", "eap"
];
manager.getNetworkConfiguration = function(config, callback) {
@ -1281,7 +1366,7 @@ var WifiManager = (function() {
});
}
}
// If config didn't contain any of the fields we want, don't lose the error callback
// If config didn't contain any of the fields we want, don't lose the error callback.
if (done == networkConfigurationFields.length)
callback(false);
}
@ -1318,7 +1403,7 @@ var WifiManager = (function() {
++errors;
if (++done == lines.length - 1) {
if (errors) {
// If an error occured, delete the new netId
// If an error occured, delete the new netId.
removeNetworkCommand(netId, function() {
callback(null);
});
@ -1357,6 +1442,43 @@ var WifiManager = (function() {
((n >> 24) & 0xFF);
}
function stringToIp(string) {
let ip = 0;
let start, end = -1;
for (let i = 0; i < 4; i++) {
start = end + 1;
end = string.indexOf(".", start);
if (end == -1) {
end = string.length;
}
let num = parseInt(string.slice(start, end), 10);
if (isNaN(num)) {
return 0;
}
ip |= num << (i * 8);
}
return ip;
}
function swap32(n) {
return (((n >> 24) & 0xFF) << 0) |
(((n >> 16) & 0xFF) << 8) |
(((n >> 8) & 0xFF) << 16) |
(((n >> 0) & 0xFF) << 24);
}
function ntohl(n) {
return swap32(n);
}
function makeMask(len) {
let mask = 0;
for (let i = 0; i < len; ++i) {
mask |= (0x80000000 >> i);
}
return ntohl(mask);
}
manager.saveConfig = function(callback) {
saveConfigCommand(callback);
}
@ -1378,6 +1500,7 @@ var WifiManager = (function() {
manager.wpsCancel = wpsCancelCommand;
manager.setPowerMode = setPowerModeCommand;
manager.setSuspendOptimizations = setSuspendOptimizationsCommand;
manager.setStaticIpMode = setStaticIpMode;
manager.getRssiApprox = getRssiApproxCommand;
manager.getLinkSpeed = getLinkSpeedCommand;
manager.getDhcpInfo = function() { return dhcpInfo; }
@ -1499,7 +1622,7 @@ function getNetworkKey(network)
// ssid here must be dequoted, and it's safer to esacpe it.
// encryption won't be empty and always be assigned one of the followings :
// "OPEN"/"WEP"/"WPA-PSK"/"WPA-EAP".
// So for a invalid network object, the returned key will be "OPEN"
// So for a invalid network object, the returned key will be "OPEN".
return escape(ssid) + encryption;
}
@ -1560,7 +1683,10 @@ Network.api = {
psk: "rw",
identity: "rw",
wep: "rw",
hidden: "rw"
hidden: "rw",
eap: "rw",
phase1: "rw",
phase2: "rw"
};
// Note: We never use ScanResult.prototype, so the fact that it's unrelated to
@ -1665,6 +1791,7 @@ function WifiWorker() {
"WifiManager:associate", "WifiManager:forget",
"WifiManager:wps", "WifiManager:getState",
"WifiManager:setPowerSavingMode",
"WifiManager:setStaticIpMode",
"child-process-shutdown"];
messages.forEach((function(msgName) {
@ -1679,10 +1806,10 @@ function WifiWorker() {
this._needToEnableNetworks = false;
this._highestPriority = -1;
// networks is a map from SSID -> a scan result.
// Networks is a map from SSID -> a scan result.
this.networks = Object.create(null);
// configuredNetworks is a map from SSID -> our view of a network. It only
// ConfiguredNetworks is a map from SSID -> our view of a network. It only
// lists networks known to the wpa_supplicant. The SSID field (and other
// fields) are quoted for ease of use with WifiManager commands.
// Note that we don't have to worry about escaping embedded quotes since in
@ -1821,6 +1948,12 @@ function WifiWorker() {
configured.auth_alg = net.auth_alg = "OPEN SHARED";
}
if ("phase1" in net)
net.phase1 = quote(net.phase1);
if ("phase2" in net)
net.phase2 = quote(net.phase2);
return net;
};
@ -2024,7 +2157,7 @@ function WifiWorker() {
}
};
WifiManager.ondhcpconnected = function() {
WifiManager.onnetworkconnected = function() {
if (this.info) {
WifiNetworkInterface.state =
Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED;
@ -2152,7 +2285,7 @@ function WifiWorker() {
// Read the 'wifi.enabled' setting in order to start with a known
// value at boot time. The handle() will be called after reading.
//
// nsISettingsServiceCallback implementation
// nsISettingsServiceCallback implementation.
var initWifiEnabledCb = {
handle: function handle(aName, aResult) {
if (aName !== SETTINGS_WIFI_ENABLED)
@ -2501,6 +2634,9 @@ WifiWorker.prototype = {
case "WifiManager:setPowerSavingMode":
this.setPowerSavingMode(msg);
break;
case "WifiManager:setStaticIpMode":
this.setStaticIpMode(msg);
break;
case "WifiManager:getState": {
let i;
if ((i = this._domManagers.indexOf(msg.manager)) === -1) {
@ -2970,6 +3106,30 @@ WifiWorker.prototype = {
});
},
setStaticIpMode: function(msg) {
const message = "WifiManager:setStaticMode:Return";
let self = this;
let network = msg.data.network;
let info = msg.data.info;
netFromDOM(network, null);
// To compatiable with DHCP returned info structure, do translation here
info.ipaddr_str = info.ipaddr;
info.proxy_str = info.proxy;
info.gateway_str = info.gateway;
info.dns1_str = info.dns1;
info.dns2_str = info.dns2;
WifiManager.setStaticIpMode(network, info, function(ok) {
if (ok) {
self._sendMessage(message, true, true, msg);
} else {
self._sendMessage(message, false, "Set static ip mode failed", msg);
}
});
},
// This is a bit ugly, but works. In particular, this depends on the fact
// that RadioManager never actually tries to get the worker from us.
get worker() { throw "Not implemented"; },

Просмотреть файл

@ -59,7 +59,7 @@ interface nsIWifi : nsISupports
void getWifiScanResults(in nsIWifiScanResultsReady callback);
};
[scriptable, uuid(caa76ee3-8ffe-4ea5-bc59-3b53a9df0d07)]
[scriptable, uuid(3f21012d-6e75-4632-b87c-acdd7c57fbf3)]
interface nsIDOMWifiManager : nsISupports
{
/**
@ -126,6 +126,23 @@ interface nsIDOMWifiManager : nsISupports
*/
nsIDOMDOMRequest setPowerSavingMode(in boolean enabled);
/**
* Given a network, configure using static IP instead of running DHCP
* @param network A network object with the SSID of the network to set static ip.
* @param info info should have following field:
* - enabled True to enable static IP, false to use DHCP
* - ipaddr configured static IP address
* - proxy configured proxy server address
* - maskLength configured mask length
* - gateway configured gateway address
* - dns1 configured first DNS server address
* - dns2 configured seconf DNS server address
* onsuccess: We have successfully configure the static ip mode.
* onerror: We have failed to configure the static ip mode.
*/
nsIDOMDOMRequest setStaticIpMode(in jsval network,
in jsval info);
/**
* Returns whether or not wifi is currently enabled.
*/

Просмотреть файл

@ -1806,3 +1806,59 @@ nsPermissionManager::ReleaseAppId(uint32_t aAppId)
return NS_OK;
}
NS_IMETHODIMP
nsPermissionManager::UpdateExpireTime(nsIPrincipal* aPrincipal,
const char* aType,
bool aExactHostMatch,
uint64_t aSessionExpireTime,
uint64_t aPersistentExpireTime)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aType);
uint64_t nowms = PR_Now() / 1000;
if (aSessionExpireTime < nowms || aPersistentExpireTime < nowms) {
return NS_ERROR_INVALID_ARG;
}
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
return NS_OK;
}
nsAutoCString host;
nsresult rv = GetHostForPrincipal(aPrincipal, host);
NS_ENSURE_SUCCESS(rv, rv);
int32_t typeIndex = GetTypeIndex(aType, false);
// If type == -1, the type isn't known,
// so just return NS_OK
if (typeIndex == -1) return NS_OK;
uint32_t appId;
rv = aPrincipal->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
bool isInBrowserElement;
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
PermissionHashKey* entry = GetPermissionHashKey(host, appId, isInBrowserElement,
typeIndex, aExactHostMatch);
if (!entry) {
return NS_OK;
}
int32_t idx = entry->GetPermissionIndex(typeIndex);
if (-1 == idx) {
return NS_OK;
}
PermissionEntry& perm = entry->GetPermissions()[idx];
if (perm.mExpireType == EXPIRE_TIME) {
perm.mExpireTime = aPersistentExpireTime;
} else if (perm.mExpireType == EXPIRE_SESSION && perm.mExpireTime != 0) {
perm.mExpireTime = aSessionExpireTime;
}
return NS_OK;
}

Просмотреть файл

@ -40,10 +40,20 @@ function do_run_test() {
// add a permission without expiration
pm.addFromPrincipal(principal, "test/expiration-perm-nexp", 1, pm.EXPIRE_NEVER, 0);
// add a permission for renewal
pm.addFromPrincipal(principal, "test/expiration-perm-renewable", 1, pm.EXPIRE_TIME, now + 100);
pm.addFromPrincipal(principal, "test/expiration-session-renewable", 1, pm.EXPIRE_SESSION, now + 100);
// And immediately renew them with longer timeouts
pm.updateExpireTime(principal, "test/expiration-perm-renewable", true, now + 100, now + 1e6);
pm.updateExpireTime(principal, "test/expiration-session-renewable", true, now + 1e6, now + 100);
// check that the second two haven't expired yet
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-exp3"));
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-session-exp3"));
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-nexp"));
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-renewable"));
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-session-renewable"));
// ... and the first one has
do_timeout(10, continue_test);
@ -63,6 +73,10 @@ function do_run_test() {
do_check_null(pm.getPermissionObject(principal, "test/expiration-perm-exp2", false));
do_check_null(pm.getPermissionObject(principal, "test/expiration-session-exp2", false));
// Check that the renewable permissions actually got renewed
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-perm-renewable"));
do_check_eq(1, pm.testPermissionFromPrincipal(principal, "test/expiration-session-renewable"));
do_finish_generator_test(test_generator);
}

Просмотреть файл

@ -45,7 +45,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'PathD2D.cpp',
'ScaledFontDWrite.cpp',
]
if CONFIG['MOZ_WINSDK_MAXVER'] >= 06020000:
if CONFIG['MOZ_WINSDK_MAXVER'] >= '0x06020000':
CPP_SOURCES += [
'RadialGradientEffectD2D1.cpp'
]

Просмотреть файл

@ -1855,6 +1855,13 @@ pref("plugins.click_to_play", false);
// The default value for nsIPluginTag.enabledState (STATE_ENABLED = 2)
pref("plugin.default.state", 2);
// How long in minutes we will allow a plugin to work after the user has chosen
// to allow it "now"
pref("plugin.sessionPermissionNow.intervalInMinutes", 60);
// How long in days we will allow a plugin to work after the user has chosen
// to allow it persistently.
pref("plugin.persistentPermissionAlways.intervalInDays", 90);
#ifndef DEBUG
// How long a plugin is allowed to process a synchronous IPC message
// before we consider it "hung".

Просмотреть файл

@ -37,7 +37,7 @@ interface nsIPrincipal;
interface nsIDOMWindow;
interface nsIPermission;
[scriptable, uuid(f75e0a32-04cd-4ed4-ad2d-d08ca92bb98e)]
[scriptable, uuid(c9fec678-f194-43c9-96b0-7bd9dbdd6bb0)]
interface nsIPermissionManager : nsISupports
{
/**
@ -230,6 +230,26 @@ interface nsIPermissionManager : nsISupports
*/
void removePermissionsForApp(in unsigned long appId,
in boolean browserOnly);
/**
* If the current permission is set to expire, reset the expiration time. If
* there is no permission or the current permission does not expire, this
* method will silently return.
*
* @param sessionExpiretime an integer representation of when this permission
* should be forgotten (milliseconds since
* Jan 1 1970 0:00:00), if it is currently
* EXPIRE_SESSION.
* @param sessionExpiretime an integer representation of when this permission
* should be forgotten (milliseconds since
* Jan 1 1970 0:00:00), if it is currently
* EXPIRE_TIME.
*/
void updateExpireTime(in nsIPrincipal principal,
in string type,
in boolean exactHost,
in uint64_t sessionExpireTime,
in uint64_t persistentExpireTime);
};
%{ C++

Просмотреть файл

@ -43,6 +43,6 @@ class CentOSBootstrapper(BaseBootstrapper):
self.run_as_root(['rpm', '-ivh', yasm])
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self.yum_update('mercurial')

Просмотреть файл

@ -32,5 +32,5 @@ class FedoraBootstrapper(BaseBootstrapper):
'wireless-tools-devel',
'yasm')
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self.yum_update('mercurial')

Просмотреть файл

@ -21,5 +21,5 @@ class GentooBootstrapper(BaseBootstrapper):
def _update_package_manager(self):
self.run_as_root(['emerge', '--sync'])
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self.run_as_root(['emerge', '--update', 'mercurial'])

Просмотреть файл

@ -30,5 +30,5 @@ class MintBootstrapper(BaseBootstrapper):
'uuid',
'yasm')
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self.apt_install('mercurial')

Просмотреть файл

@ -28,6 +28,6 @@ class OpenBSDBootstrapper(BaseBootstrapper):
def _update_package_manager(self):
self.run_as_root(['port', 'sync'])
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self.run_as_root(['pkg_add', '-u', 'mercurial'])

Просмотреть файл

@ -33,7 +33,7 @@ class UbuntuBootstrapper(BaseBootstrapper):
def _update_package_manager(self):
self.run_as_root(['apt-get', 'update'])
def upgrade_mercurial(self):
def upgrade_mercurial(self, current):
self._ensure_package_manager_updated()
self.apt_install('mercurial')

Просмотреть файл

@ -118,7 +118,7 @@ function part6() {
}
function part7() {
ok(!PopupNotifications.getNotification("click-to-play-plugins", gPluginBrowser), "part7: should not have a click-to-play notification");
ok(PopupNotifications.getNotification("click-to-play-plugins", gPluginBrowser), "part7: disabled plugins still show a notification");
let testPlugin = gPluginBrowser.contentDocument.getElementById("test");
ok(testPlugin, "part7: should have a plugin element in the page");
let objLoadingContent = testPlugin.QueryInterface(Ci.nsIObjectLoadingContent);

Просмотреть файл

@ -388,7 +388,6 @@ INNER_UNMAKE_PACKAGE = \
mv lib/$(ABI_DIR)/libmozglue.so . && \
mv lib/$(ABI_DIR)/*plugin-container* $(MOZ_CHILD_PROCESS_NAME) && \
mv $(ASSET_SO_LIBRARIES) . && \
rm -rf assets && \
rm -rf lib/$(ABI_DIR) )
endif