/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Code for deferring javascript on client side.
 * This javascript is part of JsDefer filter.
 *
 * @author atulvasu@google.com (Atul Vasu)
 * @author ksimbili@google.com (Kishore Simbili)
 */

goog.require('pagespeedutils');


/**
 * Defer javascript will be executed in two phases. First phase will be for
 * high priority scripts and second phase is for low priority scripts. Order
 * of execution will be:
 * 1) High priority scripts.
 * 2) Low priority scripts.
 * 3) Onload of high priority scripts.
 * 4) Onload of low priority scripts.
 *
 * In case of blink, order will be:
 * 1) High priority scripts present in above the fold.
 * 2) Low priority scripts present in above the fold.
 * 3) High priority scripts which are below the fold.
 * 4) Low priority scripts which are below the fold.
 * 5) Onload of high priority scripts.
 * 6) Onload of low priority scripts.
 *
 * Exporting functions using quoted attributes to prevent js compiler from
 * renaming them.
 * See http://code.google.com/closure/compiler/docs/api-tutorial3.html#dangers
 */
window['pagespeed'] = window['pagespeed'] || {};
var pagespeed = window['pagespeed'];

pagespeed['deferJsNs'] = {};
var deferJsNs = pagespeed['deferJsNs'];



/**
 * @constructor
 */
deferJsNs.DeferJs = function() {
  /**
   * Queue of tasks that need to be executed in order.
   * @type {!Array<function()>}
   * @private
   */
  this.queue_ = [];

  /**
   * Array of logs, for debugging.
   * @type {Array<string>}
   */
  this.logs = [];

  /**
   * Next item in the queue to be executed.
   * @type {!number}
   * @private
   */
  this.next_ = 0;

  /**
   * Number of scripts dynamically inserted which are not yet executed.
   * @type {!number}
   * @private
   */
  this.dynamicInsertedScriptCount_ = 0;

  /**
   * Scripts dynamically inserted by other scripts.
   * @type {Array<Element>}
   * @private
   */
  this.dynamicInsertedScript_ = [];

  /**
   * document.write() strings get buffered here, they get rendered when the
   * current script is finished executing.
   * @private
   */
  this.documentWriteHtml_ = '';

  // TODO(sriharis):  Can we have a listener module that is used for the
  // following.

  /**
   * Map of events to event listeners.
   * @type {!Object}
   * @private
   */
  this.eventListenersMap_ = {};

  /**
   * Valid Mime types for Javascript.
   */
  this.jsMimeTypes =
      ['application/ecmascript',
       'application/javascript',
       'application/x-ecmascript',
       'application/x-javascript',
       'text/ecmascript',
       'text/javascript',
       'text/javascript1.0',
       'text/javascript1.1',
       'text/javascript1.2',
       'text/javascript1.3',
       'text/javascript1.4',
       'text/javascript1.5',
       'text/jscript',
       'text/livescript',
       'text/x-ecmascript',
       'text/x-javascript'];

  /**
   * We override certain builtin browser functions, such as document.write.
   * After OnLoad, however, these should go back to behaving as they originally
   * did.  This flag deals with the case where client JS code in turn overrides
   * our overridden implementations.
   * @type {boolean}
   * @private
   */
  this.overrideDefaultImplementation_ = true;

  /**
   * Original document.getElementById handler.
   * @private
   */
  this.origGetElementById_ = document.getElementById;

  /**
   * Original document.getElementsByTagName handler.
   * @private
   */
  this.origGetElementsByTagName_ = document.getElementsByTagName;

  /**
   * Original document.write handler.
   * @private
   */
  this.origDocWrite_ = document.write;

  /**
   * Original document.open handler.
   * @private
   */
  this.origDocOpen_ = document.open;

  /**
   * Original document.close handler.
   * @private
   */
  this.origDocClose_ = document.close;

  /**
   * Original document.addEventListener handler.
   * @private
   */
  this.origDocAddEventListener_ = document.addEventListener;

  /**
   * Original window.addEventListener handler.
   * @private
   */
  this.origWindowAddEventListener_ = window.addEventListener;

  /**
   * Original document.addEventListener handler.
   * @private
   */
  this.origDocAttachEvent_ = document.attachEvent;

  /**
   * Original window.addEventListener handler.
   * @private
   */
  this.origWindowAttachEvent_ = window.attachEvent;

  /**
   * Original document.createElement handler.
   * @private
   */
  this.origCreateElement_ = document.createElement;

  /**
   * Maintains the current state for the deferJs.
   * @type {!number}
   * @private
   */
  this.state_ = deferJsNs.DeferJs.STATES.NOT_STARTED;

  /**
   * Maintains the last fired event.
   * @type {!number}
   * @private
   */
  this.eventState_ = deferJsNs.DeferJs.EVENT.NOT_STARTED;

  /**
   * This variable indicates whether deferJs is called for the first time.
   * This is set to false if deferJs is called again.
   * @private
   */
  this.firstIncrementalRun_ = true;

  /**
   * This variable indicates whether deferJs is called for the last time.
   * This is set to false in registerScriptTags if deferJs will be called again
   * @private
   */
  this.lastIncrementalRun_ = true;

  /**
   * Callback to call when current incremental scripts are done executing.
   * @private
   */
  this.incrementalScriptsDoneCallback_ = null;

  /**
   * This variable counts the total number of async scripts created by no defer
   * scripts.
   * @type {!number}
   * @private
   */
  this.noDeferAsyncScriptsCount_ = 0;

  /**
   * Async scripts created by no defer scripts.
   * @type {Array<Element>}
   * @private
   */
  this.noDeferAsyncScripts_ = [];

  /**
   * Type of the javascript node that will get executed.
   * @type {string}
   * @private
   */
  this.psaScriptType_ = '';

  /**
   * Attribute added for nodes which are not processed yet.
   * @type {string}
   * @private
   */
  this.psaNotProcessed_ = '';

  /**
   * Last Index until incremental scripts will be executed, rest scripts will
   * be executed after the execution of incrementalScriptsDoneCallback_.
   * @type {!number}
   * @private
   */
  this.optLastIndex_ = -1;
};


/**
 * Indicates if experimental js in deferJS is active.
 * @type {boolean}
 */
deferJsNs.DeferJs.isExperimentalMode = false;


/**
 * State Machine
 * NOT_STARTED --> SCRIPTS_REGISTERED --> SCRIPTS_EXECUTING ----------
 *                          ^                                         |
 *                          |                                         |
 *                    WAITING_FOR_NEXT_RUN <--                        |
 *                                             \                      |
 *                                              \                     |
 * SCRIPTS_DONE <--- WAITING_FOR_ONLOAD <--- SYNC_SCRIPTS_DONE <------
 *
 * Constants for different states of deferJs exeuction.
 * @enum {number}
 */
deferJsNs.DeferJs.STATES = {
  /**
   * Start state.
   */
  NOT_STARTED: 0,
  /**
   * This state used to mark when critical scripts are done.
   */
  WAITING_FOR_NEXT_RUN: 1,
  /**
   * In this state all script tags with type as 'text/psajs' are registered for
   * deferred execution.
   */
  SCRIPTS_REGISTERED: 2,
  /**
   * Script execution is in process.
   */
  SCRIPTS_EXECUTING: 3,
  /**
   * All the sync scripts are executed but some async scripts may not executed
   * till now.
   */
  SYNC_SCRIPTS_DONE: 4,
  /**
   * Waiting for onload event to be triggered.
   */
  WAITING_FOR_ONLOAD: 5,
  /**
   * Final state.
   */
  SCRIPTS_DONE: 6
};


/**
 * Constants for different events used by deferJs.
 * @enum {number}
 */
deferJsNs.DeferJs.EVENT = {
  /**
   * Start event state.
   */
  NOT_STARTED: 0,
  /**
   * Event triggered before executing deferred scripts.
   */
  BEFORE_SCRIPTS: 1,
  /**
   * Event corresponding to DOMContentLoaded.
   */
  DOM_READY: 2,
  /**
   * Event corresponding to onload.
   */
  LOAD: 3,
  /**
   * Event triggered after executing deferred scripts.
   */
  AFTER_SCRIPTS: 4
};


/**
 * Name of the attribute set for the nodes that are not reached so far during
 * priority scripts execution.
 * @const {string}
 */
deferJsNs.DeferJs.PRIORITY_PSA_NOT_PROCESSED = 'priority_psa_not_processed';


/**
 * Name of the attribute set for the nodes that are not reached so far during
 * scripts execution.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_NOT_PROCESSED = 'psa_not_processed';


/**
 * Name of the attribute set for the current node to mark the current location.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_CURRENT_NODE = 'psa_current_node';


/**
 * Name of the attribute to mark the script node for deletion after the
 * execution.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_TO_BE_DELETED = 'psa_to_be_deleted';


/**
 * Value for psa dummy script nodes.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_SCRIPT_TYPE = 'text/psajs';


/**
 * Value of psa dummmy priority script nodes.
 * @const {string}
 */
deferJsNs.DeferJs.PRIORITY_PSA_SCRIPT_TYPE = 'text/prioritypsajs';


/**
 * Name of orig_type attribute in deferred script node.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_ORIG_TYPE = 'data-pagespeed-orig-type';


/**
 * Name of orig_src attribute in deferred script node.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_ORIG_SRC = 'data-pagespeed-orig-src';


/**
 * Name of orig_index attribute in deferred script node.
 * @const {string}
 */
deferJsNs.DeferJs.PSA_ORIG_INDEX = 'orig_index';


/**
 * Name of the deferred onload attribute.
 * @const {string}
 */
deferJsNs.DeferJs.PAGESPEED_ONLOAD = 'data-pagespeed-onload';


/**
 * Add to defer_logs if logs are enabled.
 * @param {string} line line to be added to log.
 * @param {Error=} opt_exception optional exception to pass to log.
 */
deferJsNs.DeferJs.prototype.log = function(line, opt_exception) {
  if (this.logs) {
    this.logs.push('' + line);
    if (opt_exception) {
      this.logs.push(opt_exception.message);
      if (typeof(console) != 'undefined' &&
          typeof(console.log) != 'undefined') {
        console.log('PSA ERROR: ' + line + opt_exception.message);
      }
    }
  }
};


/**
 * Adds task to the end of queue, unless position is explicitly given.
 * @param {!function()} task Function closure to be executed later.
 * @param {number=} opt_pos optional position for ordering of jobs.
 */
deferJsNs.DeferJs.prototype.submitTask = function(task, opt_pos) {
  var pos = opt_pos ? opt_pos : this.queue_.length;
  this.queue_.splice(pos, 0, task);
};


/**
 * @param {string} str to be evaluated.
 * @param {Element=} opt_script_elem Script element to copy attributes into the
 *     new script node.
 * @return {Element} Script cloned element which is created.
 */
deferJsNs.DeferJs.prototype.globalEval = function(str, opt_script_elem) {
  var script = this.cloneScriptNode(opt_script_elem);
  script.text = str;
  script.setAttribute('type', 'text/javascript');
  var currentElem = this.getCurrentDomLocation();
  currentElem.parentNode.insertBefore(script, currentElem);
  return script;
};


/**
 * Defines a new var in the name of id's present in the doc. This is the fix for
 * IE, where setting value to the var with same name as an id in the doc throws
 * exception. While creating vars, skip the names which have '-', ':', '.'.
 * Also, variable names cannot start with digits.
 * These characters are allowed in id names but not allowed in variable
 * names.
 */
deferJsNs.DeferJs.prototype.createIdVars = function() {
  var elems = document.getElementsByTagName('*');
  var idVarsString = '';
  for (var i = 0; i < elems.length; i++) {
    // Don't use elem.id since it leads to problem in forms.
    if (elems[i].hasAttribute('id')) {
      var idStr = elems[i].getAttribute('id');
      if (idStr && idStr.search(/[-:.]/) == -1 &&
          idStr.search(/^[0-9]/) == -1) {
        try {
          if (window[idStr] && window[idStr].tagName) {
            idVarsString += 'var ' + idStr +
                '=document.getElementById("' + idStr + '");';
          }
        } catch (err) {
          this.log('Exception while evaluating.', err);
        }
      }
    }
  }
  if (idVarsString) {
    var script = this.globalEval(idVarsString);
    script.setAttribute(deferJsNs.DeferJs.PSA_NOT_PROCESSED, '');
    script.setAttribute(deferJsNs.DeferJs.PRIORITY_PSA_NOT_PROCESSED, '');
  }
};


/**
 * Tries to prefetch the file using rel-preload.
 * @param {!string} url Url to be downloaded.
 */
deferJsNs.DeferJs.prototype.attemptPrefetchOrQueue = function(url) {
  var newLink = this.origCreateElement_.call(document, 'link');
  newLink.setAttribute('rel', 'preload');
  newLink.setAttribute('as', 'script');
  newLink.setAttribute('href', url);
  document.head.appendChild(newLink);
};


/**
 * Defers execution of scriptNode, by adding it to the queue.
 * @param {Element} script script node.
 * @param {number=} opt_pos Optional position for ordering.
 * @param {boolean=} opt_prefetch Script file is prefetched if true.
 */
deferJsNs.DeferJs.prototype.addNode = function(script, opt_pos, opt_prefetch) {
  var src = script.getAttribute(deferJsNs.DeferJs.PSA_ORIG_SRC) ||
      script.getAttribute('src');
  if (src) {
    if (opt_prefetch) {
      this.attemptPrefetchOrQueue(src);
    }
    this.addUrl(src, script, opt_pos);
  } else {
    // ||'ed with empty string to make sure the the value of str is not
    // undefined or null.
    var str = script.innerHTML || script.textContent || script.data || '';
    this.addStr(str, script, opt_pos);
  }
};


/**
 * Defers execution of 'str', by adding it to the queue.
 * @param {!string} str valid javascript snippet.
 * @param {Element} script_elem Psa inserted script used as context element.
 * @param {number=} opt_pos Optional position for ordering.
 */
deferJsNs.DeferJs.prototype.addStr = function(str, script_elem, opt_pos) {
  if (this.isFireFox()) {
    // This is due to some bug identified in firefox.
    // Got this workaround from the bug raised on firefox.
    // https://bugzilla.mozilla.org/show_bug.cgi?id=728151
    this.addUrl('data:text/javascript,' + encodeURIComponent(str),
                script_elem,
                opt_pos);
    return;
  }
  this.logs.push('Add to queue str: ' + str);
  var me = this; // capture closure.
  this.submitTask(function() {
    me.removeNotProcessedAttributeTillNode(script_elem);

    var node = me.nextPsaJsNode();
    node.setAttribute(deferJsNs.DeferJs.PSA_CURRENT_NODE, '');
    try {
      me.globalEval(str, script_elem);
    } catch (err) {
      me.log('Exception while evaluating.', err);
    }
    me.log('Evaluated: ' + str);
    // TODO(ksimbili): Detach stack here to prevent recursion issues.
    me.runNext();
  }, opt_pos);
};
deferJsNs.DeferJs.prototype['addStr'] = deferJsNs.DeferJs.prototype.addStr;


/**
 * Clones a Script Node. This is equivalent of 'cloneNode'.
 * @param {Element=} opt_script_elem Psa inserted script used for cloning the
 *     new element.
 * @return {Element} Script Element with all attributes copied from
 *     opt_script_elem.
 */
deferJsNs.DeferJs.prototype.cloneScriptNode = function(opt_script_elem) {
  var newScript = this.origCreateElement_.call(document, 'script');
  if (opt_script_elem) {
    // Copy attributes.
    for (var a = opt_script_elem.attributes, n = a.length, i = n - 1;
         i >= 0; --i) {
      // Ignore 'type' and 'src' as they are set later.
      // Ignore 'async' and 'defer', as our current.
      // TODO(ksimbili): If a script has async then don't wait for it to load.
      if (a[i].name != 'type' && a[i].name != 'src' &&
          a[i].name != 'async' && a[i].name != 'defer' &&
          a[i].name != deferJsNs.DeferJs.PSA_ORIG_TYPE &&
          a[i].name != deferJsNs.DeferJs.PSA_ORIG_SRC &&
          a[i].name != deferJsNs.DeferJs.PSA_ORIG_INDEX &&
          a[i].name != deferJsNs.DeferJs.PSA_CURRENT_NODE &&
          a[i].name != this.psaNotProcessed_) {
        newScript.setAttribute(a[i].name, a[i].value);
        opt_script_elem.removeAttribute(a[i].name);
      }
    }
  }
  return newScript;
};


/**
 * Creates a dummy script node on load of which the next deferred script is
 * executed.
 * Note, this function needs to be called after a synchronous script node.
 * @param {!string} url returns javascript when fetched.
 */
deferJsNs.DeferJs.prototype.scriptOnLoad = function(url) {
  var script = this.origCreateElement_.call(document, 'script');
  script.setAttribute('type', 'text/javascript');
  script.async = false;
  script.setAttribute(deferJsNs.DeferJs.PSA_TO_BE_DELETED, '');
  script.setAttribute(deferJsNs.DeferJs.PSA_NOT_PROCESSED, '');
  script.setAttribute(deferJsNs.DeferJs.PRIORITY_PSA_NOT_PROCESSED, '');
  var me = this; // capture closure.
  var runNextHandler = function() {
    if (document.querySelector) {
      // Find the script node we inserted and remove it.
      var node = document.querySelector(
          '[' + deferJsNs.DeferJs.PSA_TO_BE_DELETED + ']');
      if (node) {
        node.parentNode.removeChild(node);
      }
    }
    me.log('Executed: ' + url);
    me.runNext();
  };
  // The onload of the new script node is guaranteed which marks as the load
  // completion of 'url'.
  deferJsNs.addOnload(script, runNextHandler);
  pagespeedutils.addHandler(script, 'error', runNextHandler);
  script.src = 'data:text/javascript,' +
      encodeURIComponent('window.pagespeed.psatemp=0;');
  var currentElem = this.getCurrentDomLocation();
  currentElem.parentNode.insertBefore(script, currentElem);
};


/**
 * Defers execution of contents of 'url'.
 * @param {!string} url returns javascript when fetched.
 * @param {Element} script_elem Psa inserted script used as context element.
 * @param {number=} opt_pos Optional position for ordering.
 */
deferJsNs.DeferJs.prototype.addUrl = function(url, script_elem, opt_pos) {
  this.logs.push('Add to queue url: ' + url);
  var me = this; // capture closure.
  this.submitTask(function() {
    me.removeNotProcessedAttributeTillNode(script_elem);

    var script = me.cloneScriptNode(script_elem);
    script.setAttribute('type', 'text/javascript');
    var useSyncScript = true;
    if ('async' in script) {
      script.async = false;
    } else if (script.readyState) {
      useSyncScript = false;
      var stateChangeHandler = function() {
        if (script.readyState == 'complete' ||
            script.readyState == 'loaded') {
          script.onreadystatechange = null;
          me.log('Executed: ' + url);
          me.runNext();
        }
      };
      pagespeedutils.addHandler(script, 'readystatechange', stateChangeHandler);
    }
    script.setAttribute('src', url);
    // If a script node with src also has a node inside it
    // (as innerHTML etc.), we simply create an equivalent text node so
    // that the DOM remains the same. Note that we do not try to execute
    // the contents of this node.
    var str = script_elem.innerHTML ||
        script_elem.textContent ||
        script_elem.data;
    if (str) {
      script.appendChild(document.createTextNode(str));
    }
    var currentElem = me.nextPsaJsNode();
    currentElem.setAttribute(deferJsNs.DeferJs.PSA_CURRENT_NODE, '');
    currentElem.parentNode.insertBefore(script, currentElem);
    if (useSyncScript) {
      // We cannot depend on the onload of the script node we just inserted,
      // because of the way we preload the js resources. Hence we are using
      // 'scriptOnLoad' to insert a dummy script tag whose onload is fired
      // reliably.
      me.scriptOnLoad(url);
    }
  }, opt_pos);
};
deferJsNs.DeferJs.prototype['addUrl'] = deferJsNs.DeferJs.prototype.addUrl;


/**
 * Remove psaNotProcessed_ attribute till the given node.
 * @param {Node=} opt_node Stop node.
 */
deferJsNs.DeferJs.prototype.removeNotProcessedAttributeTillNode = function(
    opt_node) {
  if (document.querySelectorAll && !(this.getIEVersion() <= 8)) {
    var nodes = document.querySelectorAll(
        '[' + this.psaNotProcessed_ + ']');
    for (var i = 0; i < nodes.length; i++) {
      var dom_node = nodes.item(i);
      if (dom_node == opt_node) {
        return;
      }
      if (dom_node.getAttribute('type') != this.psaScriptType_) {
        dom_node.removeAttribute(this.psaNotProcessed_);
      }
    }
  }
};


/**
 * Set 'psa_not_processed' attribute to all Nodes in DOM.
 */
deferJsNs.DeferJs.prototype.setNotProcessedAttributeForNodes = function() {
  var nodes = this.origGetElementsByTagName_.call(document, '*');
  for (var i = 0; i < nodes.length; i++) {
    var dom_node = nodes.item(i);
    dom_node.setAttribute(this.psaNotProcessed_, '');
  }
};


/**
 * Get the next script psajs node to be executed.
 * @return {Element} Element having type attribute set to 'text/psajs'.
 */
deferJsNs.DeferJs.prototype.nextPsaJsNode = function() {
  var current_node = null;
  if (document.querySelector) {
    current_node = document.querySelector(
        '[type="' + this.psaScriptType_ + '"]');
  }
  return current_node;
};


/**
 * Get the current location in DOM for the new nodes insertion. New nodes are
 * inserted before the returned node.
 * @return {Element} Element having 'psa_current_node' attribute.
 */
deferJsNs.DeferJs.prototype.getCurrentDomLocation = function() {
  var current_node;
  if (document.querySelector) {
    current_node = document.querySelector(
        '[' + deferJsNs.DeferJs.PSA_CURRENT_NODE + ']');
  }
  return current_node ||
      this.origGetElementsByTagName_.call(document, 'psanode')[0];
};


/**
 * Removes the processed script node with 'text/psajs'.
 */
deferJsNs.DeferJs.prototype.removeCurrentDomLocation = function() {
  var oldNode = this.getCurrentDomLocation();
  // getCurrentDomLocation can return 'psanode' which is not a script.
  if (oldNode.nodeName == 'SCRIPT') {
    oldNode.parentNode.removeChild(oldNode);
  }
};


/**
 * Called when the script Queue execution is finished.
 */
deferJsNs.DeferJs.prototype.onComplete = function() {
  if (this.state_ >= deferJsNs.DeferJs.STATES.WAITING_FOR_ONLOAD) {
    return;
  }

  if (this.lastIncrementalRun_ && this.isLowPriorityDeferJs()) {
    // ReadyState should be restored only during the last onComplete,
    // so that document.readyState returns 'loading' till the last deferred
    // script is executed.
    if (this.getIEVersion() && document.documentElement['originalDoScroll']) {
      document.documentElement.doScroll =
          document.documentElement['originalDoScroll'];
    }
    if (Object.defineProperty) {
      // Delete document.readyState so that browser can restore it.
      delete document['readyState'];
    }
    if (this.getIEVersion()) {
      if (Object.defineProperty) {
        // Delete document.all so that browser can restore it.
        delete document['all'];
      }
    }
  }

  this.overrideDefaultImplementation_ = false;

  if (this.lastIncrementalRun_) {
    this.state_ = deferJsNs.DeferJs.STATES.WAITING_FOR_ONLOAD;

    if (this.isLowPriorityDeferJs()) {
      var me = this;
      if (document.readyState != 'complete') {
        deferJsNs.addOnload(window, function() {
          me.fireOnload();
        });
      } else {
        // Here there is a chance that window.onload is triggered twice.
        // But we have no way of finding this.
        // TODO(ksimbili): Fix the above scenario.
        if (document.onreadystatechange) {
          this.exec(document.onreadystatechange, document);
        }
        // Execute window.onload
        if (window.onload) {
          psaAddEventListener(window, 'onload', window.onload);
          window.onload = null;
        }
        this.fireOnload();
      }
    } else {
      this.highPriorityFinalize();
    }
  } else {
    // The following state change is only for debugging.
    this.state_ = deferJsNs.DeferJs.STATES.WAITING_FOR_NEXT_RUN;
    this.firstIncrementalRun_ = false;
    if (this.incrementalScriptsDoneCallback_ && this.isLowPriorityDeferJs()) {
      pagespeed.deferJs = pagespeed.highPriorityDeferJs;
      pagespeed['deferJs'] = pagespeed.highPriorityDeferJs;
      this.exec(this.incrementalScriptsDoneCallback_);
      this.incrementalScriptsDoneCallback_ = null;
    } else {
      this.highPriorityFinalize();
    }
  }
};


/**
 * Fires 'onload' event.
 */
deferJsNs.DeferJs.prototype.fireOnload = function() {
  // Add all the elements whose onloads are deferred.
  // Note, by the time we come here, all the images, iframes etc all should have
  // been loaded. Because main page onload gets triggered when all it's
  // resources are loaded.So we can blindly trigger all those onloads.
  if (this.isLowPriorityDeferJs()) {
    this.addDeferredOnloadListeners();
    pagespeed.highPriorityDeferJs.fireOnload();
  }

  this.fireEvent(deferJsNs.DeferJs.EVENT.LOAD);

  if (this.isLowPriorityDeferJs()) {
    // Clean up psanode elements from the DOM.
    var psanodes = document.body.getElementsByTagName('psanode');
    for (var i = (psanodes.length - 1); i >= 0; i--) {
      document.body.removeChild(psanodes[i]);
    }

    // Clean up all prefetch containers we added.
    var prefetchContainers =
        document.body.getElementsByClassName('psa_prefetch_container');
    for (var i = (prefetchContainers.length - 1); i >= 0; i--) {
      prefetchContainers[i].parentNode.removeChild(prefetchContainers[i]);
    }
  }

  this.state_ = deferJsNs.DeferJs.STATES.SCRIPTS_DONE;
  this.fireEvent(deferJsNs.DeferJs.EVENT.AFTER_SCRIPTS);
};


/**
 * Finalize function for high priority scripts execution that start the
 * execution of low priority scripts.
 */
deferJsNs.DeferJs.prototype.highPriorityFinalize = function() {
  var me = this;
  window.setTimeout(function() {
    pagespeed.deferJs = pagespeed.lowPriorityDeferJs;
    pagespeed['deferJs'] = pagespeed.lowPriorityDeferJs;
    if (me.incrementalScriptsDoneCallback_) {
      pagespeed.deferJs.registerScriptTags(me.incrementalScriptsDoneCallback_,
                                           me.optLastIndex_);
      me.incrementalScriptsDoneCallback_ = null;
    } else {
      pagespeed.deferJs.registerScriptTags();
    }
    pagespeed.deferJs.execute();
  }, 0);
};


/**
 * Checks if node is present in the dom.
 * @param {Node} node Node whose presence in the dom is checked.
 * @return {boolean} returns true if node is present in the Node, false
 * otherwise.
 */
deferJsNs.DeferJs.prototype.checkNodeInDom = function(node) {
  while (node = node.parentNode) {
    if (node == document) {
      return true;
    }
  }
  return false;
};


/**
 * Script onload is not triggered if src is empty because such scripts
 * are not async scripts as these scripts will be executed while parsing
 * the dom.
 * @param {Array<Element>} dynamicInsertedScriptList is the list of dynamic
 *     inserted scripts.
 * @return {number} returns the number of scripts whose onload will not get
 *     triggered.
 */
deferJsNs.DeferJs.prototype.getNumScriptsWithNoOnload =
    function(dynamicInsertedScriptList) {
  var count = 0;
  var len = dynamicInsertedScriptList.length;
  for (var i = 0; i < len; ++i) {
    var node = dynamicInsertedScriptList[i];
    var parent = node.parentNode;
    var src = node.src;
    var text = node.textContent;
    // IE behaves differently for async scripts compared to other browsers.
    // IE triggeres script onload only if parent is not null and src or
    // textContent is not empty. But other browsers trigger onload only if
    // node is present in the dom and src is not empty.
    if (((this.getIEVersion() > 8) &&
            (!parent || (src == '' && text == ''))) ||
        (!this.getIEVersion() &&
                (!this.checkNodeInDom(node) || src == ''))) {
      count++;
    }
  }
  return count;
};


/**
 *  Checks if onComplete() function can be called or not.
 *  @return {boolean} returns true if onComplete() can be called.
 */
deferJsNs.DeferJs.prototype.canCallOnComplete = function() {
  // TODO(pulkitg): Handle scenario where somebody sets innetHTML and references
  // in the this.dynamicInsertedScriptCount_ become invalid.
  if (this.state_ != deferJsNs.DeferJs.STATES.SYNC_SCRIPTS_DONE) {
    return false;
  }
  var count = 0;
  if (this.dynamicInsertedScriptCount_ != 0) {
    count = this.getNumScriptsWithNoOnload(this.dynamicInsertedScript_);
  }
  if (this.dynamicInsertedScriptCount_ == count) {
    return true;
  }
  return false;
};


/**
 * Whether all the deferred scripts are done executing.
 * @return {boolean} true if all deferred scripts are done executing, false
 * otherwise.
 */
deferJsNs.DeferJs.prototype.scriptsAreDone = function() {
  return this.state_ === deferJsNs.DeferJs.STATES.SCRIPTS_DONE;
};
deferJsNs.DeferJs.prototype['scriptsAreDone'] =
    deferJsNs.DeferJs.prototype.scriptsAreDone;


/**
 * Schedules the next task in the queue.
 */
deferJsNs.DeferJs.prototype.runNext = function() {
  this.handlePendingDocumentWrites();
  this.removeCurrentDomLocation();
  if (this.next_ < this.queue_.length) {
    // Done here to prevent another _run_next() in stack from
    // seeing the same value of next, and get into infinite
    // loop.
    this.next_++;
    this.queue_[this.next_ - 1].call(window);
  } else {
    if (this.lastIncrementalRun_) {
      this.state_ = deferJsNs.DeferJs.STATES.SYNC_SCRIPTS_DONE;
      this.removeNotProcessedAttributeTillNode();
      this.fireEvent(deferJsNs.DeferJs.EVENT.DOM_READY);
      if (this.canCallOnComplete()) {
        this.onComplete();
      }
    } else {
      this.onComplete();
    }
  }
};


/**
 * Converts from NodeList to array of nodes.
 * @param {!NodeList} nodeList NodeList from a DOM node.
 * @return {!Array<Node>} Array of nodes returned.
 */
deferJsNs.DeferJs.prototype.nodeListToArray = function(nodeList) {
  var arr = [];
  var len = nodeList.length;
  for (var i = 0; i < len; ++i) {
    arr.push(nodeList.item(i));
  }
  return arr;
};


/**
 * SetUp needed before deferrred scripts execution.
 */
deferJsNs.DeferJs.prototype.setUp = function() {
  var me = this;
  if (this.firstIncrementalRun_ && !this.isLowPriorityDeferJs()) {
    // TODO(ksimbili): Remove this once context is not optional.
    // Place where document.write() happens if there is no context element
    // present. Happens if there is no context registering that happened in
    // registerNoScriptTags.
    var initialContextNode = document.createElement('psanode');
    initialContextNode.setAttribute('psa_dw_target', 'true');
    document.body.appendChild(initialContextNode);
    if (this.getIEVersion()) {
      this.createIdVars();
    }

    if (Object.defineProperty) {
      try {
        // Shadow document.readyState
        var propertyDescriptor = { configurable: true };
        propertyDescriptor.get = function() {
          return (me.state_ >= deferJsNs.DeferJs.STATES.SYNC_SCRIPTS_DONE) ?
              'interactive' : 'loading';
        };
        Object.defineProperty(document, 'readyState', propertyDescriptor);
      } catch (err) {
        this.log('Exception while overriding document.readyState.', err);
      }
    }
    if (this.getIEVersion()) {
      // In IE another approach for identifying DOMContentLoaded is popularly
      // used. It is described in http://javascript.nwbox.com/IEContentLoaded/ .
      // And JQuery is one of the libraries which employs this strategy.
      document.documentElement['originalDoScroll'] =
          document.documentElement.doScroll;
      document.documentElement.doScroll = function() {
        throw ('psa exception');
      };
      if (Object.defineProperty) {
        try {
          // Shadow document.all
          var propertyDescriptor = { configurable: true };
          propertyDescriptor.get = function() { return undefined; };
          Object.defineProperty(document, 'all', propertyDescriptor);
        } catch (err) {
          this.log('Exception while overriding document.all.', err);
        }
      }
    }
  }

  // override AddEventListeners.
  this.overrideAddEventListeners();

  // TODO(ksimbili): Restore the following functions to their original.
  document.writeln = function(x) {
    me.writeHtml(x + '\n');
  };
  document.write = function(x) {
    me.writeHtml(x);
  };
  document.open = function() {
    if (!me.overrideDefaultImplementation_) {
      me.origDocOpen_.call(document);
    }
  };
  document.close = function() {
    if (!me.overrideDefaultImplementation_) {
      me.origDocClose_.call(document);
    }
  };

  document.getElementById = function(str) {
    me.handlePendingDocumentWrites();
    var node = me.origGetElementById_.call(document, str);
    return (node == null ||
            node.hasAttribute(me.psaNotProcessed_)) ? null : node;
  };

  if (document.querySelectorAll && !(me.getIEVersion() <= 8)) {
    // TODO(ksimbili): Support IE8
    // TODO(jmaessen): More to the point, this only sort of works even on modern
    // browsers; origGetElementsByTagName returns a live list that changes to
    // reflect DOM changes and querySelectorAll does not (and is known to be
    // massively slower on many browsers as a result).  We might be able to get
    // around this using delegates a la document.readyState, but it'll be hard.
    document.getElementsByTagName = function(tagName) {
      if (me.overrideDefaultImplementation_) {
        try {
          return document.querySelectorAll(
              tagName + ':not([' + me.psaNotProcessed_ + '])');
        } catch (err) {
          // Fall through and emulate original behavior
        }
      }
      return me.origGetElementsByTagName_.call(document, tagName);
    };
  }

  // Overriding createElement().
  // Attaching onload & onerror function if script node is created.
  document.createElement = function(str) {
    var elem = me.origCreateElement_.call(document, str);
    if (me.overrideDefaultImplementation_ &&
        str.toLowerCase() == 'script') {
      me.dynamicInsertedScript_.push(elem);
      me.dynamicInsertedScriptCount_++;
      var onload = function() {
        me.dynamicInsertedScriptCount_--;
        var index = me.dynamicInsertedScript_.indexOf(this);
        if (index != -1) {
          me.dynamicInsertedScript_.splice(index, 1);
          if (me.canCallOnComplete()) {
            me.onComplete();
          }
        }
      };
      deferJsNs.addOnload(elem, onload);
      pagespeedutils.addHandler(elem, 'error', onload);
    }
    return elem;
  };
};


/**
 * Start the execution of the deferred script only if there is no async script
 * pending that was created by non deferred.
 */
deferJsNs.DeferJs.prototype.execute = function() {
  if (this.state_ != deferJsNs.DeferJs.STATES.SCRIPTS_REGISTERED) {
    return;
  }
  var count = 0;
  if (this.noDeferAsyncScriptsCount_ != 0) {
    count = this.getNumScriptsWithNoOnload(this.noDeferAsyncScripts_);
  }
  if (this.noDeferAsyncScriptsCount_ == count) {
    this.run();
  }
};
deferJsNs.DeferJs.prototype['execute'] = deferJsNs.DeferJs.prototype.execute;


/**
 * Starts the execution of all the deferred scripts.
 */
deferJsNs.DeferJs.prototype.run = function() {
  if (this.state_ != deferJsNs.DeferJs.STATES.SCRIPTS_REGISTERED) {
    return;
  }
  if (this.firstIncrementalRun_) {
    this.fireEvent(deferJsNs.DeferJs.EVENT.BEFORE_SCRIPTS);
  }
  this.state_ = deferJsNs.DeferJs.STATES.SCRIPTS_EXECUTING;
  this.setUp();
  // Starts executing the defer_js closures.
  this.runNext();
};
deferJsNs.DeferJs.prototype['run'] = deferJsNs.DeferJs.prototype.run;


/**
 * Parses the given html snippet.
 * @param {!string} html to be parsed.
 * @return {!Node} returns a DIV containing parsed nodes as children.
 */
deferJsNs.DeferJs.prototype.parseHtml = function(html) {
  var div = this.origCreateElement_.call(document, 'div');
  // IE HACK -- Two options.
  // 1) Either add a dummy character at the start and delete it after parsing.
  // 2) Add some non-empty node infront of html.
  div.innerHTML = '<div>_</div>' + html;
  div.removeChild(div.firstChild);
  return div;
};


/**
 * Removes the node from its parent if it has one.
 * @param {Node} node Node to be disowned from parent.
 */
deferJsNs.DeferJs.prototype.disown = function(node) {
  var parentNode = node.parentNode;
  if (parentNode) {
    parentNode.removeChild(node);
  }
};


/**
 * Inserts all the nodes before elem. It must have a parentNode for this
 * operation to succeed. (either actually inserted in DOM)
 * @param {!NodeList} nodes to insert.
 * @param {!Node} elem context element.
 */
deferJsNs.DeferJs.prototype.insertNodesBeforeElem = function(nodes, elem) {
  var nodeArray = this.nodeListToArray(nodes);
  var len = nodeArray.length;
  var parentNode = elem.parentNode;
  for (var i = 0; i < len; ++i) {
    var node = nodeArray[i];
    this.disown(node);
    parentNode.insertBefore(node, elem);
  }
};


/**
 * Returns if the node is JavaScript Node.
 * @param {!Node} node valid script Node.
 * @return {boolean} true if script node is javascript node.
 */
deferJsNs.DeferJs.prototype.isJSNode = function(node) {
  if (node.nodeName != 'SCRIPT') {
    return false;
  }

  if (node.hasAttribute('type')) {
    var type = node.getAttribute('type');
    return !type || (this.jsMimeTypes.indexOf(type) != -1);
  } else if (node.hasAttribute('language')) {
    var lang = node.getAttribute('language');
    return !lang ||
           (this.jsMimeTypes.indexOf('text/' + lang.toLowerCase()) != -1);
  }
  return true;
};


/**
 * Given the list of nodes, sets the not_processed attributes to all nodes and
 * generates list of script nodes.
 * @param {!Node} node starting node for DFS.
 * @param {!Array<!Element>} scriptNodes array of script elements (output).
 */
deferJsNs.DeferJs.prototype.markNodesAndExtractScriptNodes = function(
    node, scriptNodes) {
  if (!node.childNodes) {
    return;
  }
  var nodeArray = this.nodeListToArray(node.childNodes);
  var len = nodeArray.length;
  for (var i = 0; i < len; ++i) {
    var child = nodeArray[i];
    // <script id='A'>
    //  command1
    //  document.write('<script id='B'>command2<script>');
    //  command3
    // <\/script>
    // Browser behaviour for above script node is as follows- first execute
    // command1 and after the execution of command1, scriptB starts executing
    // and only after the complete execution of script B, command3 will execute.
    // But with deferJs turned on, after the execution of command 1, command3
    // gets executed and only after the complete execution of script A, script B
    // will execute.
    // TODO(pulkitg): Make both behaviour consistent.
    if (child.nodeName == 'SCRIPT') {
      if (this.isJSNode(child)) {
        // TODO(jud): Rewrite this function to just iterate over children,
        // instead of childNodes, and then we only have to operate over elements
        // instead of nodes.
        scriptNodes.push(/** @type {!Element} */ (child));
        child.setAttribute(deferJsNs.DeferJs.PSA_ORIG_TYPE, child.type);
        child.setAttribute('type', this.psaScriptType_);
        child.setAttribute(deferJsNs.DeferJs.PSA_ORIG_SRC, child.src);
        child.setAttribute('src', '');
        child.setAttribute(this.psaNotProcessed_, '');
      }
    } else {
      this.markNodesAndExtractScriptNodes(child, scriptNodes);
    }
  }
};


/**
 * @param {!Array<Element>} scripts Array of script nodes to be deferred.
 * @param {!number} pos position for script ordering.
 */
deferJsNs.DeferJs.prototype.deferScripts = function(scripts, pos) {
  var len = scripts.length;
  for (var i = 0; i < len; ++i) {
    this.addNode(scripts[i], pos + i, !!i);
  }
};


/**
 * Inserts html in the before elem, with scripts inside added to queue at pos.
 * @param {!string} html contains the snippet.
 * @param {!number} pos optional position to add to queue.
 * @param {Element=} opt_elem optional context element.
 */
deferJsNs.DeferJs.prototype.insertHtml = function(html, pos, opt_elem) {
  // Parse the html.
  var node = this.parseHtml(html);

  // Extract script nodes out for deferring them.
  var scriptNodes = [];
  this.markNodesAndExtractScriptNodes(node, scriptNodes);

  // Add non-script nodes before elem
  if (opt_elem) {
    this.insertNodesBeforeElem(node.childNodes, opt_elem);
  } else {
    this.log('Unable to insert nodes, no context element found');
  }

  // Add script nodes for deferring.
  this.deferScripts(scriptNodes, pos);
};


/**
 * Renders the document.write() buffer before the context
 * element.
 */
deferJsNs.DeferJs.prototype.handlePendingDocumentWrites = function() {
  if (this.documentWriteHtml_ == '') {
    return;
  }
  this.log('handle_dw: ' + this.documentWriteHtml_);

  var html = this.documentWriteHtml_;
  // Reset early because insertHtml may internally end up calling this function
  // recursively.
  this.documentWriteHtml_ = '';

  var currentElem = this.getCurrentDomLocation();
  this.insertHtml(html, this.next_, currentElem);
};


/**
 * Writes html like document.write to the current context item.
 * @param {string} html Html to be written before current context elem.
 */
deferJsNs.DeferJs.prototype.writeHtml = function(html) {
  if (this.overrideDefaultImplementation_) {
    this.log('dw: ' + html);
    this.documentWriteHtml_ += html;
  } else {
    this.origDocWrite_.call(document, html);
  }
};


/**
 * Adds page onload event listeners to our own list and called them later.
 */
deferJsNs.DeferJs.prototype.addDeferredOnloadListeners = function() {
  var onloadDeferredElements;
  if (document.querySelectorAll) {
    onloadDeferredElements = document.querySelectorAll(
        '[' + deferJsNs.DeferJs.PAGESPEED_ONLOAD + '][data-pagespeed-loaded]');
  }
  for (var i = 0; i < onloadDeferredElements.length; i++) {
    var elem = onloadDeferredElements.item(i);
    var handlerStr = elem.getAttribute(deferJsNs.DeferJs.PAGESPEED_ONLOAD);
    var functionStr = 'var psaFunc=function() {' + handlerStr + '};';
    // Define a function with the string above.
    window['eval'].call(window, functionStr);
    if (typeof window['psaFunc'] != 'function') {
      this.log('Function is not defined', new Error(''));
      continue;
    }

    psaAddEventListener(elem, 'onload', window['psaFunc']);
  }
};


/**
 * Adds functions that run as the first thing in run().
 * @param {!function()} func onload listener.
 */
deferJsNs.DeferJs.prototype.addBeforeDeferRunFunctions = function(func) {
  psaAddEventListener(window, 'onbeforescripts', func);
};
deferJsNs.DeferJs.prototype['addBeforeDeferRunFunctions'] =
    deferJsNs.DeferJs.prototype.addBeforeDeferRunFunctions;


/**
 * Adds functions that run after all the deferred scripts, DOM ready listeners
 * and onload listeners have run.
 * @param {!function()} func onload listener.
 */
deferJsNs.DeferJs.prototype.addAfterDeferRunFunctions = function(func) {
  psaAddEventListener(window, 'onafterscripts', func);
};
deferJsNs.DeferJs.prototype['addAfterDeferRunFunctions'] =
    deferJsNs.DeferJs.prototype.addAfterDeferRunFunctions;


/**
 * Firing event will execute all listeners registered for the event.
 * @param {!deferJsNs.DeferJs.EVENT.<number>} evt Event to be fired.
 */
deferJsNs.DeferJs.prototype.fireEvent = function(evt) {
  this.eventState_ = evt;
  this.log('Firing Event: ' + evt);
  var eventListeners = this.eventListenersMap_[evt] || [];
  for (var i = 0; i < eventListeners.length; ++i) {
    this.exec(eventListeners[i]);
  }
  eventListeners.length = 0;
};


/**
 * Execute function under try catch.
 * @param {!function()} func Function to be executed.
 * @param {Window|Element|Document=} opt_scopeObject Element to be used as
 *     scope.
 */
deferJsNs.DeferJs.prototype.exec = function(func, opt_scopeObject) {
  try {
    func.call(opt_scopeObject || window);
  } catch (err) {
    this.log('Exception while evaluating.', err);
  }
};


/**
 * Override native event registration function on window and document objects.
 */
deferJsNs.DeferJs.prototype.overrideAddEventListeners = function() {
  var me = this;
  // override AddEventListeners.
  if (window.addEventListener) {
    document.addEventListener = function(eventName, func, capture) {
      psaAddEventListener(document, eventName, func,
                          me.origDocAddEventListener_, capture);
    };
    window.addEventListener = function(eventName, func, capture) {
      psaAddEventListener(window, eventName, func,
                          me.origWindowAddEventListener_, capture);
    };
  } else if (window.attachEvent) {
    document.attachEvent = function(eventName, func) {
      psaAddEventListener(document, eventName, func,
                          me.origDocAttachEvent_);
    };
    window.attachEvent = function(eventName, func) {
      psaAddEventListener(window, eventName, func,
                          me.origWindowAttachEvent_);
    };
  }
};


/**
 * Registers an event with the element.
 * @param {!(Window|Node|Document)} elem Element which is registering for the
 * event.
 * @param {!string} eventName Name of the event.
 * @param {(Function|EventListener|function())} func Event handler.
 * @param {Function=} opt_originalAddEventListener Original Add event Listener
 * function.
 * @param {boolean=} opt_capture Capture event.
 */
var psaAddEventListener = function(elem, eventName, func,
                                   opt_originalAddEventListener, opt_capture) {
  var deferJs = pagespeed['deferJs'];
  if (deferJs.state_ >= deferJsNs.DeferJs.STATES.WAITING_FOR_ONLOAD) {
    // At this point we ought to revert to the original event listener
    // behavior.
    if (opt_originalAddEventListener) {
      opt_originalAddEventListener.call(elem, eventName, func, opt_capture);
      return;
    }
    // Unless there wasn't an event listener provided, in which case we are
    // calling psaAddEventListener internally and should check whether we have
    // work to do and fall through if so.  (Note that if we return
    // unconditionally here we miss event registrations and break pages.)
    if (deferJs.state_ >= deferJsNs.DeferJs.STATES.SCRIPTS_DONE) {
      return;
    }
  }
  var deferJsEvent;
  var deferJsEventName;

  if (deferJs.eventState_ < deferJsNs.DeferJs.EVENT.DOM_READY &&
      (eventName == 'DOMContentLoaded' || eventName == 'readystatechange' ||
       eventName == 'onDOMContentLoaded' ||
       eventName == 'onreadystatechange')) {
    deferJsEvent = deferJsNs.DeferJs.EVENT.DOM_READY;
    deferJsEventName = 'DOMContentLoaded';
  } else if (deferJs.eventState_ < deferJsNs.DeferJs.EVENT.LOAD &&
             (eventName == 'load' || eventName == 'onload')) {
    deferJsEvent = deferJsNs.DeferJs.EVENT.LOAD;
    deferJsEventName = 'load';
  } else if (eventName == 'onbeforescripts') {
    deferJsEvent = deferJsNs.DeferJs.EVENT.BEFORE_SCRIPTS;
  } else if (eventName == 'onafterscripts') {
    deferJsEvent = deferJsNs.DeferJs.EVENT.AFTER_SCRIPTS;
  } else {
    if (opt_originalAddEventListener) {
      opt_originalAddEventListener.call(elem, eventName, func, opt_capture);
    }
    return;
  }
  var eventListenerClosure = function() {
    // HACK HACK: This is specifically to solve for jquery libraries, who try
    // to read the event being passed.
    // Note we are not setting any of the other params in event. We don't see
    // them as a need for now.
    // This is set based on documentation from
    // https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/DOMContentLoaded#Cross-browser_fallback
    var customEvent = {};
    customEvent['bubbles'] = false;
    customEvent['cancelable'] = false;
    customEvent['eventPhase'] = 2;  // Event.AT_TARGET
    customEvent['timeStamp'] = new Date().getTime();
    customEvent['type'] = deferJsEventName;
    // event.target has to be some element in DOM. It can never be window.
    customEvent['target'] = (elem != window) ? elem : document;
    // This can be safely 'elem' because the two events "DOMContentLoaded' and
    // 'load' cannot bubble.
    customEvent['currentTarget'] = elem;
    func.call(elem, customEvent);
  };
  if (!deferJs.eventListenersMap_[deferJsEvent]) {
    deferJs.eventListenersMap_[deferJsEvent] = [];
  }
  deferJs.eventListenersMap_[deferJsEvent].push(
      eventListenerClosure);
};


/**
 * Registers all script tags which are marked text/psajs, by adding themselves
 * as the context element to the script embedded inside them.
 * @param {function()=} opt_callback Called when critical scripts are
 *     done executing.
 * @param {number=} opt_last_index till where its safe to run scripts.
 */
deferJsNs.DeferJs.prototype.registerScriptTags =
    function(opt_callback, opt_last_index) {
  if (this.state_ >= deferJsNs.DeferJs.STATES.SCRIPTS_REGISTERED) {
    return;
  }
  if (opt_callback) {
    if (!deferJsNs.DeferJs.isExperimentalMode) {
      opt_callback();
      return;
    }
    this.lastIncrementalRun_ = false;
    this.incrementalScriptsDoneCallback_ = opt_callback;
    if (opt_last_index) {
      this.optLastIndex_ = opt_last_index;
    }
  } else {
    this.lastIncrementalRun_ = true;
  }

  this.state_ = deferJsNs.DeferJs.STATES.SCRIPTS_REGISTERED;
  var scripts = document.getElementsByTagName('script');
  var len = scripts.length;
  for (var i = 0; i < len; ++i) {
    var isFirstScript = (this.queue_.length == this.next_);
    var script = scripts[i];
    // TODO(ksimbili): Use orig_type
    if (script.getAttribute('type') == this.psaScriptType_) {
      if (opt_callback) {
        var scriptIndex =
            script.getAttribute(deferJsNs.DeferJs.PSA_ORIG_INDEX);
        if (scriptIndex <= this.optLastIndex_) {
          this.addNode(script, undefined, !isFirstScript);
        }
      } else {
        if (script.getAttribute(deferJsNs.DeferJs.PSA_ORIG_INDEX) <
            this.optLastIndex_) {
          this.log('Executing a script twice. Orig_Index: ' +
                   script.getAttribute(deferJsNs.DeferJs.PSA_ORIG_INDEX),
                   new Error(''));
        }
        this.addNode(script, undefined, !isFirstScript);
      }
    }
  }
};
deferJsNs.DeferJs.prototype['registerScriptTags'] =
    deferJsNs.DeferJs.prototype.registerScriptTags;


/**
 * Runs the function when element is loaded.
 * @param {Window|Element} elem Element to attach handler.
 * @param {!function()} func New onload handler.
 */
deferJsNs.addOnload = function(elem, func) {
  pagespeedutils.addHandler(elem, 'load', func);
};
pagespeed['addOnload'] = deferJsNs.addOnload;


/**
 * @return {boolean} true if browser is Firefox.
 */
deferJsNs.DeferJs.prototype.isFireFox = function() {
  return (navigator.userAgent.indexOf('Firefox') != -1);
};


/**
 * @return {boolean} true if browser is WebKit based.
 */
deferJsNs.DeferJs.prototype.isWebKit = function() {
  return (navigator.userAgent.indexOf('AppleWebKit') != -1);
};


/**
 * @return {number} version number if browser is IE.
 */
deferJsNs.DeferJs.prototype.getIEVersion = function() {
  var version = /(?:MSIE.(\d+\.\d+))/.exec(navigator.userAgent);
  return (version && version[1]) ?
         (document.documentMode || parseFloat(version[1])) :
         NaN;
};


/**
 * Set the type of the scripts which will be executed.
 * @param {string} type of psa dummy nodes that need to be processed.
 */
deferJsNs.DeferJs.prototype.setType = function(type) {
  this.psaScriptType_ = type;
};


/**
 * Set the psaNotProcessed marker.
 * @param {string} psaNotProcessed marker.
 */
deferJsNs.DeferJs.prototype.setPsaNotProcessed = function(psaNotProcessed) {
  this.psaNotProcessed_ = psaNotProcessed;
};


/**
 * Whether defer javascript is executing low priority scripts.
 * @return {boolean} returns true if defer javascript is executing low priority
 *     scripts.
 */
deferJsNs.DeferJs.prototype.isLowPriorityDeferJs = function() {
  if (this.psaScriptType_ == deferJsNs.DeferJs.PSA_SCRIPT_TYPE) {
    return true;
  }
  return false;
};


/**
 * Overrides createElement for the non-deferred scripts. Any async script
 * created by non-deferred script should be executed before deferred scripts
 * gets executed.
 */
deferJsNs.DeferJs.prototype.noDeferCreateElementOverride = function() {
  // Attaching onload & onerror function if script node is created.
  var me = this;
  document.createElement = function(str) {
    var elem = me.origCreateElement_.call(document, str);
    if (me.overrideDefaultImplementation_ &&
        str.toLowerCase() == 'script') {
      me.noDeferAsyncScripts_.push(elem);
      me.noDeferAsyncScriptsCount_++;
      var onload = function() {
        var index = me.noDeferAsyncScripts_.indexOf(this);
        if (index != -1) {
          me.noDeferAsyncScripts_.splice(index, 1);
          me.noDeferAsyncScriptsCount_--;
          me.execute();
        }
      };
      deferJsNs.addOnload(elem, onload);
      pagespeedutils.addHandler(elem, 'error', onload);
    }
    return elem;
  };
};


/**
 * @return {boolean} true if deferJs is running with experimental flag.
 */
deferJsNs.DeferJs.prototype.isExperimentalMode = function() {
  return deferJsNs.DeferJs.isExperimentalMode;
};
deferJsNs.DeferJs.prototype['isExperimentalMode'] =
    deferJsNs.DeferJs.prototype.isExperimentalMode;


/**
 * Initialize defer javascript.
 */
deferJsNs.deferInit = function() {
  if (pagespeed['deferJs']) {
    return;
  }

  deferJsNs.DeferJs.isExperimentalMode = pagespeed['defer_js_experimental'];
  pagespeed.highPriorityDeferJs = new deferJsNs.DeferJs();
  pagespeed.highPriorityDeferJs.setType(
      deferJsNs.DeferJs.PRIORITY_PSA_SCRIPT_TYPE);
  pagespeed.highPriorityDeferJs.setPsaNotProcessed(
      deferJsNs.DeferJs.PRIORITY_PSA_NOT_PROCESSED);
  pagespeed.highPriorityDeferJs.setNotProcessedAttributeForNodes();
  pagespeed.lowPriorityDeferJs = new deferJsNs.DeferJs();
  pagespeed.lowPriorityDeferJs.setType(deferJsNs.DeferJs.PSA_SCRIPT_TYPE);
  pagespeed.lowPriorityDeferJs.setPsaNotProcessed(
      deferJsNs.DeferJs.PSA_NOT_PROCESSED);
  pagespeed.lowPriorityDeferJs.setNotProcessedAttributeForNodes();
  pagespeed.deferJs = pagespeed.highPriorityDeferJs;

  pagespeed.deferJs.noDeferCreateElementOverride();
  pagespeed['deferJs'] = pagespeed.deferJs;
};

deferJsNs.deferInit();


/**
 * Indicates if deferJs started executing.
 * @type {boolean}
 */
pagespeed.deferJsStarted = false;


/**
 * Starts deferJs execution.
 */
deferJsNs.startDeferJs = function() {
  if (pagespeed.deferJsStarted) {
    return;
  }
  pagespeed.deferJsStarted = true;
  pagespeed.deferJs.registerScriptTags();
  pagespeed.deferJs.execute();
};
deferJsNs['startDeferJs'] = deferJsNs.startDeferJs;
pagespeedutils.addHandler(document, 'DOMContentLoaded', deferJsNs.startDeferJs);
deferJsNs.addOnload(window, deferJsNs.startDeferJs);
