Bug 734323 - Invisible plugins added to the DOM after the 'load' event will not prompt a doorhanger to appear. r=margaret
☠☠ backed out by 26808dda208c ☠ ☠
authorJared Wein <jwein@mozilla.com>
Tue, 27 Mar 2012 13:50:54 -0700
changeset 90448 29529018c1da10232dfb014191805ddf097bf77b
parent 90447 21c75d1d3295dcd3bcd020cfaf83be6ef37905a6
child 90449 77319b44907b2f174188fa619d92b48cd61efa74
push id22358
push userkhuey@mozilla.com
push dateWed, 28 Mar 2012 14:41:10 +0000
treeherdermozilla-central@c3fd0768d46a [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
@@ -1460,16 +1460,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 || {};
@@ -1788,16 +1791,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) {
@@ -1910,35 +1914,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;
@@ -1989,16 +2002,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
       }
@@ -3897,16 +3915,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);
         }
       },
@@ -3923,21 +3942,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");