mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 760625 - use the blocklist to inform click-to-play plugins. r=joshmoz,bmcbride
This commit is contained in:
parent
665908a65f
commit
679f55960f
@ -140,6 +140,12 @@ var gPluginHandler = {
|
||||
self.pluginUnavailable(plugin, event.type);
|
||||
break;
|
||||
|
||||
case "PluginVulnerableUpdatable":
|
||||
let updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
self.addLinkClickCallback(updateLink, "openPluginUpdatePage");
|
||||
/* FALLTHRU */
|
||||
|
||||
case "PluginVulnerableNoUpdate":
|
||||
case "PluginClickToPlay":
|
||||
self._handleClickToPlayEvent(plugin);
|
||||
break;
|
||||
@ -151,9 +157,10 @@ var gPluginHandler = {
|
||||
}
|
||||
|
||||
// Hide the in-content UI if it's too big. The crashed plugin handler already did this.
|
||||
if (event.type != "PluginCrashed" && event.type != "PluginClickToPlay") {
|
||||
if (event.type != "PluginCrashed") {
|
||||
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
if (self.isTooSmall(plugin, overlay))
|
||||
/* overlay might be null, so only operate on it if it exists */
|
||||
if (overlay != null && self.isTooSmall(plugin, overlay))
|
||||
overlay.style.visibility = "hidden";
|
||||
}
|
||||
},
|
||||
@ -224,6 +231,12 @@ var gPluginHandler = {
|
||||
managePlugins: function (aEvent) {
|
||||
BrowserOpenAddonsMgr("addons://list/plugin");
|
||||
},
|
||||
|
||||
// Callback for user clicking on the link in a click-to-play plugin
|
||||
// (where the plugin has an update)
|
||||
openPluginUpdatePage: function (aEvent) {
|
||||
openURL(Services.urlFormatter.formatURLPref("plugins.update.url"));
|
||||
},
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Callback for user clicking "submit a report" link
|
||||
@ -258,15 +271,18 @@ var gPluginHandler = {
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
} else if (pluginsPermission == Ci.nsIPermissionManager.DENY_ACTION) {
|
||||
overlay.style.visibility = "hidden";
|
||||
if (overlay)
|
||||
overlay.style.visibility = "hidden";
|
||||
return;
|
||||
}
|
||||
|
||||
let overlay = doc.getAnonymousElementByAttribute(aPlugin, "class", "mainBox");
|
||||
// The overlay is null if the XBL binding is not attached (element is display:none).
|
||||
if (overlay) {
|
||||
overlay.addEventListener("click", function(aEvent) {
|
||||
if (aEvent.button == 0 && aEvent.isTrusted)
|
||||
// Have to check that the target is a XULElement and not the link
|
||||
// to update the plugin
|
||||
if (aEvent.target instanceof XULElement &&
|
||||
aEvent.button == 0 && aEvent.isTrusted)
|
||||
gPluginHandler.activateSinglePlugin(aEvent.target.ownerDocument.defaultView.top, aPlugin);
|
||||
}, true);
|
||||
}
|
||||
|
@ -1001,6 +1001,8 @@ var gBrowserInit = {
|
||||
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginDisabled", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginClickToPlay", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginVulnerableUpdatable", gPluginHandler, true);
|
||||
gBrowser.addEventListener("PluginVulnerableNoUpdate", gPluginHandler, true);
|
||||
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
|
||||
#ifdef XP_MACOSX
|
||||
gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);
|
||||
|
@ -517,5 +517,103 @@ function test17() {
|
||||
var missingNotification = PopupNotifications.getNotification("missing-plugins", gTestBrowser);
|
||||
ok(!missingNotification, "Test 17, Should not have a missing plugin notification");
|
||||
|
||||
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE);
|
||||
prepareTest(test18a, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
const Cr = Components.results;
|
||||
const Cm = Components.manager;
|
||||
const Cc = Components.classes;
|
||||
const gReg = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
const gRealBlocklistServiceCID = Cc["@mozilla.org/extensions/blocklist;1"];
|
||||
const gFakeBlocklistServiceCID = Components.ID("{614b68a0-3c53-4ec0-8146-28cc1e25f8a1}");
|
||||
var gFactory = null;
|
||||
|
||||
function registerFakeBlocklistService(blockState) {
|
||||
|
||||
var BlocklistService = {
|
||||
getPluginBlocklistState: function(plugin, appVersion, toolkitVersion) {
|
||||
return blockState;
|
||||
},
|
||||
|
||||
classID: gFakeBlocklistServiceCID,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBlocklistService])
|
||||
};
|
||||
|
||||
gFactory = {
|
||||
createInstance: function(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return BlocklistService.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
gReg.registerFactory(gFakeBlocklistServiceCID,
|
||||
"Fake Blocklist Service",
|
||||
"@mozilla.org/extensions/blocklist;1",
|
||||
gFactory);
|
||||
}
|
||||
|
||||
function unregisterFakeBlocklistService() {
|
||||
if (gFactory != null ) {
|
||||
gReg.unregisterFactory(gFakeBlocklistServiceCID, gFactory);
|
||||
gFactory = null;
|
||||
// This should restore the original blocklist service:
|
||||
gReg.registerFactory(gRealBlocklistServiceCID,
|
||||
"Blocklist Service",
|
||||
"@mozilla.org/extensions/blocklist;1",
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests a vulnerable, updatable plugin
|
||||
function test18a() {
|
||||
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(clickToPlayNotification, "Test 18a, Should have a click-to-play notification");
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 18a, Plugin should not be activated");
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 18a, Plugin overlay should exist, not be hidden");
|
||||
var updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
ok(updateLink.style.visibility != "hidden", "Test 18a, Plugin should have an update link");
|
||||
|
||||
var tabOpenListener = new TabOpenListener(Services.urlFormatter.formatURLPref("plugins.update.url"), false, false);
|
||||
tabOpenListener.handleEvent = function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
ok(event.target.label == this.url, "Test 18a, Update link should open up the plugin check page");
|
||||
gBrowser.removeTab(this.tab);
|
||||
test18b();
|
||||
}
|
||||
};
|
||||
EventUtils.synthesizeMouse(updateLink, 5, 5, {}, gTestBrowser.contentWindow);
|
||||
}
|
||||
|
||||
function test18b() {
|
||||
unregisterFakeBlocklistService();
|
||||
registerFakeBlocklistService(Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE);
|
||||
prepareTest(test18c, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a vulnerable plugin with no update
|
||||
function test18c() {
|
||||
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(clickToPlayNotification, "Test 18c, Should have a click-to-play notification");
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(!objLoadingContent.activated, "Test 18c, Plugin should not be activated");
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
|
||||
ok(overlay.style.visibility != "hidden", "Test 18c, Plugin overlay should exist, not be hidden");
|
||||
var updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
|
||||
ok(updateLink.style.display != "block", "Test 18c, Plugin should not have an update link");
|
||||
|
||||
unregisterFakeBlocklistService();
|
||||
var plugin = get_test_plugin();
|
||||
plugin.clicktoplay = false;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
@ -80,20 +80,6 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
static bool gClickToPlayPlugins = false;
|
||||
|
||||
static void
|
||||
InitPrefCache()
|
||||
{
|
||||
static bool initializedPrefCache = false;
|
||||
if (!initializedPrefCache) {
|
||||
mozilla::Preferences::AddBoolVarCache(&gClickToPlayPlugins, "plugins.click_to_play");
|
||||
}
|
||||
initializedPrefCache = true;
|
||||
}
|
||||
|
||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||
public:
|
||||
nsObjectLoadingContent *mContent;
|
||||
@ -181,6 +167,12 @@ nsPluginErrorEvent::Run()
|
||||
case ePluginClickToPlay:
|
||||
type = NS_LITERAL_STRING("PluginClickToPlay");
|
||||
break;
|
||||
case ePluginVulnerableUpdatable:
|
||||
type = NS_LITERAL_STRING("PluginVulnerableUpdatable");
|
||||
break;
|
||||
case ePluginVulnerableNoUpdate:
|
||||
type = NS_LITERAL_STRING("PluginVulnerableNoUpdate");
|
||||
break;
|
||||
case ePluginUnsupported:
|
||||
type = NS_LITERAL_STRING("PluginNotFound");
|
||||
break;
|
||||
@ -484,7 +476,11 @@ nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMETy
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mShouldPlay) {
|
||||
if (!pluginHost->IsPluginClickToPlayForType(aMIMEType.get())) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||
MOZ_ASSERT(thisContent);
|
||||
nsIDocument* ownerDoc = thisContent->OwnerDoc();
|
||||
@ -505,12 +501,17 @@ nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMETy
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRUint32 permission;
|
||||
rv = permissionManager->TestPermission(topUri,
|
||||
"plugins",
|
||||
&permission);
|
||||
rv = permissionManager->TestPermission(topUri, "plugins", &permission);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
||||
mShouldPlay = true;
|
||||
|
||||
PRUint32 state;
|
||||
rv = pluginHost->GetBlocklistStateForType(aMIMEType.get(), &state);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (permission == nsIPermissionManager::ALLOW_ACTION &&
|
||||
state != nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE &&
|
||||
state != nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
mCTPPlayable = true;
|
||||
} else {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
@ -542,12 +543,9 @@ GetExtensionFromURI(nsIURI* uri, nsCString& ext)
|
||||
*/
|
||||
bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
|
||||
{
|
||||
if (!mShouldPlay) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCAutoString ext;
|
||||
GetExtensionFromURI(uri, ext);
|
||||
bool enabled = false;
|
||||
|
||||
if (ext.IsEmpty()) {
|
||||
return false;
|
||||
@ -562,9 +560,18 @@ bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString&
|
||||
const char* typeFromExt;
|
||||
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
|
||||
mimeType = typeFromExt;
|
||||
return true;
|
||||
enabled = true;
|
||||
|
||||
if (!pluginHost->IsPluginClickToPlayForType(mimeType.get())) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
return false;
|
||||
} else {
|
||||
return enabled;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -598,13 +605,8 @@ nsObjectLoadingContent::nsObjectLoadingContent()
|
||||
, mIsStopping(false)
|
||||
, mSrcStreamLoading(false)
|
||||
, mFallbackReason(ePluginOtherState)
|
||||
{
|
||||
InitPrefCache();
|
||||
// If plugins.click_to_play is false, plugins should always play
|
||||
mShouldPlay = !gClickToPlayPlugins;
|
||||
// If plugins.click_to_play is true, track the activated state of plugins.
|
||||
mActivated = !gClickToPlayPlugins;
|
||||
}
|
||||
, mCTPPlayable(false)
|
||||
, mActivated(false) {}
|
||||
|
||||
nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||
{
|
||||
@ -617,10 +619,6 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||
nsresult
|
||||
nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI)
|
||||
{
|
||||
if (!mShouldPlay) {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
|
||||
// Don't do anything if we already have an active instance.
|
||||
if (mInstanceOwner) {
|
||||
return NS_OK;
|
||||
@ -665,6 +663,14 @@ nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI*
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!pluginHost->IsPluginClickToPlayForType(aMimeType)) {
|
||||
mCTPPlayable = true;
|
||||
}
|
||||
|
||||
if (!mCTPPlayable) {
|
||||
return NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
|
||||
// If you add early return(s), be sure to balance this call to
|
||||
// appShell->SuspendNative() with additional call(s) to
|
||||
// appShell->ReturnNative().
|
||||
@ -1191,6 +1197,10 @@ nsObjectLoadingContent::ObjectState() const
|
||||
switch (mFallbackReason) {
|
||||
case ePluginClickToPlay:
|
||||
return NS_EVENT_STATE_TYPE_CLICK_TO_PLAY;
|
||||
case ePluginVulnerableUpdatable:
|
||||
return NS_EVENT_STATE_VULNERABLE_UPDATABLE;
|
||||
case ePluginVulnerableNoUpdate:
|
||||
return NS_EVENT_STATE_VULNERABLE_NO_UPDATE;
|
||||
case ePluginDisabled:
|
||||
state |= NS_EVENT_STATE_HANDLER_DISABLED;
|
||||
break;
|
||||
@ -1933,8 +1943,10 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
}
|
||||
|
||||
PluginSupportState pluginDisabledState = GetPluginDisabledState(aContentType);
|
||||
if (pluginDisabledState == ePluginClickToPlay) {
|
||||
return ePluginClickToPlay;
|
||||
if (pluginDisabledState == ePluginClickToPlay ||
|
||||
pluginDisabledState == ePluginVulnerableUpdatable ||
|
||||
pluginDisabledState == ePluginVulnerableNoUpdate) {
|
||||
return pluginDisabledState;
|
||||
} else if (hasAlternateContent) {
|
||||
return ePluginOtherState;
|
||||
} else {
|
||||
@ -1946,12 +1958,28 @@ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
nsresult rv = IsPluginEnabledForType(aContentType);
|
||||
if (rv == NS_ERROR_PLUGIN_DISABLED)
|
||||
if (rv == NS_ERROR_PLUGIN_DISABLED) {
|
||||
return ePluginDisabled;
|
||||
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY)
|
||||
}
|
||||
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY) {
|
||||
PRUint32 state;
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if (pluginHost) {
|
||||
rv = pluginHost->GetBlocklistStateForType(aContentType.get(), &state);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) {
|
||||
return ePluginVulnerableUpdatable;
|
||||
} else if (state == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
return ePluginVulnerableNoUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ePluginClickToPlay;
|
||||
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED)
|
||||
}
|
||||
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED) {
|
||||
return ePluginBlocklisted;
|
||||
}
|
||||
return ePluginUnsupported;
|
||||
}
|
||||
|
||||
@ -2213,7 +2241,7 @@ nsObjectLoadingContent::PlayPlugin()
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_OK;
|
||||
|
||||
mShouldPlay = true;
|
||||
mCTPPlayable = true;
|
||||
return LoadObject(mURI, true, mContentType, true);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@ enum PluginSupportState {
|
||||
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
||||
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
|
||||
ePluginCrashed,
|
||||
ePluginClickToPlay // The plugin is disabled until the user clicks on it
|
||||
ePluginClickToPlay, // The plugin is disabled until the user clicks on it
|
||||
ePluginVulnerableUpdatable, // The plugin is vulnerable (update available)
|
||||
ePluginVulnerableNoUpdate // The plugin is vulnerable (no update available)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -372,9 +374,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// it may lose the flag.
|
||||
bool mNetworkCreated : 1;
|
||||
|
||||
// Used to keep track of whether or not a plugin should be played.
|
||||
// This is used for click-to-play plugins.
|
||||
bool mShouldPlay : 1;
|
||||
// Used to keep track of if a plugin is blocked by click-to-play.
|
||||
// True indicates the plugin is not click-to-play or it has been clicked by
|
||||
// the user.
|
||||
// False indicates the plugin is click-to-play and has not yet been clicked.
|
||||
bool mCTPPlayable : 1;
|
||||
|
||||
// Used to keep track of whether or not a plugin has been played.
|
||||
// This is used for click-to-play plugins.
|
||||
|
@ -242,6 +242,10 @@ private:
|
||||
#define NS_EVENT_STATE_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(38)
|
||||
// Content is in the sub-suboptimal region.
|
||||
#define NS_EVENT_STATE_SUB_SUB_OPTIMUM NS_DEFINE_EVENT_STATE_MACRO(39)
|
||||
// Handler for click to play plugin (vulnerable w/update)
|
||||
#define NS_EVENT_STATE_VULNERABLE_UPDATABLE NS_DEFINE_EVENT_STATE_MACRO(40)
|
||||
// Handler for click to play plugin (vulnerable w/no update)
|
||||
#define NS_EVENT_STATE_VULNERABLE_NO_UPDATE NS_DEFINE_EVENT_STATE_MACRO(41)
|
||||
|
||||
/**
|
||||
* NOTE: do not go over 63 without updating nsEventStates::InternalType!
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(88e03453-a773-47ba-9d84-14f672ac99e2)]
|
||||
[scriptable, uuid(a361a7e7-7f8d-4b68-91e9-30ae096460d4)]
|
||||
interface nsIPluginTag : nsISupports
|
||||
{
|
||||
readonly attribute AUTF8String description;
|
||||
@ -15,4 +15,5 @@ interface nsIPluginTag : nsISupports
|
||||
readonly attribute AUTF8String name;
|
||||
attribute boolean disabled;
|
||||
attribute boolean blocklisted;
|
||||
attribute boolean clicktoplay;
|
||||
};
|
||||
|
@ -342,8 +342,10 @@ nsPluginHost::nsPluginHost()
|
||||
Preferences::GetBool("plugin.override_internal_types", false);
|
||||
|
||||
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
||||
mPluginsClickToPlay = Preferences::GetBool("plugins.click_to_play", false);
|
||||
|
||||
Preferences::AddStrongObserver(this, "plugin.disable");
|
||||
Preferences::AddStrongObserver(this, "plugins.click_to_play");
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService =
|
||||
mozilla::services::GetObserverService();
|
||||
@ -1294,6 +1296,36 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPluginHost::IsPluginClickToPlayForType(const char* aMimeType)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginForType(aMimeType, true);
|
||||
if (plugin &&
|
||||
(plugin->HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) || mPluginsClickToPlay)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::GetBlocklistStateForType(const char *aMimeType, PRUint32 *aState)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginForType(aMimeType, true);
|
||||
if (plugin) {
|
||||
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
|
||||
if (blocklist) {
|
||||
// The EmptyString()s are so we use the currently running application
|
||||
// and toolkit versions
|
||||
return blocklist->GetPluginBlocklistState(plugin, EmptyString(),
|
||||
EmptyString(), aState);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// check comma delimitered extensions
|
||||
static int CompareExtensions(const char *aExtensionList, const char *aExtension)
|
||||
@ -2074,19 +2106,32 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||
EmptyString(), &state);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// If the blocklist says so then block the plugin. If the blocklist says
|
||||
// it is risky and we have never seen this plugin before then disable it
|
||||
if (state == nsIBlocklistService::STATE_BLOCKED)
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
else if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore)
|
||||
enabled = false;
|
||||
else if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore)
|
||||
warnOutdated = true;
|
||||
// If the blocklist says so, block the plugin.
|
||||
// If the blocklist says it is risky and we have never seen this
|
||||
// plugin before, then disable it.
|
||||
// If the blocklist says this is an outdated plugin, warn about
|
||||
// outdated plugins.
|
||||
// If the blocklist says the plugin is one of the click-to-play
|
||||
// states, set the click-to-play flag.
|
||||
if (state == nsIBlocklistService::STATE_BLOCKED) {
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
|
||||
enabled = false;
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) {
|
||||
warnOutdated = true;
|
||||
}
|
||||
if (state == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
|
||||
state == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
pluginTag->Mark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!enabled)
|
||||
if (!enabled) {
|
||||
pluginTag->UnMark(NS_PLUGIN_FLAG_ENABLED);
|
||||
}
|
||||
|
||||
// Plugin unloading is tag-based. If we created a new tag and loaded
|
||||
// the library in the process then we want to attempt to unload it here.
|
||||
@ -3302,6 +3347,7 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
|
||||
}
|
||||
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
|
||||
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
|
||||
mPluginsClickToPlay = Preferences::GetBool("plugins.click_to_play", false);
|
||||
// Unload or load plugins as needed
|
||||
if (mPluginsDisabled) {
|
||||
UnloadPlugins();
|
||||
|
@ -85,6 +85,8 @@ public:
|
||||
nsIPluginInstanceOwner *aOwner);
|
||||
nsresult IsPluginEnabledForType(const char* aMimeType);
|
||||
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
|
||||
bool IsPluginClickToPlayForType(const char *aMimeType);
|
||||
nsresult GetBlocklistStateForType(const char *aMimeType, PRUint32 *state);
|
||||
|
||||
nsresult GetPluginCount(PRUint32* aPluginCount);
|
||||
nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray);
|
||||
@ -281,6 +283,8 @@ private:
|
||||
|
||||
// set by pref plugin.disable
|
||||
bool mPluginsDisabled;
|
||||
// set by pref plugins.click_to_play
|
||||
bool mPluginsClickToPlay;
|
||||
|
||||
// Any instances in this array will have valid plugin objects via GetPlugin().
|
||||
// When removing an instance it might not die - be sure to null out it's plugin.
|
||||
|
@ -320,6 +320,30 @@ nsPluginTag::SetBlocklisted(bool aBlocklisted)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetClicktoplay(bool *aClicktoplay)
|
||||
{
|
||||
*aClicktoplay = HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetClicktoplay(bool aClicktoplay)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_CLICKTOPLAY) == aClicktoplay) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aClicktoplay) {
|
||||
Mark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
} else {
|
||||
UnMark(NS_PLUGIN_FLAG_CLICKTOPLAY);
|
||||
}
|
||||
|
||||
mPluginHost->UpdatePluginInfo(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPluginTag::Mark(PRUint32 mask)
|
||||
{
|
||||
bool wasEnabled = IsEnabled();
|
||||
|
@ -27,6 +27,7 @@ struct nsPluginInfo;
|
||||
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
|
||||
// no longer used 0x0008 // reuse only if regenerating pluginreg.dat
|
||||
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
|
||||
#define NS_PLUGIN_FLAG_CLICKTOPLAY 0x0020 // this is a click-to-play plugin
|
||||
|
||||
// A linked-list of plugin information that is used for instantiating plugins
|
||||
// and reflecting plugin information into JavaScript.
|
||||
|
@ -129,6 +129,10 @@ CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
|
||||
NS_EVENT_STATE_TYPE_UNSUPPORTED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
|
||||
NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableUpdatable, ":-moz-handler-vulnerable-updatable",
|
||||
NS_EVENT_STATE_VULNERABLE_UPDATABLE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableNoUpdate, ":-moz-handler-vulnerable-no-update",
|
||||
NS_EVENT_STATE_VULNERABLE_NO_UPDATE)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
|
||||
NS_EVENT_STATE_HANDLER_DISABLED)
|
||||
CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
|
||||
|
@ -24,6 +24,9 @@
|
||||
<!-- LOCALIZATION NOTE (tapToPlayPlugin): Mobile (used for touch interfaces) only has one type of plugin possible. -->
|
||||
<!ENTITY tapToPlayPlugin "Tap here to activate plugin.">
|
||||
<!ENTITY clickToPlayPlugin "Click here to activate plugin.">
|
||||
<!ENTITY clickToPlayPluginVulnerableUpdateAvailable "Click here to activate vulnerable plugin.">
|
||||
<!ENTITY clickToPlayPluginVulnerableNoUpdate "Click here to activate vulnerable plugin (no update available).">
|
||||
<!ENTITY checkForUpdates "Check for updates…">
|
||||
<!ENTITY disabledPlugin "This plugin is disabled.">
|
||||
<!ENTITY blockedPlugin.label "This plugin has been blocked for your protection.">
|
||||
|
||||
|
@ -45,6 +45,9 @@ const DEFAULT_SEVERITY = 3;
|
||||
const DEFAULT_LEVEL = 2;
|
||||
const MAX_BLOCK_LEVEL = 3;
|
||||
const SEVERITY_OUTDATED = 0;
|
||||
const VULNERABILITYSTATUS_NONE = 0;
|
||||
const VULNERABILITYSTATUS_UPDATE_AVAILABLE = 1;
|
||||
const VULNERABILITYSTATUS_NO_UPDATE = 2;
|
||||
|
||||
var gLoggingEnabled = null;
|
||||
var gBlocklistEnabled = true;
|
||||
@ -831,8 +834,14 @@ Blocklist.prototype = {
|
||||
toolkitVersion)) {
|
||||
if (blockEntryVersion.severity >= gBlocklistLevel)
|
||||
return Ci.nsIBlocklistService.STATE_BLOCKED;
|
||||
if (blockEntryVersion.severity == SEVERITY_OUTDATED)
|
||||
if (blockEntryVersion.severity == SEVERITY_OUTDATED) {
|
||||
let vulnerabilityStatus = blockEntryVersion.vulnerabilityStatus;
|
||||
if (vulnerabilityStatus == VULNERABILITYSTATUS_UPDATE_AVAILABLE)
|
||||
return Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE;
|
||||
if (vulnerabilityStatus == VULNERABILITYSTATUS_NO_UPDATE)
|
||||
return Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE;
|
||||
return Ci.nsIBlocklistService.STATE_OUTDATED;
|
||||
}
|
||||
return Ci.nsIBlocklistService.STATE_SOFTBLOCKED;
|
||||
}
|
||||
}
|
||||
@ -946,7 +955,8 @@ Blocklist.prototype = {
|
||||
if (state == Ci.nsIBlocklistService.STATE_OUTDATED) {
|
||||
gPref.setBoolPref(PREF_PLUGINS_NOTIFYUSER, true);
|
||||
}
|
||||
else {
|
||||
else if (state != Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE &&
|
||||
state != Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
|
||||
addonList.push({
|
||||
name: plugin.name,
|
||||
version: plugin.version,
|
||||
@ -959,6 +969,9 @@ Blocklist.prototype = {
|
||||
}
|
||||
}
|
||||
plugin.blocklisted = state == Ci.nsIBlocklistService.STATE_BLOCKED;
|
||||
if (state == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE ||
|
||||
state == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE)
|
||||
plugin.clicktoplay = true;
|
||||
}
|
||||
|
||||
if (addonList.length == 0) {
|
||||
@ -1039,6 +1052,11 @@ function BlocklistItemData(versionRangeElement) {
|
||||
this.severity = versionRangeElement.getAttribute("severity");
|
||||
else
|
||||
this.severity = DEFAULT_SEVERITY;
|
||||
if (versionRangeElement && versionRangeElement.hasAttribute("vulnerabilitystatus")) {
|
||||
this.vulnerabilityStatus = versionRangeElement.getAttribute("vulnerabilitystatus");
|
||||
} else {
|
||||
this.vulnerabilityStatus = VULNERABILITYSTATUS_NONE;
|
||||
}
|
||||
this.targetApps = { };
|
||||
var found = false;
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<pluginItems>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^test_plugin_0"/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="0" vulnerabilitystatus="0"/>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^test_plugin_1"/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="0" vulnerabilitystatus="1"/>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^test_plugin_2"/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="0" vulnerabilitystatus="2"/>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^test_plugin_3"/>
|
||||
<versionRange minVersion="0" maxVersion="*" vulnerabilitystatus="2"/>
|
||||
</pluginItem>
|
||||
<pluginItem>
|
||||
<match name="name" exp="^test_plugin_4"/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1" vulnerabilitystatus="2"/>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
</blocklist>
|
@ -0,0 +1,76 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const nsIBLS = Components.interfaces.nsIBlocklistService;
|
||||
|
||||
var PLUGINS = [{
|
||||
// severity=0, vulnerabilitystatus=0 -> outdated
|
||||
name: "test_plugin_0",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
},
|
||||
{
|
||||
// severity=0, vulnerabilitystatus=1 -> update available
|
||||
name: "test_plugin_1",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
},
|
||||
{
|
||||
// severity=0, vulnerabilitystatus=2 -> no update
|
||||
name: "test_plugin_2",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
},
|
||||
{
|
||||
// no severity field -> severity=3 by default -> hardblock
|
||||
name: "test_plugin_3",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
},
|
||||
{
|
||||
// severity=1, vulnerabilitystatus=2 -> softblock
|
||||
name: "test_plugin_4",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
},
|
||||
{
|
||||
// not in the blocklist -> not blocked
|
||||
name: "test_plugin_5",
|
||||
version: "5",
|
||||
disabled: false,
|
||||
blocklisted: false
|
||||
}];
|
||||
|
||||
|
||||
function run_test() {
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
|
||||
|
||||
// We cannot force the blocklist to update so just copy our test list to the profile
|
||||
var blocklistFile = gProfD.clone();
|
||||
blocklistFile.append("blocklist.xml");
|
||||
if (blocklistFile.exists())
|
||||
blocklistFile.remove(false);
|
||||
var source = do_get_file("data/test_pluginBlocklistCtp.xml");
|
||||
source.copyTo(gProfD, "blocklist.xml");
|
||||
|
||||
var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
|
||||
.getService(nsIBLS);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[0], "1", "1.9") == nsIBLS.STATE_OUTDATED);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[1], "1", "1.9") == nsIBLS.STATE_VULNERABLE_UPDATE_AVAILABLE);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[2], "1", "1.9") == nsIBLS.STATE_VULNERABLE_NO_UPDATE);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[3], "1", "1.9") == nsIBLS.STATE_BLOCKED);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[4], "1", "1.9") == nsIBLS.STATE_SOFTBLOCKED);
|
||||
|
||||
do_check_true(blocklist.getPluginBlocklistState(PLUGINS[5], "1", "1.9") == nsIBLS.STATE_NOT_BLOCKED);
|
||||
}
|
@ -186,6 +186,7 @@ skip-if = os == "android"
|
||||
[test_onPropertyChanged_appDisabled.js]
|
||||
[test_permissions.js]
|
||||
[test_plugins.js]
|
||||
[test_pluginBlocklistCtp.js]
|
||||
# Bug 676992: test consistently fails on Android
|
||||
fail-if = os == "android"
|
||||
[test_pref_properties.js]
|
||||
|
@ -26,6 +26,9 @@
|
||||
<html:div class="msg msgUnsupported">&missingPlugin;</html:div>
|
||||
<html:div class="msg msgTapToPlay">&tapToPlayPlugin;</html:div>
|
||||
<html:div class="msg msgClickToPlay">&clickToPlayPlugin;</html:div>
|
||||
<html:div class="msg msgVulnerableUpdatable">&clickToPlayPluginVulnerableUpdateAvailable;</html:div>
|
||||
<html:div class="msg msgVulnerableNoUpdate">&clickToPlayPluginVulnerableNoUpdate;</html:div>
|
||||
<html:div class="msg msgCheckForUpdates"><html:a class="checkForUpdatesLink" href="">&checkForUpdates;</html:a></html:div>
|
||||
<html:div class="msg msgDisabled">&disabledPlugin;</html:div>
|
||||
<html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
|
||||
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
|
||||
|
@ -8,14 +8,20 @@ embed:-moz-handler-disabled,
|
||||
embed:-moz-handler-blocked,
|
||||
embed:-moz-handler-crashed,
|
||||
embed:-moz-handler-clicktoplay,
|
||||
embed:-moz-handler-vulnerable-updatable,
|
||||
embed:-moz-handler-vulnerable-no-update,
|
||||
applet:-moz-handler-disabled,
|
||||
applet:-moz-handler-blocked,
|
||||
applet:-moz-handler-crashed,
|
||||
applet:-moz-handler-clicktoplay,
|
||||
applet:-moz-handler-vulnerable-updatable,
|
||||
applet:-moz-handler-vulnerable-no-update,
|
||||
object:-moz-has-handlerref:-moz-handler-disabled,
|
||||
object:-moz-has-handlerref:-moz-handler-blocked,
|
||||
object:-moz-handler-crashed,
|
||||
object:-moz-handler-clicktoplay {
|
||||
object:-moz-handler-clicktoplay,
|
||||
object:-moz-handler-vulnerable-updatable,
|
||||
object:-moz-handler-vulnerable-no-update {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
-moz-binding: url('chrome://mozapps/content/plugins/pluginProblem.xml#pluginProblem') !important;
|
||||
|
@ -18,12 +18,16 @@ html|applet:not([height]), html|applet[height=""] {
|
||||
|
||||
:-moz-type-unsupported .mainBox,
|
||||
:-moz-handler-clicktoplay .mainBox,
|
||||
:-moz-handler-vulnerable-updatable .mainBox,
|
||||
:-moz-handler-vulnerable-no-update .mainBox,
|
||||
:-moz-handler-disabled .mainBox,
|
||||
:-moz-handler-blocked .mainBox {
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
:-moz-type-unsupported .mainBox:focus,
|
||||
:-moz-handler-clicktoplay .mainBox:focus,
|
||||
:-moz-handler-vulnerable-updatable .mainBox:focus,
|
||||
:-moz-handler-vulnerable-no-update .mainBox:focus,
|
||||
:-moz-handler-disabled .mainBox:focus,
|
||||
:-moz-handler-blocked .mainBox:focus {
|
||||
outline: 1px dotted;
|
||||
@ -47,6 +51,9 @@ html|applet:not([height]), html|applet[height=""] {
|
||||
|
||||
:-moz-type-unsupported .msgUnsupported,
|
||||
:-moz-handler-clicktoplay .msgClickToPlay,
|
||||
:-moz-handler-vulnerable-updatable .msgVulnerableUpdatable,
|
||||
:-moz-handler-vulnerable-updatable .msgCheckForUpdates,
|
||||
:-moz-handler-vulnerable-no-update .msgVulnerableNoUpdate,
|
||||
:-moz-handler-clicktoplay .msgTapToPlay,
|
||||
:-moz-handler-disabled .msgDisabled,
|
||||
:-moz-handler-disabled .msgManagePlugins,
|
||||
|
@ -38,7 +38,9 @@ html|a {
|
||||
:-moz-type-unsupported .icon[status="ready"] {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
||||
}
|
||||
:-moz-handler-clicktoplay .icon {
|
||||
:-moz-handler-clicktoplay .icon,
|
||||
:-moz-handler-vulnerable-updatable .icon,
|
||||
:-moz-handler-vulnerable-no-update .icon {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginClickToPlay.png);
|
||||
}
|
||||
:-moz-handler-disabled .icon {
|
||||
@ -64,8 +66,9 @@ html|a {
|
||||
text-shadow: rgba(0,0,0,0.8) 0 0 3.5px;
|
||||
}
|
||||
|
||||
:-moz-handler-clicktoplay,
|
||||
.msgClickToPlay {
|
||||
:-moz-handler-clicktoplay .msgClickToPlay,
|
||||
:-moz-handler-vulnerable-updatable .msgClickToPlay,
|
||||
:-moz-handler-vulnerable-no-update .msgClickToPlay {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,9 @@ html|a {
|
||||
:-moz-type-unsupported .icon[status="ready"] {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginDownload.png);
|
||||
}
|
||||
:-moz-handler-clicktoplay .icon {
|
||||
:-moz-handler-clicktoplay .icon,
|
||||
:-moz-handler-vulnerable-updatable .icon,
|
||||
:-moz-handler-vulnerable-no-update .icon {
|
||||
background-image: url(chrome://mozapps/skin/plugins/contentPluginClickToPlay.png);
|
||||
}
|
||||
:-moz-handler-disabled .icon {
|
||||
@ -64,8 +66,9 @@ html|a {
|
||||
text-shadow: rgba(0,0,0,0.8) 0 0 3.5px;
|
||||
}
|
||||
|
||||
:-moz-handler-clicktoplay,
|
||||
.msgClickToPlay {
|
||||
:-moz-handler-clicktoplay .msgClickToPlay,
|
||||
:-moz-handler-vulnerable-updatable .msgClickToPlay,
|
||||
:-moz-handler-vulnerable-no-update .msgClickToPlay {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
interface nsIPluginTag;
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(31845f85-718a-4581-a672-a45c0327cb21)]
|
||||
[scriptable, uuid(cbba15b8-316d-4ae6-8ed9-fe9cf8386730)]
|
||||
interface nsIBlocklistService : nsISupports
|
||||
{
|
||||
// Indicates that the item does not appear in the blocklist.
|
||||
@ -22,6 +22,10 @@ interface nsIBlocklistService : nsISupports
|
||||
// Indicates that the item is considered outdated, and there is a known
|
||||
// update available.
|
||||
const unsigned long STATE_OUTDATED = 3;
|
||||
// Indicates that the item is vulnerable and there is an update.
|
||||
const unsigned long STATE_VULNERABLE_UPDATE_AVAILABLE = 4;
|
||||
// Indicates that the item is vulnerable and there is no update.
|
||||
const unsigned long STATE_VULNERABLE_NO_UPDATE = 5;
|
||||
|
||||
/**
|
||||
* Determine if an item is blocklisted
|
||||
|
Loading…
Reference in New Issue
Block a user