Bug 730318 - Opt-in activated plugins should use internal APIs to keep track of plugin activation. r=margaret

This commit is contained in:
Jared Wein 2012-03-28 08:53:58 -07:00
parent ac11ea4de6
commit e2874e47c1

View File

@ -1462,8 +1462,6 @@ function Tab(aURL, aParams) {
this.create(aURL, aParams);
this._zoom = 1.0;
this.userScrollPos = { x: 0, y: 0 };
this._pluginCount = 0;
this._pluginOverlayShowing = false;
this.contentDocumentIsDisplayed = true;
}
@ -1517,6 +1515,7 @@ Tab.prototype = {
this.browser.sessionHistory.addSHistoryListener(this);
this.browser.addEventListener("DOMContentLoaded", this, true);
this.browser.addEventListener("load", this, true);
this.browser.addEventListener("DOMLinkAdded", this, true);
this.browser.addEventListener("DOMTitleChanged", this, true);
this.browser.addEventListener("DOMWindowClose", this, true);
@ -1524,8 +1523,6 @@ Tab.prototype = {
this.browser.addEventListener("scroll", this, true);
this.browser.addEventListener("MozScrolledAreaChanged", this, true);
this.browser.addEventListener("PluginClickToPlay", this, true);
this.browser.addEventListener("pagehide", this, true);
this.browser.addEventListener("pageshow", this, true);
Services.obs.addObserver(this, "before-first-paint", false);
@ -1563,6 +1560,7 @@ Tab.prototype = {
this.browser.removeProgressListener(this);
this.browser.removeEventListener("DOMContentLoaded", this, true);
this.browser.removeEventListener("load", this, true);
this.browser.removeEventListener("DOMLinkAdded", this, true);
this.browser.removeEventListener("DOMTitleChanged", this, true);
this.browser.removeEventListener("DOMWindowClose", this, true);
@ -1570,8 +1568,6 @@ Tab.prototype = {
this.browser.removeEventListener("scroll", this, true);
this.browser.removeEventListener("PluginClickToPlay", this, true);
this.browser.removeEventListener("MozScrolledAreaChanged", this, true);
this.browser.removeEventListener("pagehide", this, true);
this.browser.removeEventListener("pageshow", this, true);
Services.obs.removeObserver(this, "before-first-paint");
@ -1791,13 +1787,24 @@ Tab.prototype = {
this.browser.removeEventListener("pagehide", listener, true);
}.bind(this), true);
}
break;
}
// Show a plugin doorhanger if there are plugins on the page but no
// clickable overlays showing (this doesn't work on pages loaded after
// back/forward navigation - see bug 719875)
if (this._pluginCount && !this._pluginOverlayShowing)
case "load": {
// Show a plugin doorhanger if there are no clickable overlays showing
let contentWindow = this.browser.contentWindow;
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// XXX not sure if we should enable plugins for the parent documents...
let plugins = cwu.plugins;
let isAnyPluginVisible = false;
for (let plugin of plugins) {
let overlay = plugin.ownerDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
if (overlay && !PluginHelper.isTooSmall(plugin, overlay))
isAnyPluginVisible = true;
}
if (plugins && plugins.length && !isAnyPluginVisible)
PluginHelper.showDoorHanger(this);
break;
}
@ -1905,10 +1912,6 @@ Tab.prototype = {
}
case "PluginClickToPlay": {
// Keep track of the number of plugins to know whether or not to show
// the hidden plugins doorhanger
this._pluginCount++;
let plugin = aEvent.target;
let overlay = plugin.ownerDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
if (!overlay)
@ -1922,22 +1925,14 @@ Tab.prototype = {
}
// Add click to play listener to the overlay
overlay.addEventListener("click", (function(event) {
// Play all the plugin objects when the user clicks on one
PluginHelper.playAllPlugins(this, event);
}).bind(this), true);
this._pluginOverlayShowing = true;
break;
}
case "pagehide": {
// Check to make sure it's top-level pagehide
if (aEvent.target.defaultView == this.browser.contentWindow) {
// Reset plugin state when we leave the page
this._pluginCount = 0;
this._pluginOverlayShowing = false;
}
overlay.addEventListener("click", function(e) {
if (e) {
if (!e.isTrusted)
return;
e.preventDefault();
}
PluginHelper.playAllPlugins(e.target.ownerDocument.defaultView);
}, true);
break;
}
}
@ -3910,7 +3905,7 @@ var PluginHelper = {
{
label: Strings.browser.GetStringFromName("clickToPlayPlugins.yes"),
callback: function() {
PluginHelper.playAllPlugins(aTab);
PluginHelper.playAllPlugins(aTab.browser.contentWindow);
}
},
{
@ -3923,41 +3918,19 @@ var PluginHelper = {
NativeWindow.doorhanger.show(message, "ask-to-play-plugins", buttons, aTab.id);
},
playAllPlugins: function(aTab, aEvent) {
if (aEvent) {
if (!aEvent.isTrusted)
return;
aEvent.preventDefault();
playAllPlugins: function(aContentWindow) {
let cwu = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// XXX not sure if we should enable plugins for the parent documents...
let plugins = cwu.plugins;
if (!plugins || !plugins.length)
return;
for (let plugin of plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (!objLoadingContent.activated)
objLoadingContent.playPlugin();
}
this._findAndPlayAllPlugins(aTab.browser.contentWindow);
},
// Helper function that recurses through sub-frames to find all plugin objects
_findAndPlayAllPlugins: function _findAndPlayAllPlugins(aWindow) {
let embeds = aWindow.document.getElementsByTagName("embed");
for (let i = 0; i < embeds.length; i++) {
if (!embeds[i].hasAttribute("played"))
this._playPlugin(embeds[i]);
}
let objects = aWindow.document.getElementsByTagName("object");
for (let i = 0; i < objects.length; i++) {
if (!objects[i].hasAttribute("played"))
this._playPlugin(objects[i]);
}
for (let i = 0; i < aWindow.frames.length; i++) {
this._findAndPlayAllPlugins(aWindow.frames[i]);
}
},
_playPlugin: function _playPlugin(aPlugin) {
let objLoadingContent = aPlugin.QueryInterface(Ci.nsIObjectLoadingContent);
objLoadingContent.playPlugin();
// Set an attribute on the plugin object to avoid re-loading it
aPlugin.setAttribute("played", true);
},
getPluginPreference: function getPluginPreference() {