Bug 800018 - Part 2 - Move plugin fallback event handling entirely to the front end. r=jaws

This commit is contained in:
John Schoenick 2012-11-07 13:59:20 -08:00
Родитель d433e2d472
Коммит a1c0496fa5
5 изменённых файлов: 81 добавлений и 33 удалений

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

@ -113,6 +113,34 @@ var gPluginHandler = {
true);
},
// Helper to get the binding handler type from a plugin object
_getBindingType : function(plugin) {
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
switch (plugin.pluginFallbackType) {
case Ci.nsIObjectLoadingContent.PLUGIN_UNSUPPORTED:
return "PluginNotFound";
case Ci.nsIObjectLoadingContent.PLUGIN_DISABLED:
return "PluginDisabled";
case Ci.nsIObjectLoadingContent.PLUGIN_BLOCKLISTED:
return "PluginBlocklisted";
case Ci.nsIObjectLoadingContent.PLUGIN_OUTDATED:
return "PluginOutdated";
case Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY:
return "PluginClickToPlay";
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_UPDATABLE:
return "PluginVulnerableUpdatable";
case Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE:
return "PluginVulnerableNoUpdate";
case Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW:
return "PluginPlayPreview";
default:
// Not all states map to a handler
return;
}
},
handleEvent : function(event) {
let self = gPluginHandler;
let plugin = event.target;
@ -122,10 +150,26 @@ var gPluginHandler = {
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
return;
// Force a style flush, so that we ensure our binding is attached.
plugin.clientTop;
let eventType = event.type;
if (eventType == "PluginBindingAttached") {
// The plugin binding fires this event when it is created.
// As an untrusted event, ensure that this object actually has a binding
// and make sure we don't handle it twice
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
if (!overlay || overlay._bindingHandled) {
return;
}
overlay._bindingHandled = true;
switch (event.type) {
// Lookup the handler for this binding
eventType = self._getBindingType(plugin);
if (!eventType) {
// Not all bindings have handlers
return;
}
}
switch (eventType) {
case "PluginCrashed":
self.pluginInstanceCrashed(plugin, event);
break;
@ -151,7 +195,7 @@ var gPluginHandler = {
#ifdef XP_MACOSX
case "npapi-carbon-event-model-failure":
#endif
self.pluginUnavailable(plugin, event.type);
self.pluginUnavailable(plugin, eventType);
break;
case "PluginVulnerableUpdatable":
@ -167,9 +211,9 @@ var gPluginHandler = {
let messageString = gNavigatorBundle.getFormattedString("PluginClickToPlay", [pluginName]);
let overlayText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
overlayText.textContent = messageString;
if (event.type == "PluginVulnerableUpdatable" ||
event.type == "PluginVulnerableNoUpdate") {
let vulnerabilityString = gNavigatorBundle.getString(event.type);
if (eventType == "PluginVulnerableUpdatable" ||
eventType == "PluginVulnerableNoUpdate") {
let vulnerabilityString = gNavigatorBundle.getString(eventType);
let vulnerabilityText = doc.getAnonymousElementByAttribute(plugin, "anonid", "vulnerabilityStatus");
vulnerabilityText.textContent = vulnerabilityString;
}
@ -186,9 +230,8 @@ var gPluginHandler = {
}
// Hide the in-content UI if it's too big. The crashed plugin handler already did this.
if (event.type != "PluginCrashed") {
if (eventType != "PluginCrashed") {
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
/* overlay might be null, so only operate on it if it exists */
if (overlay != null && self.isTooSmall(plugin, overlay))
overlay.style.visibility = "hidden";
}
@ -321,7 +364,6 @@ var gPluginHandler = {
return;
}
// The overlay is null if the XBL binding is not attached (element is display:none).
if (overlay) {
overlay.addEventListener("click", function(aEvent) {
// Have to check that the target is not the link to update the plugin
@ -341,11 +383,6 @@ var gPluginHandler = {
_handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
let doc = aPlugin.ownerDocument;
let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent");
if (!previewContent) {
// the XBL binding is not attached (element is display:none), fallback to click-to-play logic
gPluginHandler.stopPlayPreview(aPlugin, false);
return;
}
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
if (!iframe) {
// lazy initialization of the iframe
@ -754,6 +791,9 @@ var gPluginHandler = {
//
// Configure the crashed-plugin placeholder.
//
// Force a layout flush so the binding is attached.
plugin.clientTop;
let doc = plugin.ownerDocument;
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let statusDiv = doc.getAnonymousElementByAttribute(plugin, "class", "submitStatus");

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

@ -1012,15 +1012,11 @@ var gBrowserInit = {
gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
gBrowser.addEventListener("PluginNotFound", gPluginHandler, true);
gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
gBrowser.addEventListener("PluginBlocklisted", gPluginHandler, true);
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
gBrowser.addEventListener("PluginDisabled", gPluginHandler, true);
gBrowser.addEventListener("PluginClickToPlay", gPluginHandler, true);
gBrowser.addEventListener("PluginPlayPreview", gPluginHandler, true);
gBrowser.addEventListener("PluginVulnerableUpdatable", gPluginHandler, true);
gBrowser.addEventListener("PluginVulnerableNoUpdate", gPluginHandler, true);
// Note that the XBL binding is untrusted
gBrowser.addEventListener("PluginBindingAttached", gPluginHandler, true, true);
gBrowser.addEventListener("PluginCrashed", gPluginHandler, true);
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
#ifdef XP_MACOSX
gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);

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

@ -64,20 +64,22 @@ function test() {
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.addEventListener("PluginClickToPlay", handlePluginClickToPlay, true);
gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
prepareTest(test1, gTestRoot + "plugin_unknown.html");
}
function finishTest() {
gTestBrowser.removeEventListener("load", pageLoad, true);
gTestBrowser.removeEventListener("PluginClickToPlay", handlePluginClickToPlay, true);
gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function handlePluginClickToPlay() {
gClickToPlayPluginActualEvents++;
function handleBindingAttached(evt) {
evt.target instanceof Ci.nsIObjectLoadingContent;
if (evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY)
gClickToPlayPluginActualEvents++;
}
function pageLoad() {
@ -734,7 +736,7 @@ function test19f() {
// "display: block" can be clicked to activate.
function test20a() {
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(clickToPlayNotification, "Test 20a, Should have a click-to-play notification");
ok(!clickToPlayNotification, "Test 20a, Should not have a click-to-play notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("plugin");
var mainBox = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
@ -756,6 +758,8 @@ function test20a() {
}
function test20b() {
var clickToPlayNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(clickToPlayNotification, "Test 20b, Should now have a click-to-play notification");
var doc = gTestBrowser.contentDocument;
var plugin = doc.getElementById("plugin");
var pluginRect = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox").getBoundingClientRect();

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

@ -145,7 +145,7 @@ function test() {
gBrowser.selectedTab = newTab;
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("load", pageLoad, true);
gTestBrowser.addEventListener("PluginPlayPreview", handlePluginPlayPreview, true);
gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
registerPlayPreview('application/x-test', 'about:');
prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
@ -153,14 +153,16 @@ function test() {
function finishTest() {
gTestBrowser.removeEventListener("load", pageLoad, true);
gTestBrowser.removeEventListener("PluginPlayPreview", handlePluginPlayPreview, true);
gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
gBrowser.removeCurrentTab();
window.focus();
finish();
}
function handlePluginPlayPreview() {
gPlayPreviewPluginActualEvents++;
function handleBindingAttached(evt) {
if (evt.target instanceof Ci.nsIObjectLoadingContent &&
evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
gPlayPreviewPluginActualEvents++;
}
function pageLoad() {

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

@ -58,5 +58,11 @@
<html:div class="previewPluginContent"><!-- iframe and its src will be set at runtime --></html:div>
<html:div style="display:none;"><children/></html:div>
</content>
<implementation>
<constructor>
// Notify browser-plugins.js that we were attached
this.dispatchEvent(new CustomEvent("PluginBindingAttached"));
</constructor>
</implementation>
</binding>
</bindings>