B2G/gecko/browser/components/sessionstore/src/SessionStore.jsm
/**
   * Restore history for a window
   * @param aWindow
   *        Window reference
   * @param aTabs
   *        Array of tab references
   * @param aTabData
   *        Array of tab data
   * @param aIdMap
   *        Hash for ensuring unique frame IDs
   */
Restore history for a window
@param aWindow
Window reference
@param aTabs
Array of tab references
@param aTabData
Array of tab data
@param aIdMap
Hash for ensuring unique frame IDs
Restore history for a window @param aWindow Window reference @param aTabs Array of tab references @param aTabData Array of tab data @param aIdMap Hash for ensuring unique frame IDs
function ssi_restoreHistory(aWindow, aTabs, aTabData, aIdMap, aDocIdentMap) {
    var _this = this;
    while (aTabs.length > 0 && !(this._canRestoreTabHistory(aTabs[0]))) {
      aTabs.shift();
      aTabData.shift();
    }
    if (aTabs.length == 0) {
      this._setWindowStateReady(aWindow);
      return; 
    }
    var tab = aTabs.shift();
    var tabData = aTabData.shift();
    var browser = aWindow.gBrowser.getBrowserForTab(tab);
    var history = browser.webNavigation.sessionHistory;
    if (history.count > 0) {
      history.PurgeHistory(history.count);
    }
    history.QueryInterface(Ci.nsISHistoryInternal);
    browser.__SS_shistoryListener = new SessionStoreSHistoryListener(tab);
    history.addSHistoryListener(browser.__SS_shistoryListener);
    if (!tabData.entries) {
      tabData.entries = [];
    }
    if (tabData.extData) {
      tab.__SS_extdata = {};
      for (let key in tabData.extData)
        tab.__SS_extdata[key] = tabData.extData[key];
    }
    else
      delete tab.__SS_extdata;
    for (var i = 0; i < tabData.entries.length; i++) {
      if (!tabData.entries[i].url)
        continue;
      history.addEntry(this._deserializeHistoryEntry(tabData.entries[i],
                                                     aIdMap, aDocIdentMap), true);
    }
    var disallow = (tabData.disallow)?tabData.disallow.split(","):[];
    CAPABILITIES.forEach(function(aCapability) {
      browser.docShell["allow" + aCapability] = disallow.indexOf(aCapability) == -1;
    });
    for (let name in this.xulAttributes)
      tab.removeAttribute(name);
    for (let name in tabData.attributes)
      tab.setAttribute(name, tabData.attributes[name]);
    if (tabData.storage && browser.docShell instanceof Ci.nsIDocShell)
      SessionStorage.deserialize(browser.docShell, tabData.storage);
    var event = aWindow.document.createEvent("Events");
    event.initEvent("SSTabRestoring", true, false);
    tab.dispatchEvent(event);
    aWindow.setTimeout(function(){
      _this.restoreHistory(aWindow, aTabs, aTabData, aIdMap, aDocIdentMap);
    }, 0);
    if (aWindow.gBrowser.selectedBrowser == browser) {
      this.restoreTab(tab);
    }
    else {
      if (tabData.pinned)
        this._tabsToRestore.priority.push(tab);
      else if (tabData.hidden)
        this._tabsToRestore.hidden.push(tab);
      else
        this._tabsToRestore.visible.push(tab);
      this.restoreNextTab();
    }
  }
function ssi_restoreHistory ( aWindow , aTabs , aTabData , aIdMap , aDocIdentMap ) { var _this = this ; while ( aTabs . length > 0 && ! ( this . _canRestoreTabHistory ( aTabs [ 0 ] ) ) ) { aTabs . shift ( ) ; aTabData . shift ( ) ; } if ( aTabs . length == 0 ) { this . _setWindowStateReady ( aWindow ) ; return ; } var tab = aTabs . shift ( ) ; var tabData = aTabData . shift ( ) ; var browser = aWindow . gBrowser . getBrowserForTab ( tab ) ; var history = browser . webNavigation . sessionHistory ; if ( history . count > 0 ) { history . PurgeHistory ( history . count ) ; } history . QueryInterface ( Ci . nsISHistoryInternal ) ; browser . __SS_shistoryListener = new SessionStoreSHistoryListener ( tab ) ; history . addSHistoryListener ( browser . __SS_shistoryListener ) ; if ( ! tabData . entries ) { tabData . entries = [ ] ; } if ( tabData . extData ) { tab . __SS_extdata = { } ; for ( let key in tabData . extData ) tab . __SS_extdata [ key ] = tabData . extData [ key ] ; } else delete tab . __SS_extdata ; for ( var i = 0 ; i < tabData . entries . length ; i ++ ) { if ( ! tabData . entries [ i ] . url ) continue ; history . addEntry ( this . _deserializeHistoryEntry ( tabData . entries [ i ] , aIdMap , aDocIdentMap ) , true ) ; } var disallow = ( tabData . disallow ) ? tabData . disallow . split ( "," ) : [ ] ; CAPABILITIES . forEach ( function ( aCapability ) { browser . docShell [ "allow" + aCapability ] = disallow . indexOf ( aCapability ) == - 1 ; } ) ; for ( let name in this . xulAttributes ) tab . removeAttribute ( name ) ; for ( let name in tabData . attributes ) tab . setAttribute ( name , tabData . attributes [ name ] ) ; if ( tabData . storage && browser . docShell instanceof Ci . nsIDocShell ) SessionStorage . deserialize ( browser . docShell , tabData . storage ) ; var event = aWindow . document . createEvent ( "Events" ) ; event . initEvent ( "SSTabRestoring" , true , false ) ; tab . dispatchEvent ( event ) ; aWindow . setTimeout ( function ( ) { _this . restoreHistory ( aWindow , aTabs , aTabData , aIdMap , aDocIdentMap ) ; } , 0 ) ; if ( aWindow . gBrowser . selectedBrowser == browser ) { this . restoreTab ( tab ) ; } else { if ( tabData . pinned ) this . _tabsToRestore . priority . push ( tab ) ; else if ( tabData . hidden ) this . _tabsToRestore . hidden . push ( tab ) ; else this . _tabsToRestore . visible . push ( tab ) ; this . restoreNextTab ( ) ; } }
Restore history for a window
 @param aWindow
        Window reference
 @param aTabs
        Array of tab references
 @param aTabData
        Array of tab data
 @param aIdMap
        Hash for ensuring unique frame IDs
Restore history for a window @param aWindow Window reference @param aTabs Array of tab references @param aTabData Array of tab data @param aIdMap Hash for ensuring unique frame IDs
// if the tab got removed before being completely restored, then skip it // At this point we're essentially ready for consumers to read/write data // via the sessionstore API so we'll send the SSWindowStateReady event. // no more tabs to restore //XXXzpao Wallpaper patch for bug 514751 // make sure to reset the capabilities and attributes, in case this tab gets reused // notify the tabbrowser that the tab chrome has been restored // Restore the history in the next tab // This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but // it ensures each window will have its selected tab loaded. // Put the tab into the right bucket