Commit 89f8e590 authored by Jared Wein's avatar Jared Wein
Browse files

Bug 730318 - Opt-in activated plugins should use internal APIs to keep track...

Bug 730318 - Opt-in activated plugins should use internal APIs to keep track of plugin activation. r=margaret
parent 80d210f3
Loading
Loading
Loading
Loading
+38 −65
Original line number Diff line number Diff line
@@ -1455,8 +1455,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;
}

@@ -1511,6 +1509,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);
@@ -1518,8 +1517,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);

@@ -1558,6 +1555,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);
@@ -1565,8 +1563,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");

@@ -1763,13 +1759,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;
      }

@@ -1877,10 +1884,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)
@@ -1894,22 +1897,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;
      }
    }
@@ -3859,7 +3854,7 @@ var PluginHelper = {
      {
        label: Strings.browser.GetStringFromName("clickToPlayPlugins.yes"),
        callback: function() {
          PluginHelper.playAllPlugins(aTab);
          PluginHelper.playAllPlugins(aTab.browser.contentWindow);
        }
      },
      {
@@ -3872,41 +3867,19 @@ var PluginHelper = {
    NativeWindow.doorhanger.show(message, "ask-to-play-plugins", buttons, aTab.id);
  },

  playAllPlugins: function(aTab, aEvent) {
    if (aEvent) {
      if (!aEvent.isTrusted)
  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;
      aEvent.preventDefault();
    }

    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);
    for (let plugin of plugins) {
      let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
      if (!objLoadingContent.activated)
        objLoadingContent.playPlugin();

    // Set an attribute on the plugin object to avoid re-loading it
    aPlugin.setAttribute("played", true);
    }
  },

  getPluginPreference: function getPluginPreference() {