Bug 734323 - Invisible plugins added to the DOM after the 'load' event will not prompt a doorhanger to appear. r=margaret
authorJared Wein <jwein@mozilla.com>
Wed, 28 Mar 2012 08:54:00 -0700
changeset 90530 265ae1eb0189237ad7a7995fd60fce74e26c7687
parent 90529 486ff4199ca3f8a9ccc63fc2a04e3705f6b550b5
child 90531 fa4228a37dbc7015c84a236646189d976b13c7a7
push id22366
push usermak77@bonardo.net
push dateThu, 29 Mar 2012 15:38:30 +0000
treeherdermozilla-central@ff3521bc6559 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs734323
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 734323 - Invisible plugins added to the DOM after the 'load' event will not prompt a doorhanger to appear. r=margaret
mobile/android/chrome/content/browser.js
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1458,16 +1458,19 @@ let gScreenHeight = 1;
 function Tab(aURL, aParams) {
   this.browser = null;
   this.id = 0;
   this.showProgress = true;
   this.create(aURL, aParams);
   this._zoom = 1.0;
   this.userScrollPos = { x: 0, y: 0 };
   this.contentDocumentIsDisplayed = true;
+  this.clickToPlayPluginDoorhangerShown = false;
+  this.clickToPlayPluginsActivated = false;
+  this.loadEventProcessed = false;
 }
 
 Tab.prototype = {
   create: function(aURL, aParams) {
     if (this.browser)
       return;
 
     aParams = aParams || {};
@@ -1786,16 +1789,17 @@ Tab.prototype = {
             this.browser.removeEventListener("click", ErrorPageEventHandler, false);
             this.browser.removeEventListener("pagehide", listener, true);
           }.bind(this), true);
         }
         break;
       }
 
       case "load": {
+        this.loadEventProcessed = true;
         // 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) {
@@ -1908,35 +1912,44 @@ Tab.prototype = {
           return;
 
         this.sendViewportUpdate(true);
         break;
       }
 
       case "PluginClickToPlay": {
         let plugin = aEvent.target;
-        let overlay = plugin.ownerDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
-        if (!overlay)
+
+        if (this.clickToPlayPluginsActivated) {
+          PluginHelper.playPlugin(plugin);
           return;
+        }
 
         // If the overlay is too small, hide the overlay and act like this
         // is a hidden plugin object
-        if (PluginHelper.isTooSmall(plugin, overlay)) {
-          overlay.style.visibility = "hidden";
+        let overlay = plugin.ownerDocument.getAnonymousElementByAttribute(plugin, "class", "mainBox");
+        if (!overlay || PluginHelper.isTooSmall(plugin, overlay)) {
+          if (overlay)
+            overlay.style.visibility = "hidden";
+          if (this.loadEventProcessed && !this.clickToPlayPluginDoorhangerShown)
+            PluginHelper.showDoorHanger(this);
           return;
         }
 
         // Add click to play listener to the overlay
         overlay.addEventListener("click", function(e) {
           if (e) {
             if (!e.isTrusted)
               return;
             e.preventDefault();
           }
-          PluginHelper.playAllPlugins(e.target.ownerDocument.defaultView);
+          let win = e.target.ownerDocument.defaultView.top;
+          let tab = BrowserApp.getTabForWindow(win);
+          tab.clickToPlayPluginsActivated = true;
+          PluginHelper.playAllPlugins(win);
         }, true);
         break;
       }
     }
   },
 
   onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
     let contentWin = aWebProgress.DOMWindow;
@@ -1987,16 +2000,21 @@ Tab.prototype = {
     let uri = browser.currentURI.spec;
     let documentURI = "";
     let contentType = "";
     if (browser.contentDocument) {
       documentURI = browser.contentDocument.documentURIObject.spec;
       contentType = browser.contentDocument.contentType;
     }
 
+    // Reset state of click-to-play plugin notifications.
+    this.clickToPlayPluginDoorhangerShown = false;
+    this.clickToPlayPluginsActivated = false;
+    this.loadEventProcessed = false;
+
     let message = {
       gecko: {
         type: "Content:LocationChange",
         tabID: this.id,
         uri: uri,
         documentURI: documentURI,
         contentType: contentType
       }
@@ -3895,16 +3913,17 @@ var ClipboardHelper = {
       }
       return false;
     }
   }
 };
 
 var PluginHelper = {
   showDoorHanger: function(aTab) {
+    aTab.clickToPlayPluginDoorhangerShown = true;
     let message = Strings.browser.GetStringFromName("clickToPlayPlugins.message");
     let buttons = [
       {
         label: Strings.browser.GetStringFromName("clickToPlayPlugins.yes"),
         callback: function() {
           PluginHelper.playAllPlugins(aTab.browser.contentWindow);
         }
       },
@@ -3921,21 +3940,23 @@ var PluginHelper = {
   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();
-    }
+    plugins.forEach(this.playPlugin);
+  },
+
+  playPlugin: function(plugin) {
+    let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+    if (!objLoadingContent.activated)
+      objLoadingContent.playPlugin();
   },
 
   getPluginPreference: function getPluginPreference() {
     let pluginDisable = Services.prefs.getBoolPref("plugin.disable");
     if (pluginDisable)
       return "0";
 
     let clickToPlay = Services.prefs.getBoolPref("plugins.click_to_play");